# llms-full (private-aware)
> Built from GitHub files and website pages. Large files may be truncated.

--- docs/installation.md ---
---
title: Installation
id: installation
---

Each supported framework comes with its own package. Each framework package re-exports everything from the core `@tanstack/db` package.

## React

```sh
npm install @tanstack/react-db
```

TanStack DB is compatible with React v16.8+

## Solid

```sh
npm install @tanstack/solid-db
```

## Svelte

```sh
npm install @tanstack/svelte-db
```

## Vue

```sh
npm install @tanstack/vue-db
```

TanStack DB is compatible with Vue v3.3.0+

## Angular

```sh
npm install @tanstack/angular-db
```

TanStack DB is compatible with Angular v16.0.0+

## Vanilla JS

```sh
npm install @tanstack/db
```

Install the the core `@tanstack/db` package to use DB without a framework.

## Collection Packages

TanStack DB also provides specialized collection packages for different data sources and storage needs:

### Query Collection

For loading data using TanStack Query:

```sh
npm install @tanstack/query-db-collection
```

Use `queryCollectionOptions` to fetch data into collections using TanStack Query. This is perfect for REST APIs and existing TanStack Query setups.

### Local Collections

Local storage and in-memory collections are included with the framework packages:

- **LocalStorageCollection** - For persistent local data that syncs across browser tabs
- **LocalOnlyCollection** - For temporary in-memory data and UI state

Both use `localStorageCollectionOptions` and `localOnlyCollectionOptions` respectively, available from your framework package (e.g., `@tanstack/react-db`).

### Sync Engines

#### Electric Collection

For real-time sync with [ElectricSQL](https://electric-sql.com):

```sh
npm install @tanstack/electric-db-collection
```

Use `electricCollectionOptions` to sync data from Postgres databases through ElectricSQL shapes. Ideal for real-time, local-first applications.

#### TrailBase Collection

For syncing with [TrailBase](https://trailbase.io) backends:

```sh
npm install @tanstack/trailbase-db-collection
```

Use `trailBaseCollectionOptions` to sync records from TrailBase's Record APIs with built-in subscription support.

### RxDB Collection

For offline-first apps and local persistence with [RxDB](https://rxdb.info):

```sh
npm install @tanstack/rxdb-db-collection
```

Use `rxdbCollectionOptions` to bridge an [RxDB collection](https://rxdb.info/rx-collection.html) into TanStack DB.
This gives you reactive TanStack DB collections backed by RxDB's powerful local-first database, replication, and conflict handling features.


## Links discovered
- [ElectricSQL](https://electric-sql.com)
- [TrailBase](https://trailbase.io)
- [RxDB](https://rxdb.info)
- [RxDB collection](https://rxdb.info/rx-collection.html)

--- docs/overview.md ---
---
title: Overview
id: overview
---

# TanStack DB - Documentation

Welcome to the TanStack DB documentation.

TanStack DB is the reactive client store for your API. It solves the problems of building fast, modern apps, helping you:

- avoid endpoint sprawl and network waterfalls by loading data into normalized collections
- optimise client performance with sub-millisecond live queries and real-time reactivity
- take the network off the interaction path with instant optimistic writes

Data loading is optimized. Interactions feel instantaneous. Your backend stays simple and your app stays blazing fast. No matter how much data you load.

## Remove the complexity from building fast, modern apps

TanStack DB lets you query your data however your components need it, with a blazing-fast local query engine, real-time reactivity and instant optimistic updates.

Instead of choosing between the least of two evils:

1. **view-specific APIs** - complicating your backend and leading to network waterfalls
2. **load everything and filter** - leading to slow loads and sluggish client performance

TanStack DB enables a new way:

3. **normalized collections** - keep your backend simple
4. **query-driven sync** - optimizes your data loading
5. **sub-millisecond live queries** - keep your app fast and responsive

It extends TanStack Query with collections, live queries and optimistic mutations, working seamlessly with REST APIs, sync engines, or any data source.

## Contents

- [How it works](#how-it-works) &mdash; understand the TanStack DB development model and how the pieces fit together
- [API reference](#api-reference) &mdash; for the primitives and function interfaces
- [Usage examples](#usage-examples) &mdash; examples of common usage patterns
- [More info](#more-info) &mdash; where to find support and more information

## How it works

TanStack DB works by:

- [defining collections](#defining-collections) typed sets of objects that can be populated with data
- [using live queries](#using-live-queries) to query data from/across collections
- [making optimistic mutations](#making-optimistic-mutations) using transactional mutators

```tsx
// Define collections to load data into
const todoCollection = createCollection({
  // ...your config
  onUpdate: updateMutationFn,
})

const Todos = () => {
  // Bind data using live queries
  const { data: todos } = useLiveQuery((q) =>
    q.from({ todo: todoCollection }).where(({ todo }) => todo.completed)
  )

  const complete = (todo) => {
    // Instantly applies optimistic state
    todoCollection.update(todo.id, (draft) => {
      draft.completed = true
    })
  }

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id} onClick={() => complete(todo)}>
          {todo.text}
        </li>
      ))}
    </ul>
  )
}
```

### Defining collections

Collections are typed sets of objects that can be populated with data. They're designed to de-couple loading data into your app from binding data to your components.

Collections can be populated in many ways, including:

- fetching data, for example [from API endpoints using TanStack Query](https://tanstack.com/query/latest)
- syncing data, for example [using a sync engine like ElectricSQL](https://electric-sql.com/)
- storing local data, for example [using localStorage for user preferences and settings](./collections/local-storage-collection.md) or [in-memory client data or UI state](./collections/local-only-collection.md)
- from live collection queries, creating [derived collections as materialised views](#using-live-queries)

Once you have your data in collections, you can query across them using live queries in your components.

#### Sync Modes

Collections support three sync modes to optimize data loading:

- **Eager mode** (default): Loads entire collection upfront. Best for <10k rows of mostly static data like user preferences or small reference tables.
- **On-demand mode**: Loads only what queries request. Best for large datasets (>50k rows), search interfaces, and catalogs where most data won't be accessed.
- **Progressive mode**: Loads query subset immediately, syncs full dataset in background. Best for collaborative apps needing instant first paint AND sub-millisecond queries.

With on-demand mode, your component's query becomes the API call:

```tsx
const productsCollection = createCollection(
  queryCollectionOptions({
    queryKey: ['products'],
    queryFn: async (ctx) => {
      // Query predicates passed automatically in ctx.meta
      const params = parseLoadSubsetOptions(ctx.meta?.loadSubsetOptions)
      return api.getProducts(params) // e.g., GET /api/products?category=electronics&price_lt=100
    },
    syncMode: 'on-demand', // ← Enable query-driven sync
  })
)
```

TanStack DB automatically collapses duplicate requests, performs delta loading when expanding queries, optimizes joins into minimal batched requests, and respects your TanStack Query cache policies. You often end up with _fewer_ network requests than custom view-specific APIs.

See the [Query Collection documentation](./collections/query-collection.md#queryfn-and-predicate-push-down) for full predicate mapping details.

### Using live queries

Live queries are used to query data out of collections. Live queries are reactive: when the underlying data changes in a way that would affect the query result, the result is incrementally updated and returned from the query, triggering a re-render.

TanStack DB live queries are implemented using [d2ts](https://github.com/electric-sql/d2ts), a TypeScript implementation of differential dataflow. This allows the query results to update _incrementally_ (rather than by re-running the whole query). This makes them blazing fast, usually sub-millisecond, even for highly complex queries.

**Performance:** Updating one row in a sorted 100,000-item collection completes in ~0.7ms on an M1 Pro MacBook—fast enough that optimistic updates feel truly instantaneous, even with complex queries and large datasets.

Live queries support joins across collections. This allows you to:

1. load normalised data into collections and then de-normalise it through queries; simplifying your backend by avoiding the need for bespoke API endpoints that match your client
2. join data from multiple sources; for example, syncing some data out of a database, fetching some other data from an external API and then joining these into a unified data model for your front-end code

Every query returns another collection which can _also_ be queried.

For more details on live queries, see the [Live Queries](./guides/live-queries.md) documentation.

### Making optimistic mutations

Collections support `insert`, `update` and `delete` operations. When called, by default they trigger the corresponding `onInsert`, `onUpdate`, `onDelete` handlers which are responsible for writing the mutation to the backend.

```ts
// Define collection with persistence handlers
const todoCollection = createCollection({
  id: "todos",
  // ... other config
  onUpdate: async ({ transaction }) => {
    const { original, changes } = transaction.mutations[0]
    await api.todos.update(original.id, changes)
  },
})

// Immediately applies optimistic state
todoCollection.update(todo.id, (draft) => {
  draft.completed = true
})
```

The collection maintains optimistic state separately from synced data. When live queries read from the collection, they see a local view that overlays the optimistic mutations on top of the immutable synced data.

The optimistic state is held until the handler resolves, at which point the data is persisted to the server and synced back. If the handler throws an error, the optimistic state is rolled back.

For more complex mutations, you can create custom actions with `createOptimisticAction` or custom transactions with `createTransaction`. See the [Mutations guide](./guides/mutations.md) for details.

### Uni-directional data flow

This combines to support a model of uni-directional data flow, extending the redux/flux style state management pattern beyond the client, to take in the server as well:

<figure>
  <a href="https://raw.githubusercontent.com/TanStack/db/main/docs/unidirectional-data-flow.lg.png" target="_blank">
    <img src="https://raw.githubusercontent.com/TanStack/db/main/docs/unidirectional-data-flow.png" />
  </a>
</figure>

With an instant inner loop of optimistic state, superseded in time by the slower outer loop of persisting to the server and syncing the updated server state back into the collection.

## API reference

### Collections

TanStack DB provides several built-in collection types for different data sources and use cases. Each collection type has its own detailed documentation page:

#### Built-in Collection Types

**Fetch Collections**

- **[QueryCollection](./collections/query-collection.md)** &mdash; Load data into collections using TanStack Query for REST APIs and data fetching.

**Sync Collections**

- **[ElectricCollection](./collections/electric-collection.md)** &mdash; Sync data into collections from Postgres using ElectricSQL's real-time sync engine.

- **[TrailBaseCollection](./collections/trailbase-collection.md)** &mdash; Sync data into collections using TrailBase's self-hosted backend with real-time subscriptions.

- **[RxDBCollection](./collections/rxdb-collection.md)** &mdash; Integrate with RxDB for offline-first local persistence with powerful replication and sync capabilities.

- **[PowerSyncCollection](./collections/powersync-collection.md)** &mdash; Sync with PowerSync's SQLite-based database for offline-first persistence with real-time synchronization with PostgreSQL, MongoDB, and MySQL backends.

**Local Collections**

- **[LocalStorageCollection](./collections/local-storage-collection.md)** &mdash; Store small amounts of local-only state that persists across sessions and syncs across browser tabs.

- **[LocalOnlyCollection](./collections/local-only-collection.md)** &mdash; Manage in-memory client data or UI state that doesn't need persistence or cross-tab sync.

#### Collection Schemas

All collections optionally (though strongly recommended) support adding a `schema`.

If provided, this must be a [Standard Schema](https://standardschema.dev) compatible schema instance, such as [Zod](https://zod.dev), [Valibot](https://valibot.dev), [ArkType](https://arktype.io), or [Effect](https://effect.website/docs/schema/introduction/).

**What schemas do:**

1. **Runtime validation** - Ensures data meets your constraints before entering the collection
2. **Type transformations** - Convert input types to rich output types (e.g., string → Date)
3. **Default values** - Automatically populate missing fields
4. **Type safety** - Infer TypeScript types from your schema

**Example:**
```typescript
const todoSchema = z.object({
  id: z.string(),
  text: z.string(),
  completed: z.boolean().default(false),
  created_at: z.string().transform(val => new Date(val)),  // string → Date
  priority: z.number().default(0)
})

const collection = createCollection(
  queryCollectionOptions({
    schema: todoSchema,
    // ...
  })
)

// Users provide simple inputs
collection.insert({
  id: "1",
  text: "Buy groceries",
  created_at: "2024-01-01T00:00:00Z"  // string
  // completed and priority filled automatically
})

// Collection stores and returns rich types
const todo = collection.get("1")
console.log(todo.created_at.getFullYear())  // It's a Date!
console.log(todo.completed)  // false (default)
```

The collection will use the schema for its type inference. If you provide a schema, you cannot also pass an explicit type parameter (e.g., `createCollection<Todo>()`).

**Learn more:** See the [Schemas guide](./guides/schemas.md) for comprehensive documentation on schema validation, type transformations, and best practices.

#### Creating Custom Collection Types

You can create your own collection types by implementing the `Collection` interface found in [`../packages/db/src/collection/index.ts`](https://github.com/TanStack/db/blob/main/packages/db/src/collection/index.ts).

See the existing implementations in [`../packages/db`](https://github.com/TanStack/db/tree/main/packages/db), [`../packages/query-db-collection`](https://github.com/TanStack/db/tree/main/packages/query-db-collection), [`../packages/electric-db-collection`](https://github.com/TanStack/db/tree/main/packages/electric-db-collection) and [`../packages/trailbase-db-collection`](https://github.com/TanStack/db/tree/main/packages/trailbase-db-collection) for reference. Also see the [Collection Options Creator guide](./guides/collection-options-creator.md) for a pattern to create reusable collection configuration factories.

### Live queries

#### `useLiveQuery` hook

Use the `useLiveQuery` hook to assign live query results to a state variable in your React components:

```ts
import { useLiveQuery } from '@tanstack/react-db'
import { eq } from '@tanstack/db'

const Todos = () => {
  const { data: todos } = useLiveQuery((q) =>
    q
      .from({ todo: todoCollection })
      .where(({ todo }) => eq(todo.completed, false))
      .orderBy(({ todo }) => todo.created_at, 'asc')
      .select(({ todo }) => ({
        id: todo.id,
        text: todo.text
      }))
  )

  return <List items={ todos } />
}
```

You can also query across collections with joins:

```ts
import { useLiveQuery } from '@tanstack/react-db'
import { eq } from '@tanstack/db'

const Todos = () => {
  const { data: todos } = useLiveQuery((q) =>
    q
      .from({ todos: todoCollection })
      .join(
        { lists: listCollection },
        ({ todos, lists }) => eq(lists.id, todos.listId),
        'inner'
      )
      .where(({ lists }) => eq(lists.active, true))
      .select(({ todos, lists }) => ({
        id: todos.id,
        title: todos.title,
        listName: lists.name
      }))
  )

  return <List items={ todos } />
}
```

#### `useLiveSuspenseQuery` hook

For React Suspense support, use `useLiveSuspenseQuery`. This hook suspends rendering during initial data load and guarantees that `data` is always defined:

```tsx
import { useLiveSuspenseQuery } from '@tanstack/react-db'
import { Suspense } from 'react'

const Todos = () => {
  // data is always defined - no need for optional chaining
  const { data: todos } = useLiveSuspenseQuery((q) =>
    q
      .from({ todo: todoCollection })
      .where(({ todo }) => eq(todo.completed, false))
  )

  return <List items={ todos } />
}

const App = () => (
  <Suspense fallback={<div>Loading...</div>}>
    <Todos />
  </Suspense>
)
```

See the [React Suspense section in Live Queries](./guides/live-queries#using-with-react-suspense) for detailed usage patterns and when to use `useLiveSuspenseQuery` vs `useLiveQuery`.

#### `queryBuilder`

You can also build queries directly (outside of the component lifecycle) using the underlying `queryBuilder` API:

```ts
import { createLiveQueryCollection, eq } from "@tanstack/db"

const completedTodos = createLiveQueryCollection({
  startSync: true,
  query: (q) =>
    q
      .from({ todo: todoCollection })
      .where(({ todo }) => eq(todo.completed, true)),
})

const results = completedTodos.toArray
```

Note also that:

1. the query results [are themselves a collection](#derived-collections)
2. the `useLiveQuery` automatically starts and stops live query subscriptions when you mount and unmount your components; if you're creating queries manually, you need to manually manage the subscription lifecycle yourself

See the [Live Queries](./guides/live-queries.md) documentation for more details.

### Transactional mutators

For more complex mutations beyond simple CRUD operations, TanStack DB provides `createOptimisticAction` and `createTransaction` for creating custom mutations with full control over the mutation lifecycle.

See the [Mutations guide](./guides/mutations.md) for comprehensive documentation on:

- Creating custom actions with `createOptimisticAction`
- Manual transactions with `createTransaction`
- Mutation merging behavior
- Controlling optimistic vs non-optimistic updates
- Handling temporary IDs
- Transaction lifecycle states

## Usage examples

Here we illustrate two common ways of using TanStack DB:

1. [using TanStack Query](#1-tanstack-query) with an existing REST API
2. [using the ElectricSQL sync engine](#2-electricsql-sync) for real-time sync with your existing API

> [!TIP]
> You can combine these patterns. One of the benefits of TanStack DB is that you can integrate different ways of loading data and handling mutations into the same app. Your components don't need to know where the data came from or goes.

### 1. TanStack Query

You can use TanStack DB with your existing REST API via TanStack Query.

The steps are to:

1. create [QueryCollection](./collections/query-collection.md)s that load data using TanStack Query
2. implement mutation handlers that handle mutations by posting them to your API endpoints

```tsx
import { useLiveQuery, createCollection } from "@tanstack/react-db"
import { queryCollectionOptions } from "@tanstack/query-db-collection"

// Load data into collections using TanStack Query.
// It's common to define these in a `collections` module.
const todoCollection = createCollection(
  queryCollectionOptions({
    queryKey: ["todos"],
    queryFn: async () => fetch("/api/todos"),
    getKey: (item) => item.id,
    schema: todoSchema, // any standard schema
    onInsert: async ({ transaction }) => {
      const { changes: newTodo } = transaction.mutations[0]

      // Handle the local write by sending it to your API.
      await api.todos.create(newTodo)
    },
    // also add onUpdate, onDelete as needed.
  })
)
const listCollection = createCollection(
  queryCollectionOptions({
    queryKey: ["todo-lists"],
    queryFn: async () => fetch("/api/todo-lists"),
    getKey: (item) => item.id,
    schema: todoListSchema,
    onInsert: async ({ transaction }) => {
      const { changes: newTodo } = transaction.mutations[0]

      // Handle the local write by sending it to your API.
      await api.todoLists.create(newTodo)
    },
    // also add onUpdate, onDelete as needed.
  })
)

const Todos = () => {
  // Read the data using live queries. Here we show a live
  // query that joins across two collections.
  const { data: todos } = useLiveQuery((q) =>
    q
      .from({ todo: todoCollection })
      .join(
        { list: listCollection },
        ({ todo, list }) => eq(list.id, todo.list_id),
        "inner"
      )
      .where(({ list }) => eq(list.active, true))
      .select(({ todo, list }) => ({
        id: todo.id,
        text: todo.text,
        status: todo.status,
        listName: list.name,
      }))
  )

  // ...
}
```

This pattern allows you to extend an existing TanStack Query application, or any application built on a REST API, with blazing fast, cross-collection live queries and local optimistic mutations with automatically managed optimistic state.

### 2. ElectricSQL sync

One of the most powerful ways of using TanStack DB is with a sync engine, for a fully local-first experience with real-time sync. This allows you to incrementally adopt sync into an existing app, whilst still handling writes with your existing API.

#### Why Sync Engines?

While TanStack DB works great with REST APIs, sync engines provide powerful benefits:

- **Easy real-time updates**: No WebSocket plumbing—write to your database and changes stream automatically to all clients
- **Automatic side-effects**: When a mutation triggers cascading changes across tables, all affected data syncs automatically without manual cache invalidation
- **Efficient delta updates**: Only changed rows cross the wire, making it practical to load large datasets client-side

This pattern enables the "load everything once" approach that makes apps like Linear and Figma feel instant.

Here, we illustrate this pattern using [ElectricSQL](https://electric-sql.com) as the sync engine.

```tsx
import type { Collection } from "@tanstack/db"
import type {
  MutationFn,
  PendingMutation,
  createCollection,
} from "@tanstack/react-db"
import { electricCollectionOptions } from "@tanstack/electric-db-collection"

export const todoCollection = createCollection(
  electricCollectionOptions({
    id: "todos",
    schema: todoSchema,
    // Electric syncs data using "shapes". These are filtered views
    // on database tables that Electric keeps in sync for you.
    shapeOptions: {
      url: "https://api.electric-sql.cloud/v1/shape",
      params: {
        table: "todos",
      },
    },
    getKey: (item) => item.id,
    schema: todoSchema,
    onInsert: async ({ transaction }) => {
      const response = await api.todos.create(transaction.mutations[0].modified)

      return { txid: response.txid }
    },
    // You can also implement onUpdate, onDelete as needed.
  })
)

const AddTodo = () => {
  return (
    <Button
      onClick={() => todoCollection.insert({ text: "🔥 Make app faster" })}
    />
  )
}
```

## React Native

When using TanStack DB with React Native, you need to install and configure a UUID generation library since React Native doesn't include crypto.randomUUID() by default.

Install the `react-native-random-uuid` package:

```bash
npm install react-native-random-uuid
```

Then import it at the entry point of your React Native app (e.g., in your `App.js` or `index.js`):

```javascript
import "react-native-random-uuid"
```

This polyfill provides the `crypto.randomUUID()` function that TanStack DB uses internally for generating unique identifiers.

## More info

If you have questions / need help using TanStack DB, let us know on the Discord or start a GitHub discussion:

- [`#db` channel in the TanStack discord](https://discord.gg/yjUNbvbraC)
- [GitHub discussions](https://github.com/tanstack/db/discussions)


## Links discovered
- [from API endpoints using TanStack Query](https://tanstack.com/query/latest)
- [using a sync engine like ElectricSQL](https://electric-sql.com/)
- [using localStorage for user preferences and settings](https://github.com/tanstack/db/blob/main/docs/collections/local-storage-collection.md)
- [in-memory client data or UI state](https://github.com/tanstack/db/blob/main/docs/collections/local-only-collection.md)
- [Query Collection documentation](https://github.com/tanstack/db/blob/main/docs/collections/query-collection.md#queryfn-and-predicate-push-down)
- [d2ts](https://github.com/electric-sql/d2ts)
- [Live Queries](https://github.com/tanstack/db/blob/main/docs/guides/live-queries.md)
- [Mutations guide](https://github.com/tanstack/db/blob/main/docs/guides/mutations.md)
- [QueryCollection](https://github.com/tanstack/db/blob/main/docs/collections/query-collection.md)
- [ElectricCollection](https://github.com/tanstack/db/blob/main/docs/collections/electric-collection.md)
- [TrailBaseCollection](https://github.com/tanstack/db/blob/main/docs/collections/trailbase-collection.md)
- [RxDBCollection](https://github.com/tanstack/db/blob/main/docs/collections/rxdb-collection.md)
- [PowerSyncCollection](https://github.com/tanstack/db/blob/main/docs/collections/powersync-collection.md)
- [LocalStorageCollection](https://github.com/tanstack/db/blob/main/docs/collections/local-storage-collection.md)
- [LocalOnlyCollection](https://github.com/tanstack/db/blob/main/docs/collections/local-only-collection.md)
- [Standard Schema](https://standardschema.dev)
- [Zod](https://zod.dev)
- [Valibot](https://valibot.dev)
- [ArkType](https://arktype.io)
- [Effect](https://effect.website/docs/schema/introduction/)
- [Schemas guide](https://github.com/tanstack/db/blob/main/docs/guides/schemas.md)
- [`../packages/db/src/collection/index.ts`](https://github.com/TanStack/db/blob/main/packages/db/src/collection/index.ts)
- [`../packages/db`](https://github.com/TanStack/db/tree/main/packages/db)
- [`../packages/query-db-collection`](https://github.com/TanStack/db/tree/main/packages/query-db-collection)
- [`../packages/electric-db-collection`](https://github.com/TanStack/db/tree/main/packages/electric-db-collection)
- [`../packages/trailbase-db-collection`](https://github.com/TanStack/db/tree/main/packages/trailbase-db-collection)
- [Collection Options Creator guide](https://github.com/tanstack/db/blob/main/docs/guides/collection-options-creator.md)
- [React Suspense section in Live Queries](https://github.com/tanstack/db/blob/main/docs/guides/live-queries#using-with-react-suspense.md)
- [ElectricSQL](https://electric-sql.com)
- [`#db` channel in the TanStack discord](https://discord.gg/yjUNbvbraC)
- [GitHub discussions](https://github.com/tanstack/db/discussions)
- [<img src="https://raw.githubusercontent.com/TanStack/db/main/docs/unidirectional-data-flow.png" />](https://raw.githubusercontent.com/TanStack/db/main/docs/unidirectional-data-flow.lg.png)

--- docs/framework/angular/overview.md ---
---
title: TanStack DB Angular Adapter
id: adapter
---

## Installation

```sh
npm install @tanstack/angular-db
```

## Angular inject function

See the [Angular Functions Reference](./reference/index.md) to see the full list of functions available in the Angular Adapter.

For comprehensive documentation on writing queries (filtering, joins, aggregations, etc.), see the [Live Queries Guide](../../guides/live-queries).

## Basic Usage

### injectLiveQuery

The `injectLiveQuery` function creates a live query that automatically updates your component when data changes. It returns an object containing Angular signals for reactive state management:

```typescript
import { Component } from '@angular/core'
import { injectLiveQuery } from '@tanstack/angular-db'
import { eq } from '@tanstack/db'

@Component({
  selector: 'app-todo-list',
  standalone: true,
  template: `
    @if (query.isLoading()) {
      <div>Loading...</div>
    } @else {
      <ul>
        @for (todo of query.data(); track todo.id) {
          <li>{{ todo.text }}</li>
        }
      </ul>
    }
  `
})
export class TodoListComponent {
  query = injectLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => eq(todos.completed, false))
     .select(({ todos }) => ({ id: todos.id, text: todos.text }))
  )
}
```

**Note:** All return values (`data`, `isLoading`, `status`, etc.) are Angular signals, so call them with `()` in your template: `query.data()`, `query.isLoading()`.

> **Template Syntax:** Examples use Angular 17+ control flow (`@if`, `@for`). For Angular 16, use `*ngIf` and `*ngFor` instead.

### Reactive Parameters

For queries that depend on reactive values, use the `params` option to re-run the query when those values change:

```typescript
import { Component, signal } from '@angular/core'
import { injectLiveQuery } from '@tanstack/angular-db'
import { gt } from '@tanstack/db'

@Component({
  selector: 'app-filtered-todos',
  standalone: true,
  template: `
    <div>{{ query.data().length }} high-priority todos</div>
  `
})
export class FilteredTodosComponent {
  minPriority = signal(5)

  query = injectLiveQuery({
    params: () => ({ minPriority: this.minPriority() }),
    query: ({ params, q }) =>
      q.from({ todos: todosCollection })
       .where(({ todos }) => gt(todos.priority, params.minPriority))
  })
}
```

#### When to Use Reactive Parameters

Use the reactive `params` option when your query depends on:
- Component signals
- Input properties
- Computed values
- Other reactive state

When any reactive value accessed in the `params` function changes, the query is recreated and re-executed.

#### What Happens When Parameters Change

When a parameter value changes:
1. The previous live-query collection is disposed
2. A new query is created with the updated parameter values
3. `status()`/`isLoading()` reflect the new query's lifecycle
4. `data()` updates automatically when the new results arrive

#### Best Practices

**Use reactive params for dynamic queries:**

```typescript
import { Component, Input, signal } from '@angular/core'
import { injectLiveQuery } from '@tanstack/angular-db'
import { eq, and } from '@tanstack/db'

@Component({
  selector: 'app-todo-list',
  standalone: true,
  template: `<div>{{ query.data().length }} todos</div>`
})
export class TodoListComponent {
  // Angular 16+ compatible input
  @Input({ required: true }) userId!: number
  status = signal('active')

  // Good - reactive params track all dependencies
  query = injectLiveQuery({
    params: () => ({
      userId: this.userId,
      status: this.status()
    }),
    query: ({ params, q }) =>
      q.from({ todos: todosCollection })
       .where(({ todos }) => and(
         eq(todos.userId, params.userId),
         eq(todos.status, params.status)
       ))
  })
}
```

**Using Angular 17+ signal inputs:**

```typescript
import { Component, input, signal } from '@angular/core'
import { injectLiveQuery } from '@tanstack/angular-db'
import { eq, and } from '@tanstack/db'

@Component({
  selector: 'app-todo-list',
  standalone: true,
  template: `<div>{{ query.data().length }} todos</div>`
})
export class TodoListComponent {
  // Angular 17+ signal-based input
  userId = input.required<number>()
  status = signal('active')

  query = injectLiveQuery({
    params: () => ({
      userId: this.userId(),
      status: this.status()
    }),
    query: ({ params, q }) =>
      q.from({ todos: todosCollection })
       .where(({ todos }) => and(
         eq(todos.userId, params.userId),
         eq(todos.status, params.status)
       ))
  })
}
```

**Static queries don't need params:**

```typescript
import { Component } from '@angular/core'
import { injectLiveQuery } from '@tanstack/angular-db'

@Component({
  selector: 'app-all-todos',
  standalone: true,
  template: `<div>{{ query.data().length }} todos</div>`
})
export class AllTodosComponent {
  // No reactive dependencies - query never changes
  query = injectLiveQuery((q) =>
    q.from({ todos: todosCollection })
  )
}
```

**Access multiple signals in template:**

```typescript
import { Component } from '@angular/core'
import { injectLiveQuery } from '@tanstack/angular-db'
import { eq } from '@tanstack/db'

@Component({
  selector: 'app-todos',
  standalone: true,
  template: `
    <div>Status: {{ query.status() }}</div>
    <div>Loading: {{ query.isLoading() }}</div>
    <div>Ready: {{ query.isReady() }}</div>
    <div>Total: {{ query.data().length }}</div>
  `
})
export class TodosComponent {
  query = injectLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => eq(todos.completed, false))
  )
}
```


## Links discovered
- [Angular Functions Reference](https://github.com/tanstack/db/blob/main/docs/framework/angular/reference/index.md)
- [Live Queries Guide](https://github.com/tanstack/db/blob/main/docs/guides/live-queries.md)

--- docs/framework/react/overview.md ---
---
title: TanStack DB React Adapter
id: adapter
---

## Installation

```sh
npm install @tanstack/react-db
```

## React Hooks

See the [React Functions Reference](./reference/index.md) to see the full list of hooks available in the React Adapter.

For comprehensive documentation on writing queries (filtering, joins, aggregations, etc.), see the [Live Queries Guide](../../guides/live-queries).

## Basic Usage

### useLiveQuery

The `useLiveQuery` hook creates a live query that automatically updates your component when data changes:

```tsx
import { useLiveQuery } from '@tanstack/react-db'

function TodoList() {
  const { data, isLoading } = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => eq(todos.completed, false))
     .select(({ todos }) => ({ id: todos.id, text: todos.text }))
  )

  if (isLoading) return <div>Loading...</div>

  return (
    <ul>
      {data.map(todo => <li key={todo.id}>{todo.text}</li>)}
    </ul>
  )
}
```

### Dependency Arrays

All query hooks (`useLiveQuery`, `useLiveInfiniteQuery`, `useLiveSuspenseQuery`) accept an optional dependency array as their last parameter. This array works similarly to React's `useEffect` dependencies - when any value in the array changes, the query is recreated and re-executed.

#### When to Use Dependency Arrays

Use dependency arrays when your query depends on external reactive values (props, state, or other hooks):

```tsx
function FilteredTodos({ minPriority }: { minPriority: number }) {
  const { data } = useLiveQuery(
    (q) => q.from({ todos: todosCollection })
           .where(({ todos }) => gt(todos.priority, minPriority)),
    [minPriority] // Re-run when minPriority changes
  )

  return <div>{data.length} high-priority todos</div>
}
```

#### What Happens When Dependencies Change

When a dependency value changes:
1. The previous live query collection is cleaned up
2. A new query is created with the updated values
3. The component re-renders with the new data
4. The hook suspends (for `useLiveSuspenseQuery`) or shows loading state

#### Best Practices

**Include all external values used in the query:**

```tsx
// Good - all external values in deps
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => and(
           eq(todos.userId, userId),
           eq(todos.status, status)
         )),
  [userId, status]
)

// Bad - missing dependencies
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => eq(todos.userId, userId)),
  [] // Missing userId!
)
```

**Empty array for static queries:**

```tsx
// No external dependencies - query never changes
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection }),
  []
)
```

**Omit the array for queries with no external dependencies:**

```tsx
// Same as above - no deps needed
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
)
```

### useLiveInfiniteQuery

For paginated data with live updates, use `useLiveInfiniteQuery`:

```tsx
const { data, pages, fetchNextPage, hasNextPage } = useLiveInfiniteQuery(
  (q) => q
    .from({ posts: postsCollection })
    .where(({ posts }) => eq(posts.category, category))
    .orderBy(({ posts }) => posts.createdAt, 'desc'),
  {
    pageSize: 20,
    getNextPageParam: (lastPage, allPages) =>
      lastPage.length === 20 ? allPages.length : undefined
  },
  [category] // Re-run when category changes
)
```

**Note:** The dependency array is only available when using the query function variant, not when passing a pre-created collection.

### useLiveSuspenseQuery

For React Suspense integration, use `useLiveSuspenseQuery`:

```tsx
function TodoList({ filter }: { filter: string }) {
  const { data } = useLiveSuspenseQuery(
    (q) => q.from({ todos: todosCollection })
           .where(({ todos }) => eq(todos.filter, filter)),
    [filter] // Re-suspends when filter changes
  )

  return (
    <ul>
      {data.map(todo => <li key={todo.id}>{todo.text}</li>)}
    </ul>
  )
}

function App() {
  return (
    <Suspense fallback={<div>Loading...</div>}>
      <TodoList filter="active" />
    </Suspense>
  )
}
```

When dependencies change, `useLiveSuspenseQuery` will re-suspend, showing your Suspense fallback until the new data is ready.


## Links discovered
- [React Functions Reference](https://github.com/tanstack/db/blob/main/docs/framework/react/reference/index.md)
- [Live Queries Guide](https://github.com/tanstack/db/blob/main/docs/guides/live-queries.md)

--- docs/framework/solid/overview.md ---
---
title: TanStack DB Solid Adapter
id: adapter
---

## Installation

```sh
npm install @tanstack/solid-db
```

## Solid Primitives

See the [Solid Functions Reference](./reference/index.md) to see the full list of primitives available in the Solid Adapter.

For comprehensive documentation on writing queries (filtering, joins, aggregations, etc.), see the [Live Queries Guide](../../guides/live-queries).

## Basic Usage

### useLiveQuery

The `useLiveQuery` primitive creates a live query that automatically updates your component when data changes. It returns an object where `data` is a plain array and status fields (e.g. `isLoading()`, `status()`) are accessors:

```tsx
import { useLiveQuery } from '@tanstack/solid-db'
import { eq } from '@tanstack/db'
import { Show, For } from 'solid-js'

function TodoList() {
  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => eq(todos.completed, false))
     .select(({ todos }) => ({ id: todos.id, text: todos.text }))
  )

  return (
    <Show when={!query.isLoading()} fallback={<div>Loading...</div>}>
      <ul>
        <For each={query.data}>
          {(todo) => <li>{todo.text}</li>}
        </For>
      </ul>
    </Show>
  )
}
```

**Note:** `query.data` returns an array directly (not a function), but status fields like `isLoading()`, `status()`, etc. are accessor functions.

### Reactive Queries with Signals

Solid uses fine-grained reactivity, which means queries automatically track and respond to signal changes. Simply call signals inside your query function, and Solid will automatically recompute when they change:

```tsx
import { createSignal } from 'solid-js'
import { useLiveQuery } from '@tanstack/solid-db'
import { gt } from '@tanstack/db'

function FilteredTodos(props: { minPriority: number }) {
  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => gt(todos.priority, props.minPriority))
  )

  return <div>{query.data.length} high-priority todos</div>
}
```

When `props.minPriority` changes, Solid's reactivity system automatically:
1. Detects the prop access inside the query function
2. Cleans up the previous live query collection
3. Creates a new query with the updated value
4. Updates the component with the new data

#### Using Signals from Component State

```tsx
import { createSignal } from 'solid-js'
import { useLiveQuery } from '@tanstack/solid-db'
import { eq, and } from '@tanstack/db'

function TodoList() {
  const [userId, setUserId] = createSignal(1)
  const [status, setStatus] = createSignal('active')

  // Solid automatically tracks userId() and status() calls
  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => and(
       eq(todos.userId, userId()),
       eq(todos.status, status())
     ))
  )

  return (
    <div>
      <select onChange={(e) => setStatus(e.currentTarget.value)}>
        <option value="active">Active</option>
        <option value="completed">Completed</option>
      </select>
      <div>{query.data.length} todos</div>
    </div>
  )
}
```

**Key Point:** Unlike React, you don't need dependency arrays. Solid's reactive system automatically tracks any signals, props, or stores accessed during query execution.

#### Best Practices

**Access signals inside the query function:**

```tsx
import { createSignal } from 'solid-js'
import { useLiveQuery } from '@tanstack/solid-db'
import { gt } from '@tanstack/db'

function TodoList() {
  const [minPriority, setMinPriority] = createSignal(5)

  // Good - signal accessed inside query function
  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => gt(todos.priority, minPriority()))
  )

  // Solid automatically tracks minPriority() and recomputes when it changes
  return <div>{query.data.length} todos</div>
}
```

**Don't read signals outside the query function:**

```tsx
import { createSignal } from 'solid-js'
import { useLiveQuery } from '@tanstack/solid-db'
import { gt } from '@tanstack/db'

function TodoList() {
  const [minPriority, setMinPriority] = createSignal(5)

  // Bad - reading signal outside query function
  const currentPriority = minPriority()
  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => gt(todos.priority, currentPriority))
  )
  // Won't update when minPriority changes!

  return <div>{query.data.length} todos</div>
}
```

**Static queries need no special handling:**

```tsx
import { useLiveQuery } from '@tanstack/solid-db'

function AllTodos() {
  // No signals accessed - query never changes
  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
  )

  return <div>{query.data.length} todos</div>
}
```

### Using Pre-created Collections

You can also pass an existing collection to `useLiveQuery`. This is useful for sharing queries across components:

```tsx
import { createLiveQueryCollection } from '@tanstack/db'
import { useLiveQuery } from '@tanstack/solid-db'

// Create collection outside component
const todosQuery = createLiveQueryCollection((q) =>
  q.from({ todos: todosCollection })
   .where(({ todos }) => eq(todos.active, true))
)

function TodoList() {
  // Pass existing collection
  const query = useLiveQuery(() => todosQuery)

  return <div>{query.data.length} todos</div>
}
```


## Links discovered
- [Solid Functions Reference](https://github.com/tanstack/db/blob/main/docs/framework/solid/reference/index.md)
- [Live Queries Guide](https://github.com/tanstack/db/blob/main/docs/guides/live-queries.md)

--- docs/framework/svelte/overview.md ---
---
title: TanStack DB Svelte Adapter
id: adapter
---

## Installation

```sh
npm install @tanstack/svelte-db
```

## Svelte Utilities

See the [Svelte Functions Reference](./reference/index.md) to see the full list of utilities available in the Svelte Adapter.

For comprehensive documentation on writing queries (filtering, joins, aggregations, etc.), see the [Live Queries Guide](../../guides/live-queries).

## Basic Usage

### useLiveQuery

The `useLiveQuery` utility creates a live query that automatically updates your component when data changes. It returns reactive values powered by Svelte 5 runes:

```svelte
<script>
  import { useLiveQuery } from '@tanstack/svelte-db'
  import { eq } from '@tanstack/db'

  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => eq(todos.completed, false))
     .select(({ todos }) => ({ id: todos.id, text: todos.text }))
  )
</script>

{#if query.isLoading}
  <div>Loading...</div>
{:else}
  <ul>
    {#each query.data as todo (todo.id)}
      <li>{todo.text}</li>
    {/each}
  </ul>
{/if}
```

**Note:** With Svelte 5, `useLiveQuery` returns reactive values through getters. Access `query.data` and `query.isLoading` directly (no `$` prefix needed).

### Dependency Arrays

The `useLiveQuery` utility accepts an optional dependency array as its last parameter. When any value in the array changes, the query is recreated and re-executed.

#### When to Use Dependency Arrays

Use dependency arrays when your query depends on external reactive values (props or state):

```svelte
<script>
  import { useLiveQuery } from '@tanstack/svelte-db'
  import { gt } from '@tanstack/db'

  let { minPriority } = $props()

  const query = useLiveQuery(
    (q) => q.from({ todos: todosCollection })
           .where(({ todos }) => gt(todos.priority, minPriority)),
    [() => minPriority] // Re-run when minPriority changes
  )
</script>

<div>{query.data.length} high-priority todos</div>
```

**Note:** When using props or reactive state in the query, wrap them in a function for the dependency array.

#### What Happens When Dependencies Change

When a dependency value changes:
1. The previous live query collection is cleaned up
2. A new query is created with the updated values
3. The component re-renders with the new data
4. The utility shows loading state again

#### Best Practices

**Include all external values used in the query:**

```svelte
<script>
  import { useLiveQuery } from '@tanstack/svelte-db'
  import { eq, and } from '@tanstack/db'

  let userId = $state(1)
  let status = $state('active')

  // Good - all external values in deps
  const query = useLiveQuery(
    (q) => q.from({ todos: todosCollection })
           .where(({ todos }) => and(
             eq(todos.userId, userId),
             eq(todos.status, status)
           )),
    [() => userId, () => status]
  )

  // Bad - missing dependencies
  const badQuery = useLiveQuery(
    (q) => q.from({ todos: todosCollection })
           .where(({ todos }) => eq(todos.userId, userId)),
    [] // Missing userId!
  )
</script>

<div>{query.data.length} todos</div>
```

**Empty array for static queries:**

```svelte
<script>
  import { useLiveQuery } from '@tanstack/svelte-db'

  // No external dependencies - query never changes
  const query = useLiveQuery(
    (q) => q.from({ todos: todosCollection }),
    []
  )
</script>

<div>{query.data.length} todos</div>
```

**Omit the array for queries with no external dependencies:**

```svelte
<script>
  import { useLiveQuery } from '@tanstack/svelte-db'

  // Same as above - no deps needed
  const query = useLiveQuery(
    (q) => q.from({ todos: todosCollection })
  )
</script>

<div>{query.data.length} todos</div>
```

### Accessing Multiple Properties

You can access all status properties directly on the query result:

```svelte
<script>
  import { useLiveQuery } from '@tanstack/svelte-db'
  import { eq } from '@tanstack/db'

  const query = useLiveQuery((q) =>
    q.from({ todos: todosCollection })
     .where(({ todos }) => eq(todos.active, true))
  )
</script>

<div>
  <div>Status: {query.status}</div>
  <div>Loading: {query.isLoading}</div>
  <div>Ready: {query.isReady}</div>
  <div>Total: {query.data.length}</div>
</div>
```


## Links discovered
- [Svelte Functions Reference](https://github.com/tanstack/db/blob/main/docs/framework/svelte/reference/index.md)
- [Live Queries Guide](https://github.com/tanstack/db/blob/main/docs/guides/live-queries.md)

--- docs/framework/vue/overview.md ---
---
title: TanStack DB Vue Adapter
id: adapter
---

## Installation

```sh
npm install @tanstack/vue-db
```

## Vue Composables

See the [Vue Functions Reference](./reference/index.md) to see the full list of composables available in the Vue Adapter.

For comprehensive documentation on writing queries (filtering, joins, aggregations, etc.), see the [Live Queries Guide](../../guides/live-queries).

## Basic Usage

### useLiveQuery

The `useLiveQuery` composable creates a live query that automatically updates your component when data changes. It returns reactive computed refs:

```vue
<script setup>
import { useLiveQuery } from '@tanstack/vue-db'
import { eq } from '@tanstack/db'

const { data, isLoading } = useLiveQuery((q) =>
  q.from({ todos: todosCollection })
   .where(({ todos }) => eq(todos.completed, false))
   .select(({ todos }) => ({ id: todos.id, text: todos.text }))
)
</script>

<template>
  <div v-if="isLoading">Loading...</div>
  <ul v-else>
    <li v-for="todo in data" :key="todo.id">{{ todo.text }}</li>
  </ul>
</template>
```

**Note:** All return values (`data`, `isLoading`, `status`, etc.) are computed refs, so access them with `.value` in `<script>` but directly in `<template>`.

### Dependency Arrays

The `useLiveQuery` composable accepts an optional dependency array as its last parameter. When any reactive value in the array changes, the query is recreated and re-executed.

#### When to Use Dependency Arrays

Use dependency arrays when your query depends on external reactive values (refs, props, or reactive objects):

```vue
<script setup>
import { ref } from 'vue'
import { useLiveQuery } from '@tanstack/vue-db'
import { gt } from '@tanstack/db'

const minPriority = ref(5)

const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => gt(todos.priority, minPriority.value)),
  [minPriority] // Pass the ref directly, it will be unwrapped automatically
)
</script>

<template>
  <div>{{ data.length }} high-priority todos</div>
</template>
```

**Important:** Pass refs directly in the dependency array, not as functions. Vue will automatically track them.

#### What Happens When Dependencies Change

When a dependency value changes:
1. The previous live query collection is cleaned up
2. A new query is created with the updated values
3. The component re-renders with the new data
4. The composable shows loading state again

#### Best Practices

**Include all external refs used in the query:**

```vue
<script setup>
import { ref } from 'vue'
import { useLiveQuery } from '@tanstack/vue-db'
import { eq, and } from '@tanstack/db'

const userId = ref(1)
const status = ref('active')

// Good - all refs in deps array
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => and(
           eq(todos.userId, userId.value),
           eq(todos.status, status.value)
         )),
  [userId, status] // Pass refs directly
)

// Bad - missing dependencies
const { data: badData } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => eq(todos.userId, userId.value)),
  [] // Missing userId!
)
</script>

<template>
  <div>{{ data.length }} todos</div>
</template>
```

**Using with props:**

```vue
<script setup>
import { toRef } from 'vue'
import { useLiveQuery } from '@tanstack/vue-db'
import { eq } from '@tanstack/db'

const props = defineProps<{ userId: number }>()

// Option 1: Convert prop to ref
const userIdRef = toRef(props, 'userId')
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => eq(todos.userId, userIdRef.value)),
  [userIdRef]
)

// Option 2: Use a getter function for the prop
const { data: data2 } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
         .where(({ todos }) => eq(todos.userId, props.userId)),
  [() => props.userId] // Getter function for non-ref values
)
</script>

<template>
  <div>{{ data.length }} todos</div>
</template>
```

**Empty array for static queries:**

```vue
<script setup>
import { useLiveQuery } from '@tanstack/vue-db'

// No external dependencies - query never changes
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection }),
  []
)
</script>

<template>
  <div>{{ data.length }} todos</div>
</template>
```

**Omit the array for queries with no external dependencies:**

```vue
<script setup>
import { useLiveQuery } from '@tanstack/vue-db'

// Same as above - no deps needed
const { data } = useLiveQuery(
  (q) => q.from({ todos: todosCollection })
)
</script>

<template>
  <div>{{ data.length }} todos</div>
</template>
```

### Using Pre-created Collections

You can also pass an existing collection to `useLiveQuery`. This is useful for sharing queries across components:

```vue
<script setup>
import { ref } from 'vue'
import { createLiveQueryCollection } from '@tanstack/db'
import { useLiveQuery } from '@tanstack/vue-db'
import { eq } from '@tanstack/db'

// Create collection outside component or in a composable
const todosQuery = createLiveQueryCollection({
  query: (q) => q.from({ todos: todosCollection })
               .where(({ todos }) => eq(todos.active, true)),
  startSync: true
})

// Use the pre-created collection
const { data, collection } = useLiveQuery(todosQuery)

// Or use a reactive ref to switch between collections
const currentQuery = ref(todosQuery)
const { data: reactiveData } = useLiveQuery(currentQuery)
</script>

<template>
  <div>{{ data.length }} todos</div>
</template>
```


## Links discovered
- [Vue Functions Reference](https://github.com/tanstack/db/blob/main/docs/framework/vue/reference/index.md)
- [Live Queries Guide](https://github.com/tanstack/db/blob/main/docs/guides/live-queries.md)

--- docs/reference/index.md ---
---
id: "@tanstack/db"
title: "@tanstack/db"
---

# @tanstack/db

## Namespaces

- [IR](@tanstack/namespaces/IR/index.md)

## Classes

- [AggregateFunctionNotInSelectError](classes/AggregateFunctionNotInSelectError.md)
- [AggregateNotSupportedError](classes/AggregateNotSupportedError.md)
- [BaseIndex](classes/BaseIndex.md)
- [BaseQueryBuilder](classes/BaseQueryBuilder.md)
- [BTreeIndex](classes/BTreeIndex.md)
- [CannotCombineEmptyExpressionListError](classes/CannotCombineEmptyExpressionListError.md)
- [CollectionConfigurationError](classes/CollectionConfigurationError.md)
- [CollectionImpl](classes/CollectionImpl.md)
- [CollectionInErrorStateError](classes/CollectionInErrorStateError.md)
- [CollectionInputNotFoundError](classes/CollectionInputNotFoundError.md)
- [CollectionIsInErrorStateError](classes/CollectionIsInErrorStateError.md)
- [CollectionOperationError](classes/CollectionOperationError.md)
- [CollectionRequiresConfigError](classes/CollectionRequiresConfigError.md)
- [CollectionRequiresSyncConfigError](classes/CollectionRequiresSyncConfigError.md)
- [CollectionStateError](classes/CollectionStateError.md)
- [DeduplicatedLoadSubset](classes/DeduplicatedLoadSubset.md)
- [DeleteKeyNotFoundError](classes/DeleteKeyNotFoundError.md)
- [DistinctRequiresSelectError](classes/DistinctRequiresSelectError.md)
- [DuplicateAliasInSubqueryError](classes/DuplicateAliasInSubqueryError.md)
- [DuplicateDbInstanceError](classes/DuplicateDbInstanceError.md)
- [DuplicateKeyError](classes/DuplicateKeyError.md)
- [DuplicateKeySyncError](classes/DuplicateKeySyncError.md)
- [EmptyReferencePathError](classes/EmptyReferencePathError.md)
- [GroupByError](classes/GroupByError.md)
- [HavingRequiresGroupByError](classes/HavingRequiresGroupByError.md)
- [IndexProxy](classes/IndexProxy.md)
- [InvalidCollectionStatusTransitionError](classes/InvalidCollectionStatusTransitionError.md)
- [InvalidJoinCondition](classes/InvalidJoinCondition.md)
- [InvalidJoinConditionLeftSourceError](classes/InvalidJoinConditionLeftSourceError.md)
- [InvalidJoinConditionRightSourceError](classes/InvalidJoinConditionRightSourceError.md)
- [InvalidJoinConditionSameSourceError](classes/InvalidJoinConditionSameSourceError.md)
- [InvalidJoinConditionSourceMismatchError](classes/InvalidJoinConditionSourceMismatchError.md)
- [InvalidKeyError](classes/InvalidKeyError.md)
- [InvalidSchemaError](classes/InvalidSchemaError.md)
- [InvalidSourceError](classes/InvalidSourceError.md)
- [InvalidSourceTypeError](classes/InvalidSourceTypeError.md)
- [InvalidStorageDataFormatError](classes/InvalidStorageDataFormatError.md)
- [InvalidStorageObjectFormatError](classes/InvalidStorageObjectFormatError.md)
- [JoinCollectionNotFoundError](classes/JoinCollectionNotFoundError.md)
- [JoinConditionMustBeEqualityError](classes/JoinConditionMustBeEqualityError.md)
- [JoinError](classes/JoinError.md)
- [KeyUpdateNotAllowedError](classes/KeyUpdateNotAllowedError.md)
- [LazyIndexWrapper](classes/LazyIndexWrapper.md)
- [LimitOffsetRequireOrderByError](classes/LimitOffsetRequireOrderByError.md)
- [LocalStorageCollectionError](classes/LocalStorageCollectionError.md)
- [MissingAliasInputsError](classes/MissingAliasInputsError.md)
- [MissingDeleteHandlerError](classes/MissingDeleteHandlerError.md)
- [MissingHandlerError](classes/MissingHandlerError.md)
- [MissingInsertHandlerError](classes/MissingInsertHandlerError.md)
- [MissingMutationFunctionError](classes/MissingMutationFunctionError.md)
- [MissingUpdateArgumentError](classes/MissingUpdateArgumentError.md)
- [MissingUpdateHandlerError](classes/MissingUpdateHandlerError.md)
- [NegativeActiveSubscribersError](classes/NegativeActiveSubscribersError.md)
- [NoKeysPassedToDeleteError](classes/NoKeysPassedToDeleteError.md)
- [NoKeysPassedToUpdateError](classes/NoKeysPassedToUpdateError.md)
- [NonAggregateExpressionNotInGroupByError](classes/NonAggregateExpressionNotInGroupByError.md)
- [NonRetriableError](classes/NonRetriableError.md)
- [NoPendingSyncTransactionCommitError](classes/NoPendingSyncTransactionCommitError.md)
- [NoPendingSyncTransactionWriteError](classes/NoPendingSyncTransactionWriteError.md)
- [OnlyOneSourceAllowedError](classes/OnlyOneSourceAllowedError.md)
- [OnMutateMustBeSynchronousError](classes/OnMutateMustBeSynchronousError.md)
- [QueryBuilderError](classes/QueryBuilderError.md)
- [QueryCompilationError](classes/QueryCompilationError.md)
- [QueryMustHaveFromClauseError](classes/QueryMustHaveFromClauseError.md)
- [QueryOptimizerError](classes/QueryOptimizerError.md)
- [SchemaMustBeSynchronousError](classes/SchemaMustBeSynchronousError.md)
- [SchemaValidationError](classes/SchemaValidationError.md)
- [SerializationError](classes/SerializationError.md)
- [SetWindowRequiresOrderByError](classes/SetWindowRequiresOrderByError.md)
- [SortedMap](classes/SortedMap.md)
- [StorageError](classes/StorageError.md)
- [StorageKeyRequiredError](classes/StorageKeyRequiredError.md)
- [SubQueryMustHaveFromClauseError](classes/SubQueryMustHaveFromClauseError.md)
- [SubscriptionNotFoundError](classes/SubscriptionNotFoundError.md)
- [SyncCleanupError](classes/SyncCleanupError.md)
- [SyncTransactionAlreadyCommittedError](classes/SyncTransactionAlreadyCommittedError.md)
- [SyncTransactionAlreadyCommittedWriteError](classes/SyncTransactionAlreadyCommittedWriteError.md)
- [TanStackDBError](classes/TanStackDBError.md)
- [TransactionAlreadyCompletedRollbackError](classes/TransactionAlreadyCompletedRollbackError.md)
- [TransactionError](classes/TransactionError.md)
- [TransactionNotPendingCommitError](classes/TransactionNotPendingCommitError.md)
- [TransactionNotPendingMutateError](classes/TransactionNotPendingMutateError.md)
- [UndefinedKeyError](classes/UndefinedKeyError.md)
- [UnknownExpressionTypeError](classes/UnknownExpressionTypeError.md)
- [UnknownFunctionError](classes/UnknownFunctionError.md)
- [UnknownHavingExpressionTypeError](classes/UnknownHavingExpressionTypeError.md)
- [UnsupportedAggregateFunctionError](classes/UnsupportedAggregateFunctionError.md)
- [UnsupportedFromTypeError](classes/UnsupportedFromTypeError.md)
- [UnsupportedJoinSourceTypeError](classes/UnsupportedJoinSourceTypeError.md)
- [UnsupportedJoinTypeError](classes/UnsupportedJoinTypeError.md)
- [UpdateKeyNotFoundError](classes/UpdateKeyNotFoundError.md)
- [WhereClauseConversionError](classes/WhereClauseConversionError.md)

## Interfaces

- [BaseCollectionConfig](interfaces/BaseCollectionConfig.md)
- [BaseStrategy](interfaces/BaseStrategy.md)
- [BTreeIndexOptions](interfaces/BTreeIndexOptions.md)
- [ChangeMessage](interfaces/ChangeMessage.md)
- [Collection](interfaces/Collection.md)
- [CollectionConfig](interfaces/CollectionConfig.md)
- [CollectionLike](interfaces/CollectionLike.md)
- [Context](interfaces/Context.md)
- [CreateOptimisticActionsOptions](interfaces/CreateOptimisticActionsOptions.md)
- [CurrentStateAsChangesOptions](interfaces/CurrentStateAsChangesOptions.md)
- [DebounceStrategy](interfaces/DebounceStrategy.md)
- [DebounceStrategyOptions](interfaces/DebounceStrategyOptions.md)
- [IndexInterface](interfaces/IndexInterface.md)
- [IndexOptions](interfaces/IndexOptions.md)
- [IndexStats](interfaces/IndexStats.md)
- [InsertConfig](interfaces/InsertConfig.md)
- [LiveQueryCollectionConfig](interfaces/LiveQueryCollectionConfig.md)
- [LocalOnlyCollectionConfig](interfaces/LocalOnlyCollectionConfig.md)
- [LocalOnlyCollectionUtils](interfaces/LocalOnlyCollectionUtils.md)
- [LocalStorageCollectionConfig](interfaces/LocalStorageCollectionConfig.md)
- [LocalStorageCollectionUtils](interfaces/LocalStorageCollectionUtils.md)
- [OperationConfig](interfaces/OperationConfig.md)
- [OptimisticChangeMessage](interfaces/OptimisticChangeMessage.md)
- [PacedMutationsConfig](interfaces/PacedMutationsConfig.md)
- [ParsedOrderBy](interfaces/ParsedOrderBy.md)
- [Parser](interfaces/Parser.md)
- [ParseWhereOptions](interfaces/ParseWhereOptions.md)
- [PendingMutation](interfaces/PendingMutation.md)
- [QueueStrategy](interfaces/QueueStrategy.md)
- [QueueStrategyOptions](interfaces/QueueStrategyOptions.md)
- [RangeQueryOptions](interfaces/RangeQueryOptions.md)
- [SimpleComparison](interfaces/SimpleComparison.md)
- [SubscribeChangesOptions](interfaces/SubscribeChangesOptions.md)
- [SubscribeChangesSnapshotOptions](interfaces/SubscribeChangesSnapshotOptions.md)
- [Subscription](interfaces/Subscription.md)
- [SubscriptionStatusChangeEvent](interfaces/SubscriptionStatusChangeEvent.md)
- [SubscriptionStatusEvent](interfaces/SubscriptionStatusEvent.md)
- [SubscriptionUnsubscribedEvent](interfaces/SubscriptionUnsubscribedEvent.md)
- [SyncConfig](interfaces/SyncConfig.md)
- [ThrottleStrategy](interfaces/ThrottleStrategy.md)
- [ThrottleStrategyOptions](interfaces/ThrottleStrategyOptions.md)
- [Transaction](interfaces/Transaction.md)
- [TransactionConfig](interfaces/TransactionConfig.md)

## Type Aliases

- [ChangeListener](type-aliases/ChangeListener.md)
- [ChangesPayload](type-aliases/ChangesPayload.md)
- [CleanupFn](type-aliases/CleanupFn.md)
- [ClearStorageFn](type-aliases/ClearStorageFn.md)
- [CollectionConfigSingleRowOption](type-aliases/CollectionConfigSingleRowOption.md)
- [CollectionStatus](type-aliases/CollectionStatus.md)
- [DeleteMutationFn](type-aliases/DeleteMutationFn.md)
- [DeleteMutationFnParams](type-aliases/DeleteMutationFnParams.md)
- [FieldPath](type-aliases/FieldPath.md)
- [Fn](type-aliases/Fn.md)
- [GetResult](type-aliases/GetResult.md)
- [GetStorageSizeFn](type-aliases/GetStorageSizeFn.md)
- [IndexConstructor](type-aliases/IndexConstructor.md)
- [IndexOperation](type-aliases/IndexOperation.md)
- [IndexResolver](type-aliases/IndexResolver.md)
- [InferResultType](type-aliases/InferResultType.md)
- [InferSchemaInput](type-aliases/InferSchemaInput.md)
- [InferSchemaOutput](type-aliases/InferSchemaOutput.md)
- [InitialQueryBuilder](type-aliases/InitialQueryBuilder.md)
- [InputRow](type-aliases/InputRow.md)
- [InsertMutationFn](type-aliases/InsertMutationFn.md)
- [InsertMutationFnParams](type-aliases/InsertMutationFnParams.md)
- [KeyedNamespacedRow](type-aliases/KeyedNamespacedRow.md)
- [KeyedStream](type-aliases/KeyedStream.md)
- [LiveQueryCollectionUtils](type-aliases/LiveQueryCollectionUtils.md)
- [LoadSubsetFn](type-aliases/LoadSubsetFn.md)
- [LoadSubsetOptions](type-aliases/LoadSubsetOptions.md)
- [MaybeSingleResult](type-aliases/MaybeSingleResult.md)
- [MutationFn](type-aliases/MutationFn.md)
- [MutationFnParams](type-aliases/MutationFnParams.md)
- [NamespacedAndKeyedStream](type-aliases/NamespacedAndKeyedStream.md)
- [NamespacedRow](type-aliases/NamespacedRow.md)
- [NonEmptyArray](type-aliases/NonEmptyArray.md)
- [NonSingleResult](type-aliases/NonSingleResult.md)
- [OperationType](type-aliases/OperationType.md)
- [OperatorName](type-aliases/OperatorName.md)
- [QueryBuilder](type-aliases/QueryBuilder.md)
- [Ref](type-aliases/Ref.md)
- [ResolveTransactionChanges](type-aliases/ResolveTransactionChanges.md)
- [ResultStream](type-aliases/ResultStream.md)
- [Row](type-aliases/Row.md)
- [SingleResult](type-aliases/SingleResult.md)
- [Source](type-aliases/Source.md)
- [StandardSchema](type-aliases/StandardSchema.md)
- [StandardSchemaAlias](type-aliases/StandardSchemaAlias.md)
- [StorageApi](type-aliases/StorageApi.md)
- [StorageEventApi](type-aliases/StorageEventApi.md)
- [Strategy](type-aliases/Strategy.md)
- [StrategyOptions](type-aliases/StrategyOptions.md)
- [StringCollationConfig](type-aliases/StringCollationConfig.md)
- [SubscriptionEvents](type-aliases/SubscriptionEvents.md)
- [SubscriptionStatus](type-aliases/SubscriptionStatus.md)
- [SyncConfigRes](type-aliases/SyncConfigRes.md)
- [SyncMode](type-aliases/SyncMode.md)
- [TransactionState](type-aliases/TransactionState.md)
- [TransactionWithMutations](type-aliases/TransactionWithMutations.md)
- [UnloadSubsetFn](type-aliases/UnloadSubsetFn.md)
- [UpdateMutationFn](type-aliases/UpdateMutationFn.md)
- [UpdateMutationFnParams](type-aliases/UpdateMutationFnParams.md)
- [UtilsRecord](type-aliases/UtilsRecord.md)
- [WritableDeep](type-aliases/WritableDeep.md)

## Variables

- [IndexOperation](variables/IndexOperation.md)
- [operators](variables/operators.md)
- [Query](variables/Query.md)

## Functions

- [add](functions/add.md)
- [and](functions/and.md)
- [avg](functions/avg.md)
- [coalesce](functions/coalesce.md)
- [compileQuery](functions/compileQuery.md)
- [concat](functions/concat.md)
- [count](functions/count.md)
- [createArrayChangeProxy](functions/createArrayChangeProxy.md)
- [createChangeProxy](functions/createChangeProxy.md)
- [createCollection](functions/createCollection.md)
- [createLiveQueryCollection](functions/createLiveQueryCollection.md)
- [createOptimisticAction](functions/createOptimisticAction.md)
- [createPacedMutations](functions/createPacedMutations.md)
- [createTransaction](functions/createTransaction.md)
- [debounceStrategy](functions/debounceStrategy.md)
- [deepEquals](functions/deepEquals.md)
- [eq](functions/eq.md)
- [extractFieldPath](functions/extractFieldPath.md)
- [extractSimpleComparisons](functions/extractSimpleComparisons.md)
- [extractValue](functions/extractValue.md)
- [getActiveTransaction](functions/getActiveTransaction.md)
- [gt](functions/gt.md)
- [gte](functions/gte.md)
- [ilike](functions/ilike.md)
- [inArray](functions/inArray.md)
- [isLimitSubset](functions/isLimitSubset.md)
- [isNull](functions/isNull.md)
- [isOrderBySubset](functions/isOrderBySubset.md)
- [isPredicateSubset](functions/isPredicateSubset.md)
- [isUndefined](functions/isUndefined.md)
- [isWhereSubset](functions/isWhereSubset.md)
- [length](functions/length.md)
- [like](functions/like.md)
- [liveQueryCollectionOptions](functions/liveQueryCollectionOptions.md)
- [localOnlyCollectionOptions](functions/localOnlyCollectionOptions.md)
- [localStorageCollectionOptions](functions/localStorageCollectionOptions.md)
- [lower](functions/lower.md)
- [lt](functions/lt.md)
- [lte](functions/lte.md)
- [max](functions/max.md)
- [min](functions/min.md)
- [minusWherePredicates](functions/minusWherePredicates.md)
- [not](functions/not.md)
- [or](functions/or.md)
- [parseLoadSubsetOptions](functions/parseLoadSubsetOptions.md)
- [parseOrderByExpression](functions/parseOrderByExpression.md)
- [parseWhereExpression](functions/parseWhereExpression.md)
- [queueStrategy](functions/queueStrategy.md)
- [sum](functions/sum.md)
- [throttleStrategy](functions/throttleStrategy.md)
- [unionWherePredicates](functions/unionWherePredicates.md)
- [upper](functions/upper.md)
- [walkExpression](functions/walkExpression.md)
- [withArrayChangeTracking](functions/withArrayChangeTracking.md)
- [withChangeTracking](functions/withChangeTracking.md)


## Links discovered
- [IR](https://github.com/tanstack/db/blob/main/docs/reference/@tanstack/namespaces/IR/index.md)
- [AggregateFunctionNotInSelectError](https://github.com/tanstack/db/blob/main/docs/reference/classes/AggregateFunctionNotInSelectError.md)
- [AggregateNotSupportedError](https://github.com/tanstack/db/blob/main/docs/reference/classes/AggregateNotSupportedError.md)
- [BaseIndex](https://github.com/tanstack/db/blob/main/docs/reference/classes/BaseIndex.md)
- [BaseQueryBuilder](https://github.com/tanstack/db/blob/main/docs/reference/classes/BaseQueryBuilder.md)
- [BTreeIndex](https://github.com/tanstack/db/blob/main/docs/reference/classes/BTreeIndex.md)
- [CannotCombineEmptyExpressionListError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CannotCombineEmptyExpressionListError.md)
- [CollectionConfigurationError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionConfigurationError.md)
- [CollectionImpl](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionImpl.md)
- [CollectionInErrorStateError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionInErrorStateError.md)
- [CollectionInputNotFoundError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionInputNotFoundError.md)
- [CollectionIsInErrorStateError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionIsInErrorStateError.md)
- [CollectionOperationError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionOperationError.md)
- [CollectionRequiresConfigError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionRequiresConfigError.md)
- [CollectionRequiresSyncConfigError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionRequiresSyncConfigError.md)
- [CollectionStateError](https://github.com/tanstack/db/blob/main/docs/reference/classes/CollectionStateError.md)
- [DeduplicatedLoadSubset](https://github.com/tanstack/db/blob/main/docs/reference/classes/DeduplicatedLoadSubset.md)
- [DeleteKeyNotFoundError](https://github.com/tanstack/db/blob/main/docs/reference/classes/DeleteKeyNotFoundError.md)
- [DistinctRequiresSelectError](https://github.com/tanstack/db/blob/main/docs/reference/classes/DistinctRequiresSelectError.md)
- [DuplicateAliasInSubqueryError](https://github.com/tanstack/db/blob/main/docs/reference/classes/DuplicateAliasInSubqueryError.md)
- [DuplicateDbInstanceError](https://github.com/tanstack/db/blob/main/docs/reference/classes/DuplicateDbInstanceError.md)
- [DuplicateKeyError](https://github.com/tanstack/db/blob/main/docs/reference/classes/DuplicateKeyError.md)
- [DuplicateKeySyncError](https://github.com/tanstack/db/blob/main/docs/reference/classes/DuplicateKeySyncError.md)
- [EmptyReferencePathError](https://github.com/tanstack/db/blob/main/docs/reference/classes/EmptyReferencePathError.md)
- [GroupByError](https://github.com/tanstack/db/blob/main/docs/reference/classes/GroupByError.md)
- [HavingRequiresGroupByError](https://github.com/tanstack/db/blob/main/docs/reference/classes/HavingRequiresGroupByError.md)
- [IndexProxy](https://github.com/tanstack/db/blob/main/docs/reference/classes/IndexProxy.md)
- [InvalidCollectionStatusTransitionError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidCollectionStatusTransitionError.md)
- [InvalidJoinCondition](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidJoinCondition.md)
- [InvalidJoinConditionLeftSourceError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidJoinConditionLeftSourceError.md)
- [InvalidJoinConditionRightSourceError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidJoinConditionRightSourceError.md)
- [InvalidJoinConditionSameSourceError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidJoinConditionSameSourceError.md)
- [InvalidJoinConditionSourceMismatchError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidJoinConditionSourceMismatchError.md)
- [InvalidKeyError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidKeyError.md)
- [InvalidSchemaError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidSchemaError.md)
- [InvalidSourceError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidSourceError.md)
- [InvalidSourceTypeError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidSourceTypeError.md)
- [InvalidStorageDataFormatError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidStorageDataFormatError.md)
- [InvalidStorageObjectFormatError](https://github.com/tanstack/db/blob/main/docs/reference/classes/InvalidStorageObjectFormatError.md)
- [JoinCollectionNotFoundError](https://github.com/tanstack/db/blob/main/docs/reference/classes/JoinCollectionNotFoundError.md)
- [JoinConditionMustBeEqualityError](https://github.com/tanstack/db/blob/main/docs/reference/classes/JoinConditionMustBeEqualityError.md)
- [JoinError](https://github.com/tanstack/db/blob/main/docs/reference/classes/JoinError.md)
- [KeyUpdateNotAllowedError](https://github.com/tanstack/db/blob/main/docs/reference/classes/KeyUpdateNotAllowedError.md)
- [LazyIndexWrapper](https://github.com/tanstack/db/blob/main/docs/reference/classes/LazyIndexWrapper.md)
- [LimitOffsetRequireOrderByError](https://github.com/tanstack/db/blob/main/docs/reference/classes/LimitOffsetRequireOrderByError.md)
- [LocalStorageCollectionError](https://github.com/tanstack/db/blob/main/docs/reference/classes/LocalStorageCollectionError.md)
- [MissingAliasInputsError](https://github.com/tanstack/db/blob/main/docs/reference/classes/MissingAliasInputsError.md)
- [MissingDeleteHandlerError](https://github.com/tanstack/db/blob/main/docs/reference/classes/MissingDeleteHandlerError.md)
- [MissingHandlerError](https://github.com/tanstack/db/blob/main/docs/reference/classes/MissingHandlerError.md)
- [MissingInsertHandlerError](https://github.com/tanstack/db/blob/main/docs/reference/classes/MissingInsertHandlerError.md)
- [MissingMutationFunctionError](https://github.com/tanstack/db/blob/main/docs/reference/classes/MissingMutationFunctionError.md)
- [MissingUpdateArgumentError](https://github.com/tanstack/db/blob/main/docs/reference/classes/MissingUpdateArgumentError.md)
- [MissingUpdateHandlerError](https://github.com/tanstack/db/blob/main/docs/reference/classes/MissingUpdateHandlerError.md)
- [NegativeActiveSubscribersError](https://github.com/tanstack/db/blob/main/docs/reference/classes/NegativeActiveSubscribersError.md)
- [NoKeysPassedToDeleteError](https://github.com/tanstack/db/blob/main/docs/reference/classes/NoKeysPassedToDeleteError.md)
- [NoKeysPassedToUpdateError](https://github.com/tanstack/db/blob/main/docs/reference/classes/NoKeysPassedToUpdateError.md)
- [NonAggregateExpressionNotInGroupByError](https://github.com/tanstack/db/blob/main/docs/reference/classes/NonAggregateExpressionNotInGroupByError.md)
- [NonRetriableError](https://github.com/tanstack/db/blob/main/docs/reference/classes/NonRetriableError.md)
- [NoPendingSyncTransactionCommitError](https://github.com/tanstack/db/blob/main/docs/reference/classes/NoPendingSyncTransactionCommitError.md)
- [NoPendingSyncTransactionWriteError](https://github.com/tanstack/db/blob/main/docs/reference/classes/NoPendingSyncTransactionWriteError.md)
- [OnlyOneSourceAllowedError](https://github.com/tanstack/db/blob/main/docs/reference/classes/OnlyOneSourceAllowedError.md)
- [OnMutateMustBeSynchronousError](https://github.com/tanstack/db/blob/main/docs/reference/classes/OnMutateMustBeSynchronousError.md)
- [QueryBuilderError](https://github.com/tanstack/db/blob/main/docs/reference/classes/QueryBuilderError.md)
- [QueryCompilationError](https://github.com/tanstack/db/blob/main/docs/reference/classes/QueryCompilationError.md)
- [QueryMustHaveFromClauseError](https://github.com/tanstack/db/blob/main/docs/reference/classes/QueryMustHaveFromClauseError.md)
- [QueryOptimizerError](https://github.com/tanstack/db/blob/main/docs/reference/classes/QueryOptimizerError.md)
- [SchemaMustBeSynchronousError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SchemaMustBeSynchronousError.md)
- [SchemaValidationError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SchemaValidationError.md)
- [SerializationError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SerializationError.md)
- [SetWindowRequiresOrderByError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SetWindowRequiresOrderByError.md)
- [SortedMap](https://github.com/tanstack/db/blob/main/docs/reference/classes/SortedMap.md)
- [StorageError](https://github.com/tanstack/db/blob/main/docs/reference/classes/StorageError.md)
- [StorageKeyRequiredError](https://github.com/tanstack/db/blob/main/docs/reference/classes/StorageKeyRequiredError.md)
- [SubQueryMustHaveFromClauseError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SubQueryMustHaveFromClauseError.md)
- [SubscriptionNotFoundError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SubscriptionNotFoundError.md)
- [SyncCleanupError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SyncCleanupError.md)
- [SyncTransactionAlreadyCommittedError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SyncTransactionAlreadyCommittedError.md)
- [SyncTransactionAlreadyCommittedWriteError](https://github.com/tanstack/db/blob/main/docs/reference/classes/SyncTransactionAlreadyCommittedWriteError.md)
- [TanStackDBError](https://github.com/tanstack/db/blob/main/docs/reference/classes/TanStackDBError.md)
- [TransactionAlreadyCompletedRollbackError](https://github.com/tanstack/db/blob/main/docs/reference/classes/TransactionAlreadyCompletedRollbackError.md)
- [TransactionError](https://github.com/tanstack/db/blob/main/docs/reference/classes/TransactionError.md)
- [TransactionNotPendingCommitError](https://github.com/tanstack/db/blob/main/docs/reference/classes/TransactionNotPendingCommitError.md)
- [TransactionNotPendingMutateError](https://github.com/tanstack/db/blob/main/docs/reference/classes/TransactionNotPendingMutateError.md)
- [UndefinedKeyError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UndefinedKeyError.md)
- [UnknownExpressionTypeError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UnknownExpressionTypeError.md)
- [UnknownFunctionError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UnknownFunctionError.md)
- [UnknownHavingExpressionTypeError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UnknownHavingExpressionTypeError.md)
- [UnsupportedAggregateFunctionError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UnsupportedAggregateFunctionError.md)
- [UnsupportedFromTypeError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UnsupportedFromTypeError.md)
- [UnsupportedJoinSourceTypeError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UnsupportedJoinSourceTypeError.md)
- [UnsupportedJoinTypeError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UnsupportedJoinTypeError.md)
- [UpdateKeyNotFoundError](https://github.com/tanstack/db/blob/main/docs/reference/classes/UpdateKeyNotFoundError.md)
- [WhereClauseConversionError](https://github.com/tanstack/db/blob/main/docs/reference/classes/WhereClauseConversionError.md)
- [BaseCollectionConfig](https://github.com/tanstack/db/blob/main/docs/reference/interfaces/BaseCollectionConfig.md)
- [BaseStrategy](https://github.com/tanstack/db/blob/main/docs/reference/interfaces/BaseStrategy.md)
- [BTreeIndexOptions](https://github.com/tanstack/db/blob/main/docs/reference/interfaces/BTreeIndexOptions.md)
- [ChangeMessage](https://github.com/tanstack/db/blob/main/docs/reference/interfaces/ChangeMessage.md)
- [Collection](https://github.com/tanstack/db/blob/main/docs/reference/interfaces/Collection.md)
- [CollectionConfig](https://github.com/tanstack/db/blob/main/docs/reference/interfaces/CollectionConfig.md)
- [CollectionLike](https://github.com/tanstack/db/blob/main/docs/reference/interfaces/CollectionLike.md)

--- docs/reference/electric-db-collection/index.md ---
---
id: "@tanstack/electric-db-collection"
title: "@tanstack/electric-db-collection"
---

# @tanstack/electric-db-collection

## Classes

- [ElectricDBCollectionError](classes/ElectricDBCollectionError.md)
- [ExpectedNumberInAwaitTxIdError](classes/ExpectedNumberInAwaitTxIdError.md)
- [StreamAbortedError](classes/StreamAbortedError.md)
- [TimeoutWaitingForMatchError](classes/TimeoutWaitingForMatchError.md)
- [TimeoutWaitingForTxIdError](classes/TimeoutWaitingForTxIdError.md)

## Interfaces

- [ElectricCollectionConfig](interfaces/ElectricCollectionConfig.md)
- [ElectricCollectionUtils](interfaces/ElectricCollectionUtils.md)

## Type Aliases

- [AwaitTxIdFn](type-aliases/AwaitTxIdFn.md)
- [Txid](type-aliases/Txid.md)

## Functions

- [electricCollectionOptions](functions/electricCollectionOptions.md)


## Links discovered
- [ElectricDBCollectionError](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/classes/ElectricDBCollectionError.md)
- [ExpectedNumberInAwaitTxIdError](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/classes/ExpectedNumberInAwaitTxIdError.md)
- [StreamAbortedError](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/classes/StreamAbortedError.md)
- [TimeoutWaitingForMatchError](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/classes/TimeoutWaitingForMatchError.md)
- [TimeoutWaitingForTxIdError](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/classes/TimeoutWaitingForTxIdError.md)
- [ElectricCollectionConfig](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/interfaces/ElectricCollectionConfig.md)
- [ElectricCollectionUtils](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/interfaces/ElectricCollectionUtils.md)
- [AwaitTxIdFn](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/type-aliases/AwaitTxIdFn.md)
- [Txid](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/type-aliases/Txid.md)
- [electricCollectionOptions](https://github.com/tanstack/db/blob/main/docs/reference/electric-db-collection/functions/electricCollectionOptions.md)

--- docs/reference/powersync-db-collection/index.md ---
---
id: "@tanstack/powersync-db-collection"
title: "@tanstack/powersync-db-collection"
---

# @tanstack/powersync-db-collection

## Classes

- [PowerSyncTransactor](classes/PowerSyncTransactor.md)

## Type Aliases

- [BasePowerSyncCollectionConfig](type-aliases/BasePowerSyncCollectionConfig.md)
- [ConfigWithArbitraryCollectionTypes](type-aliases/ConfigWithArbitraryCollectionTypes.md)
- [ConfigWithSQLiteInputType](type-aliases/ConfigWithSQLiteInputType.md)
- [ConfigWithSQLiteTypes](type-aliases/ConfigWithSQLiteTypes.md)
- [CustomSQLiteSerializer](type-aliases/CustomSQLiteSerializer.md)
- [EnhancedPowerSyncCollectionConfig](type-aliases/EnhancedPowerSyncCollectionConfig.md)
- [InferPowerSyncOutputType](type-aliases/InferPowerSyncOutputType.md)
- [PowerSyncCollectionConfig](type-aliases/PowerSyncCollectionConfig.md)
- [PowerSyncCollectionMeta](type-aliases/PowerSyncCollectionMeta.md)
- [PowerSyncCollectionUtils](type-aliases/PowerSyncCollectionUtils.md)
- [SerializerConfig](type-aliases/SerializerConfig.md)
- [TransactorOptions](type-aliases/TransactorOptions.md)

## Variables

- [DEFAULT\_BATCH\_SIZE](variables/DEFAULT_BATCH_SIZE.md)

## Functions

- [powerSyncCollectionOptions](functions/powerSyncCollectionOptions.md)


## Links discovered
- [PowerSyncTransactor](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/classes/PowerSyncTransactor.md)
- [BasePowerSyncCollectionConfig](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/BasePowerSyncCollectionConfig.md)
- [ConfigWithArbitraryCollectionTypes](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/ConfigWithArbitraryCollectionTypes.md)
- [ConfigWithSQLiteInputType](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/ConfigWithSQLiteInputType.md)
- [ConfigWithSQLiteTypes](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/ConfigWithSQLiteTypes.md)
- [CustomSQLiteSerializer](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/CustomSQLiteSerializer.md)
- [EnhancedPowerSyncCollectionConfig](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/EnhancedPowerSyncCollectionConfig.md)
- [InferPowerSyncOutputType](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/InferPowerSyncOutputType.md)
- [PowerSyncCollectionConfig](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/PowerSyncCollectionConfig.md)
- [PowerSyncCollectionMeta](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/PowerSyncCollectionMeta.md)
- [PowerSyncCollectionUtils](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/PowerSyncCollectionUtils.md)
- [SerializerConfig](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/SerializerConfig.md)
- [TransactorOptions](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/type-aliases/TransactorOptions.md)
- [DEFAULT\_BATCH\_SIZE](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/variables/DEFAULT_BATCH_SIZE.md)
- [powerSyncCollectionOptions](https://github.com/tanstack/db/blob/main/docs/reference/powersync-db-collection/functions/powerSyncCollectionOptions.md)

--- examples/angular/todos/README.md ---
# Todos

This project was generated using [Angular CLI](https://github.com/angular/angular-cli) version 20.1.6.

## Development server

To start a local development server, run:

```bash
ng serve
```

Once the server is running, open your browser and navigate to `http://localhost:4200/`. The application will automatically reload whenever you modify any of the source files.

## Code scaffolding

Angular CLI includes powerful code scaffolding tools. To generate a new component, run:

```bash
ng generate component component-name
```

For a complete list of available schematics (such as `components`, `directives`, or `pipes`), run:

```bash
ng generate --help
```

## Building

To build the project run:

```bash
ng build
```

This will compile your project and store the build artifacts in the `dist/` directory. By default, the production build optimizes your application for performance and speed.

## Running unit tests

To execute unit tests with the [Karma](https://karma-runner.github.io) test runner, use the following command:

```bash
ng test
```

## Running end-to-end tests

For end-to-end (e2e) testing, run:

```bash
ng e2e
```

Angular CLI does not come with an end-to-end testing framework by default. You can choose one that suits your needs.

## Additional Resources

For more information on using the Angular CLI, including detailed command references, visit the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.


## Links discovered
- [Angular CLI](https://github.com/angular/angular-cli)
- [Karma](https://karma-runner.github.io)
- [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli)

--- examples/react/offline-transactions/README.md ---
# Welcome to TanStack.com!

This site is built with TanStack Router!

- [TanStack Router Docs](https://tanstack.com/router)

It's deployed automagically with Netlify!

- [Netlify](https://netlify.com/)

## Development

From your terminal:

```sh
pnpm install
pnpm dev
```

This starts your app in development mode, rebuilding assets on file changes.

## Editing and previewing the docs of TanStack projects locally

The documentations for all TanStack projects except for `React Charts` are hosted on [https://tanstack.com](https://tanstack.com), powered by this TanStack Router app.
In production, the markdown doc pages are fetched from the GitHub repos of the projects, but in development they are read from the local file system.

Follow these steps if you want to edit the doc pages of a project (in these steps we'll assume it's [`TanStack/form`](https://github.com/tanstack/form)) and preview them locally :

1. Create a new directory called `tanstack`.

```sh
mkdir tanstack
```

2. Enter the directory and clone this repo and the repo of the project there.

```sh
cd tanstack
git clone git@github.com:TanStack/tanstack.com.git
git clone git@github.com:TanStack/form.git
```

> [!NOTE]
> Your `tanstack` directory should look like this:
>
> ```
> tanstack/
>    |
>    +-- form/
>    |
>    +-- tanstack.com/
> ```

> [!WARNING]
> Make sure the name of the directory in your local file system matches the name of the project's repo. For example, `tanstack/form` must be cloned into `form` (this is the default) instead of `some-other-name`, because that way, the doc pages won't be found.

3. Enter the `tanstack/tanstack.com` directory, install the dependencies and run the app in dev mode:

```sh
cd tanstack.com
pnpm i
# The app will run on https://localhost:3000 by default
pnpm dev
```

4. Now you can visit http://localhost:3000/form/latest/docs/overview in the browser and see the changes you make in `tanstack/form/docs`.

> [!NOTE]
> The updated pages need to be manually reloaded in the browser.

> [!WARNING]
> You will need to update the `docs/config.json` file (in the project's repo) if you add a new doc page!


## Links discovered
- [TanStack Router Docs](https://tanstack.com/router)
- [Netlify](https://netlify.com/)
- [https://tanstack.com](https://tanstack.com)
- [`TanStack/form`](https://github.com/tanstack/form)

--- examples/react/projects/README.md ---
This is a TanStack Start project with tRPC API running on Start's server functions so it's easily deployable to many hosting platforms.

All reads from the Postgres database are done via tRPC queries which populate TanStack DB query collections.

We sync normalized data from tables into TanStack DB collections in the client & then write client-side queries for displaying data in components.

# Getting Started

## Create a new project

To create a new project based on this starter, run the following commands:

```
npx gitpick tanstack/db/tree/main/examples/react/projects my-tanstack-db-project
cd my-tanstack-db-project
```

Copy the .env.example file to .env and fill in the values.

_The database url will be set by default to development postgres docker container, and during development the better-auth secret is not required._

```
cp .env.example .env
```

## Running the Application

**Note: Docker is required to run this starter**

To run this application:

```bash
npm install
npm run dev

# From a separate terminal
npm run migrate
```

# Building For Production

To build this application for production:

```bash
npm run build
```

## Testing

This project uses [Vitest](https://vitest.dev/) for testing. You can run the tests with:

```bash
npm run test
```

## AI

The starter includes an `AGENT.md`. Depending on which AI coding tool you use, you may need to copy/move it to the right file name e.g. `.cursor/rules`.

## Styling

This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.

## Routing

This project uses [TanStack Router](https://tanstack.com/router). The initial setup is a file based router. Which means that the routes are managed as files in `src/routes`.

### Adding A Route

To add a new route to your application just add another a new file in the `./src/routes` directory.

TanStack will automatically generate the content of the route file for you.

Now that you have two routes you can use a `Link` component to navigate between them.

### Adding Links

To use SPA (Single Page Application) navigation you will need to import the `Link` component from `@tanstack/react-router`.

```tsx
import { Link } from '@tanstack/react-router'
```

Then anywhere in your JSX you can use it like so:

```tsx
<Link to="/about">About</Link>
```

This will create a link that will navigate to the `/about` route.

More information on the `Link` component can be found in the [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent).

### Using A Layout

In the File Based Routing setup the layout is located in `src/routes/__root.tsx`. Anything you add to the root route will appear in all the routes. The route content will appear in the JSX where you use the `<Outlet />` component.

Here is an example layout that includes a header:

```tsx
import { Outlet, createRootRoute } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'

import { Link } from '@tanstack/react-router'

export const Route = createRootRoute({
  component: () => (
    <>
      <header>
        <nav>
          <Link to="/">Home</Link>
          <Link to="/about">About</Link>
        </nav>
      </header>
      <Outlet />
      <TanStackRouterDevtools />
    </>
  ),
})
```

The `<TanStackRouterDevtools />` component is not required so you can remove it if you don't want it in your layout.

More information on layouts can be found in the [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts).

## Data Fetching

There are multiple ways to fetch data in your application. You can use TanStack DB to fetch data from a server. But you can also use the `loader` functionality built into TanStack Router to load the data for a route before it's rendered.

For example:

```tsx
const peopleRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/people',
  loader: async () => {
    const response = await fetch('https://swapi.dev/api/people')
    return response.json() as Promise<{
      results: {
        name: string
      }[]
    }>
  },
  component: () => {
    const data = peopleRoute.useLoaderData()
    return (
      <ul>
        {data.results.map((person) => (
          <li key={person.name}>{person.name}</li>
        ))}
      </ul>
    )
  },
})
```

Loaders simplify your data fetching logic dramatically. Check out more information in the [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters).

### TanStack DB with Query Collections

TanStack DB gives you robust support for live queries and optimistic mutations. With no stale data, super fast re-rendering and sub-millisecond cross-collection queries — even for large complex apps.

Built on a TypeScript implementation of differential dataflow, TanStack DB provides:

- 🔥 **Blazing fast query engine** - sub-millisecond live queries, even for complex queries with joins and aggregates
- 🎯 **Fine-grained reactivity** - minimize component re-rendering
- 💪 **Robust transaction primitives** - easy optimistic mutations with sync and lifecycle support
- 🌟 **Normalized data** - keep your backend simple

#### Core Concepts

**Collections** - Typed sets of objects that can mirror a backend table or be populated with filtered views like `pendingTodos` or `decemberNewTodos`. Collections are just JavaScript data that you can load on demand.

**Live Queries** - Run reactively against and across collections with support for joins, filters and aggregates. Powered by differential dataflow, query results update incrementally without re-running the whole query.

**Transactional Optimistic Mutations** - Batch and stage local changes across collections with immediate application of local optimistic updates. Sync transactions to the backend with automatic rollbacks and management of optimistic state.

#### Usage with Query Collections

This example uses Query Collections for server-state synchronization with tRPC:

```tsx
import { createCollection } from '@tanstack/react-db'
import { queryCollectionOptions } from '@tanstack/query-db-collection'
import { QueryClient } from '@tanstack/query-core'

const queryClient = new QueryClient()

export const todoCollection = createCollection(
  queryCollectionOptions<Todo>({
    id: 'todos',
    queryKey: ['todos'],
    queryFn: async () => {
      const todos = await trpc.todos.getAll.query()
      return todos.map((todo) => ({
        ...todo,
        created_at: new Date(todo.created_at),
        updated_at: new Date(todo.updated_at),
      }))
    },
    queryClient,
    schema: todoSchema,
    getKey: (item) => item.id,
    onInsert: async ({ transaction }) => {
      const { modified: newTodo } = transaction.mutations[0]
      const result = await trpc.todos.create.mutate({
        text: newTodo.text,
        completed: newTodo.completed,
        project_id: newTodo.project_id,
      })
      return { txid: result.txid }
    },
    // You can also implement onUpdate, onDelete as needed
  })
)
```

Apply mutations with local optimistic state that automatically syncs:

```tsx
const AddTodo = () => {
  return (
    <Button
      onClick={() =>
        todoCollection.insert({
          id: crypto.randomUUID(),
          text: '🔥 Make app faster',
          completed: false,
        })
      }
    />
  )
}
```

#### Live Queries with Cross-Collection Joins

Use live queries to read data reactively across collections:

```tsx
import { useLiveQuery } from '@tanstack/react-db'

const Todos = () => {
  // Read data using live queries with cross-collection joins
  const { data: todos } = useLiveQuery((query) =>
    query
      .from({ t: todoCollection })
      .join({
        type: 'inner',
        from: { l: listCollection },
        on: [`@l.id`, `=`, `@t.list_id`],
      })
      .where('@l.active', '=', true)
      .select('@t.id', '@t.text', '@t.status', '@l.name')
  )

  return (
    <ul>
      {todos.map((todo) => (
        <li key={todo.id}>
          {todo.text} - {todo.name}
        </li>
      ))}
    </ul>
  )
}
```

This pattern provides blazing fast, cross-collection live queries and local optimistic mutations with automatically managed optimistic state, all synced with your backend via tRPC.

You can learn more about TanStack DB in the [TanStack DB documentation](https://tanstack.com/db/latest/docs/overview).

# Learn More

You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).


## Links discovered
- [Vitest](https://vitest.dev/)
- [Tailwind CSS](https://tailwindcss.com/)
- [TanStack Router](https://tanstack.com/router)
- [Link documentation](https://tanstack.com/router/v1/docs/framework/react/api/router/linkComponent)
- [Layouts documentation](https://tanstack.com/router/latest/docs/framework/react/guide/routing-concepts#layouts)
- [Loader documentation](https://tanstack.com/router/latest/docs/framework/react/guide/data-loading#loader-parameters)
- [TanStack DB documentation](https://tanstack.com/db/latest/docs/overview)
- [TanStack documentation](https://tanstack.com)

--- examples/react/todo/README.md ---
# Todo example app

## How to run

- Go to the root of the repository and run:
  - `pnpm install`
  - `pnpm build`

- Install packages
  `pnpm install`

- Start dev server & Docker containers: Postgres, Electric, TrailBase
  `pnpm dev`

- Run Postgres DB migrations
  `pnpm db:push`

- Optionally, check out the TrailBase admin UI @ http://localhost:4000/\_/admin
  (email: admin@localhost, password: secret)


--- examples/solid/todo/README.md ---
# Todo example app

## How to run

- Go to the root of the repository and run:
  - `pnpm install`
  - `pnpm build`

- Install packages
  `pnpm install`

- Start dev server & Docker containers: Postgres, Electric, TrailBase
  `pnpm dev`

- Run Postgres DB migrations
  `pnpm db:push`

- Optionally, check out the TrailBase admin UI @ http://localhost:4000/\_/admin
  (email: admin@localhost, password: secret)


--- examples/react/paced-mutations-demo/index.html ---
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Paced Mutations Demo</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>


--- examples/react/todo/index.html ---
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link href="/src/styles.css" rel="stylesheet" />
    <title>TODO App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>


--- examples/solid/todo/index.html ---
<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="/vite.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link href="/src/styles.css" rel="stylesheet" />
    <title>TODO App</title>
  </head>
  <body>
    <div id="root"></div>
    <script type="module" src="/src/main.tsx"></script>
  </body>
</html>


--- examples/angular/todos/src/index.html ---
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Todos</title>
    <base href="/" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />
  </head>
  <body>
    <app-root></app-root>
  </body>
</html>


--- examples/react/projects/AGENT.md ---
# TanStack Start + DB Projects Example

This is a TanStack Start project with tRPC API running on Start's server functions so it's easily deployable to many hosting platforms.

All reads from the Postgres database are done via tRPC queries which populate TanStack DB query collections.

We sync normalized data from tables into TanStack DB collections in the client & then write client-side queries for displaying data in components.

## Initial setup

Before you started, all necessary package install is done via `pnpm install` and a dev server is started with `pnpm dev`.

## Linting and formatting

Human devs have IDEs that autoformat code on every file save. After you edit files, you must do the equivalent by running `pnpm lint`.

This command will also report linter errors that were not automatically fixable. Use your judgement as to which of the linter violations should be fixed.

## Build/Test Commands

- `pnpm run dev` - Start development server with Docker services
- `pnpm run build` - Build for production
- `pnpm run test` - Run all Vitest tests
- `vitest run <test-file>` - Run single test file
- `pnpm run start` - Start production server

## Architecture

- **Frontend**: TanStack Start (SSR framework for React and other frameworks) with file-based routing in `src/routes/`
- **Database**: PostgreSQL with Drizzle ORM, schema in `src/db/schema.ts`
- **Services**: Docker Compose setup (Postgres on 54321)
- **Styling**: Tailwind CSS v4
- **Authentication**: better-auth
- **API**: tRPC for full e2e typesafety.

## Code Style

- **TypeScript**: Strict mode, ES2022 target, bundler module resolution
- **Imports**: Use `@/*` path aliases for `src/` directory imports
- **Components**: React 19 with JSX transform, functional components preferred
- **Server DB**: Drizzle ORM with PostgreSQL dialect, schema-first approach
- **Client DB**: TanStack DB with Query Collections
- **Routing**: File-based with TanStack Router, use `Link` component for navigation
- **Testing**: Vitest with @testing-library/react for component tests
- **file names** should always use kebab-case


--- packages/offline-transactions/src/api/OfflineAction.ts ---
import { OnMutateMustBeSynchronousError } from '@tanstack/db'
import { OfflineTransaction } from './OfflineTransaction'
import type { Transaction } from '@tanstack/db'
import type {
  CreateOfflineActionOptions,
  OfflineMutationFn,
  OfflineTransaction as OfflineTransactionType,
} from '../types'

function isPromiseLike(value: unknown): value is PromiseLike<unknown> {
  return (
    !!value &&
    (typeof value === `object` || typeof value === `function`) &&
    typeof (value as { then?: unknown }).then === `function`
  )
}

export function createOfflineAction<T>(
  options: CreateOfflineActionOptions<T>,
  mutationFn: OfflineMutationFn,
  persistTransaction: (tx: OfflineTransactionType) => Promise<void>,
  executor: any,
): (variables: T) => Transaction {
  const { mutationFnName, onMutate } = options
  console.log(`createOfflineAction 2`, options)

  return (variables: T): Transaction => {
    const offlineTransaction = new OfflineTransaction(
      {
        mutationFnName,
        autoCommit: false,
      },
      mutationFn,
      persistTransaction,
      executor,
    )

    const transaction = offlineTransaction.mutate(() => {
      console.log(`mutate`)
      const maybePromise = onMutate(variables) as unknown

      if (isPromiseLike(maybePromise)) {
        throw new OnMutateMustBeSynchronousError()
      }
    })

    // Immediately commit
    const commitPromise = (async () => {
      try {
        await transaction.commit()
        console.log(`offlineAction committed - success`)
      } catch {
        console.log(`offlineAction commit failed - error`)
      }
    })()

    // Don't await - this is fire-and-forget for optimistic actions
    // But catch to prevent unhandled rejection
    commitPromise.catch(() => {
      // Already handled in try/catch above
    })

    return transaction
  }
}


--- packages/offline-transactions/src/api/OfflineTransaction.ts ---
import { createTransaction } from '@tanstack/db'
import { NonRetriableError } from '../types'
import type { PendingMutation, Transaction } from '@tanstack/db'
import type {
  CreateOfflineTransactionOptions,
  OfflineMutationFn,
  OfflineTransaction as OfflineTransactionType,
} from '../types'

export class OfflineTransaction {
  private offlineId: string
  private mutationFnName: string
  private autoCommit: boolean
  private idempotencyKey: string
  private metadata: Record<string, any>
  private transaction: Transaction | null = null
  private persistTransaction: (tx: OfflineTransactionType) => Promise<void>
  private executor: any // Will be typed properly - reference to OfflineExecutor

  constructor(
    options: CreateOfflineTransactionOptions,
    mutationFn: OfflineMutationFn,
    persistTransaction: (tx: OfflineTransactionType) => Promise<void>,
    executor: any,
  ) {
    this.offlineId = crypto.randomUUID()
    this.mutationFnName = options.mutationFnName
    this.autoCommit = options.autoCommit ?? true
    this.idempotencyKey = options.idempotencyKey ?? crypto.randomUUID()
    this.metadata = options.metadata ?? {}
    this.persistTransaction = persistTransaction
    this.executor = executor
  }

  mutate(callback: () => void): Transaction {
    this.transaction = createTransaction({
      id: this.offlineId,
      autoCommit: false,
      mutationFn: async () => {
        // This is the blocking mutationFn that waits for the executor
        // First persist the transaction to the outbox
        const offlineTransaction: OfflineTransactionType = {
          id: this.offlineId,
          mutationFnName: this.mutationFnName,
          mutations: this.transaction!.mutations,
          keys: this.extractKeys(this.transaction!.mutations),
          idempotencyKey: this.idempotencyKey,
          createdAt: new Date(),
          retryCount: 0,
          nextAttemptAt: Date.now(),
          metadata: this.metadata,
          spanContext: undefined,
          version: 1,
        }

        const completionPromise = this.executor.waitForTransactionCompletion(
          this.offlineId,
        )

        try {
          await this.persistTransaction(offlineTransaction)
          // Now block and wait for the executor to complete the real mutation
          await completionPromise
        } catch (error) {
          const normalizedError =
            error instanceof Error ? error : new Error(String(error))
          this.executor.rejectTransaction(this.offlineId, normalizedError)
          throw error
        }

        return
      },
      metadata: this.metadata,
    })

    this.transaction.mutate(() => {
      callback()
    })

    if (this.autoCommit) {
      // Auto-commit for direct OfflineTransaction usage
      this.commit().catch((error) => {
        console.error(`Auto-commit failed:`, error)
        throw error
      })
    }

    return this.transaction
  }

  async commit(): Promise<Transaction> {
    if (!this.transaction) {
      throw new Error(`No mutations to commit. Call mutate() first.`)
    }

    try {
      // Commit the TanStack DB transaction
      // This will trigger the mutationFn which handles persistence and waiting
      await this.transaction.commit()
      return this.transaction
    } catch (error) {
      // Only rollback for NonRetriableError - other errors should allow retry
      if (error instanceof NonRetriableError) {
        this.transaction.rollback()
      }
      throw error
    }
  }

  rollback(): void {
    if (this.transaction) {
      this.transaction.rollback()
    }
  }

  private extractKeys(mutations: Array<PendingMutation>): Array<string> {
    return mutations.map((mutation) => mutation.globalKey)
  }

  get id(): string {
    return this.offlineId
  }
}


--- packages/angular-db/CHANGELOG.md ---
# @tanstack/angular-db

## 0.1.38

### Patch Changes

- Updated dependencies [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0), [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435), [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)]:
  - @tanstack/db@0.5.12

## 0.1.37

### Patch Changes

- Fixed `isReady` to return `true` for disabled queries in `useLiveQuery`/`injectLiveQuery` across all framework packages. When a query function returns `null` or `undefined` (disabling the query), there's no async operation to wait for, so the hook should be considered "ready" immediately. ([#886](https://github.com/TanStack/db/pull/886))

  Additionally, all frameworks now have proper TypeScript overloads that explicitly support returning `undefined | null` from query functions, making the disabled query pattern type-safe.

  This fixes the common pattern where users conditionally enable queries and don't want to show loading states when the query is disabled.

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)]:
  - @tanstack/db@0.5.11

## 0.1.36

### Patch Changes

- Updated dependencies [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd), [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)]:
  - @tanstack/db@0.5.10

## 0.1.35

### Patch Changes

- Updated dependencies [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)]:
  - @tanstack/db@0.5.9

## 0.1.34

### Patch Changes

- Updated dependencies [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60), [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)]:
  - @tanstack/db@0.5.8

## 0.1.33

### Patch Changes

- Updated dependencies [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)]:
  - @tanstack/db@0.5.7

## 0.1.32

### Patch Changes

- Updated dependencies [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)]:
  - @tanstack/db@0.5.6

## 0.1.31

### Patch Changes

- Updated dependencies [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)]:
  - @tanstack/db@0.5.5

## 0.1.30

### Patch Changes

- Updated dependencies [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938), [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe), [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116), [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)]:
  - @tanstack/db@0.5.4

## 0.1.29

### Patch Changes

- Updated dependencies [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9), [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)]:
  - @tanstack/db@0.5.3

## 0.1.28

### Patch Changes

- Updated dependencies [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)]:
  - @tanstack/db@0.5.2

## 0.1.27

### Patch Changes

- Updated dependencies [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)]:
  - @tanstack/db@0.5.1

## 0.1.26

### Patch Changes

- Updated dependencies [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/db@0.5.0

## 0.1.25

### Patch Changes

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20

## 0.1.24

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19

## 0.1.23

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18

## 0.1.22

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17

## 0.1.21

### Patch Changes

- Updated dependencies [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110), [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b), [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)]:
  - @tanstack/db@0.4.16

## 0.1.20

### Patch Changes

- Updated dependencies [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)]:
  - @tanstack/db@0.4.15

## 0.1.19

### Patch Changes

- Updated dependencies [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)]:
  - @tanstack/db@0.4.14

## 0.1.18

### Patch Changes

- Updated dependencies [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)]:
  - @tanstack/db@0.4.13

## 0.1.17

### Patch Changes

- Updated dependencies [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477), [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)]:
  - @tanstack/db@0.4.12

## 0.1.16

### Patch Changes

- Updated dependencies [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)]:
  - @tanstack/db@0.4.11

## 0.1.15

### Patch Changes

- Updated dependencies [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a), [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)]:
  - @tanstack/db@0.4.10

## 0.1.14

### Patch Changes

- Updated dependencies [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47), [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13), [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)]:
  - @tanstack/db@0.4.9

## 0.1.13

### Patch Changes

- Updated dependencies [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450), [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)]:
  - @tanstack/db@0.4.8

## 0.1.12

### Patch Changes

- Updated dependencies [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)]:
  - @tanstack/db@0.4.7

## 0.1.11

### Patch Changes

- Updated dependencies [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113), [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)]:
  - @tanstack/db@0.4.6

## 0.1.10

### Patch Changes

- Updated dependencies [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)]:
  - @tanstack/db@0.4.5

## 0.1.9

### Patch Changes

- Updated dependencies [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888), [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd), [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627), [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c), [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)]:
  - @tanstack/db@0.4.4

## 0.1.8

### Patch Changes

- Updated dependencies [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)]:
  - @tanstack/db@0.4.3

## 0.1.7

### Patch Changes

- Updated dependencies [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a), [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534), [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b), [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)]:
  - @tanstack/db@0.4.2

## 0.1.6

### Patch Changes

- Updated dependencies [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)]:
  - @tanstack/db@0.4.1

## 0.1.5

### Patch Changes

- Let collection.subscribeChanges return a subscription object. Move all data loading code related to optimizations into that subscription object. ([#564](https://github.com/TanStack/db/pull/564))

- Updated dependencies [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58), [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f), [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)]:
  - @tanstack/db@0.4.0

## 0.1.4

### Patch Changes

- Updated dependencies [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)]:
  - @tanstack/db@0.3.2

## 0.1.3

### Patch Changes

- Updated dependencies [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)]:
  - @tanstack/db@0.3.1

## 0.1.2

### Patch Changes

- Updated dependencies [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc), [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)]:
  - @tanstack/db@0.3.0

## 0.1.1

### Patch Changes

- Updated dependencies [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5), [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)]:
  - @tanstack/db@0.2.5

## 0.1.0

### Minor Changes

- Add @tanstack/angular-db package with Angular integration for TanStack DB ([#424](https://github.com/TanStack/db/pull/424))

## 0.1.0

### Minor Changes

- Initial release of @tanstack/angular-db package


## Links discovered
- [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0)
- [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435)
- [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)
- [#886](https://github.com/TanStack/db/pull/886)
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd)
- [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)
- [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)
- [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60)
- [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)
- [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)
- [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)
- [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)
- [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938)
- [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe)
- [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116)
- [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)
- [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9)
- [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)
- [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)
- [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)
- [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45)
- [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a)
- [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)
- [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)
- [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9)
- [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)
- [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)
- [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110)
- [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b)
- [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)
- [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)
- [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)
- [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)
- [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477)
- [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)
- [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)
- [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a)
- [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)
- [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47)
- [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13)
- [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)
- [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450)
- [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)
- [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)
- [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113)
- [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)
- [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)
- [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888)
- [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd)
- [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627)
- [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c)
- [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)
- [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)
- [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a)
- [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534)
- [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b)
- [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)
- [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)
- [#564](https://github.com/TanStack/db/pull/564)
- [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f)
- [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)
- [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)
- [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc)
- [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)
- [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5)
- [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)
- [#424](https://github.com/TanStack/db/pull/424)

--- packages/db-collection-e2e/CHANGELOG.md ---
# @tanstack/db-collection-e2e

## 0.0.14

### Patch Changes

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd), [`f458e05`](https://github.com/TanStack/db/commit/f458e05bb6f5b577ba1d1032a48b46cf860f3c9d)]:
  - @tanstack/db@0.5.11
  - @tanstack/query-db-collection@1.0.6
  - @tanstack/electric-db-collection@0.2.12

## 0.0.13

### Patch Changes

- Updated dependencies [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd), [`aebd0fa`](https://github.com/TanStack/db/commit/aebd0fa43345ea28dcdb3f446cdd393de1d1e4b7), [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)]:
  - @tanstack/electric-db-collection@0.2.11
  - @tanstack/db@0.5.10
  - @tanstack/query-db-collection@1.0.5

## 0.0.12

### Patch Changes

- Updated dependencies [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)]:
  - @tanstack/db@0.5.9
  - @tanstack/electric-db-collection@0.2.10
  - @tanstack/query-db-collection@1.0.5

## 0.0.11

### Patch Changes

- Updated dependencies [[`03842c6`](https://github.com/TanStack/db/commit/03842c633eb990448d26d80025d26184c8de58f2)]:
  - @tanstack/electric-db-collection@0.2.9

## 0.0.10

### Patch Changes

- Updated dependencies [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60), [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)]:
  - @tanstack/db@0.5.8
  - @tanstack/electric-db-collection@0.2.8
  - @tanstack/query-db-collection@1.0.5

## 0.0.9

### Patch Changes

- Updated dependencies [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)]:
  - @tanstack/db@0.5.7
  - @tanstack/electric-db-collection@0.2.7
  - @tanstack/query-db-collection@1.0.5

## 0.0.8

### Patch Changes

- Updated dependencies [[`a540d7c`](https://github.com/TanStack/db/commit/a540d7c34042d69cf1f81d1219df5f3f3d57e200), [`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)]:
  - @tanstack/query-db-collection@1.0.5
  - @tanstack/db@0.5.6
  - @tanstack/electric-db-collection@0.2.6

## 0.0.7

### Patch Changes

- Updated dependencies [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)]:
  - @tanstack/query-db-collection@1.0.4
  - @tanstack/db@0.5.5
  - @tanstack/electric-db-collection@0.2.5

## 0.0.6

### Patch Changes

- Fix progressive mode to use fetchSnapshot and atomic swap ([#852](https://github.com/TanStack/db/pull/852))

  Progressive mode was broken because `requestSnapshot()` injected snapshots into the stream in causally correct position, which didn't work properly with the `full` mode stream. This release fixes progressive mode by:

  **Core Changes:**
  - Use `fetchSnapshot()` during initial sync to fetch and apply snapshots immediately in sync transactions
  - Buffer all stream messages during initial sync (renamed flag to `isBufferingInitialSync`)
  - Perform atomic swap on first `up-to-date`: truncate snapshot data → apply buffered messages → mark ready
  - Track txids/snapshots only after atomic swap (enables correct optimistic transaction confirmation)

  **Test Infrastructure:**
  - Added `ELECTRIC_TEST_HOOKS` symbol for test control (hidden from public API)
  - Added `progressiveTestControl.releaseInitialSync()` to E2E test config for explicit transition control
  - Created comprehensive progressive mode E2E test suite (8 tests):
    - Explicit snapshot phase and atomic swap validation
    - Txid tracking behavior (Electric-only)
    - Multiple concurrent snapshots with deduplication
    - Incremental updates after swap
    - Predicate handling and resilience tests

  **Bug Fixes:**
  - Fixed type errors in test files
  - All 166 unit tests + 95 E2E tests passing

- Updated dependencies [[`f66f2cf`](https://github.com/TanStack/db/commit/f66f2cf944bbcc1a34ad7e340de2e78f5e27e666), [`e657a7d`](https://github.com/TanStack/db/commit/e657a7dad71dff6fb3dd24c2824f5b86d9f92cd5), [`f15b2a7`](https://github.com/TanStack/db/commit/f15b2a7081a2a21bd23ba3657fac44fc9c2f39a8), [`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938), [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe), [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116), [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)]:
  - @tanstack/query-db-collection@1.0.3
  - @tanstack/electric-db-collection@0.2.4
  - @tanstack/db@0.5.4

## 0.0.5

### Patch Changes

- Updated dependencies [[`a90f95e`](https://github.com/TanStack/db/commit/a90f95eaeb7cc334955ae5e8ffb98940fce1ecf1), [`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9), [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)]:
  - @tanstack/query-db-collection@1.0.2
  - @tanstack/db@0.5.3
  - @tanstack/electric-db-collection@0.2.3

## 0.0.4

### Patch Changes

- Updated dependencies [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)]:
  - @tanstack/db@0.5.2
  - @tanstack/electric-db-collection@0.2.2
  - @tanstack/query-db-collection@1.0.1

## 0.0.3

### Patch Changes

- Updated dependencies [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38), [`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)]:
  - @tanstack/query-db-collection@1.0.1
  - @tanstack/db@0.5.1
  - @tanstack/electric-db-collection@0.2.1

## 0.0.2

### Patch Changes

- Updated dependencies [[`1afb027`](https://github.com/TanStack/db/commit/1afb027dbf3e34292a418fc549f799c4e0ce8922), [`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`58f119a`](https://github.com/TanStack/db/commit/58f119ac4f1b05dbfff8617f59f53973abdb1920), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`8f746db`](https://github.com/TanStack/db/commit/8f746db61ff160eae9834e0b9d83c40ef315ae12), [`7aceffa`](https://github.com/TanStack/db/commit/7aceffa46e746cff3dee51230dd2f9e09cb24137), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/electric-db-collection@0.2.0
  - @tanstack/db@0.5.0
  - @tanstack/query-db-collection@1.0.0


## Links discovered
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [`f458e05`](https://github.com/TanStack/db/commit/f458e05bb6f5b577ba1d1032a48b46cf860f3c9d)
- [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd)
- [`aebd0fa`](https://github.com/TanStack/db/commit/aebd0fa43345ea28dcdb3f446cdd393de1d1e4b7)
- [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)
- [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)
- [[`03842c6`](https://github.com/TanStack/db/commit/03842c633eb990448d26d80025d26184c8de58f2)
- [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60)
- [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)
- [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)
- [[`a540d7c`](https://github.com/TanStack/db/commit/a540d7c34042d69cf1f81d1219df5f3f3d57e200)
- [`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)
- [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)
- [#852](https://github.com/TanStack/db/pull/852)
- [[`f66f2cf`](https://github.com/TanStack/db/commit/f66f2cf944bbcc1a34ad7e340de2e78f5e27e666)
- [`e657a7d`](https://github.com/TanStack/db/commit/e657a7dad71dff6fb3dd24c2824f5b86d9f92cd5)
- [`f15b2a7`](https://github.com/TanStack/db/commit/f15b2a7081a2a21bd23ba3657fac44fc9c2f39a8)
- [`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938)
- [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe)
- [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116)
- [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)
- [[`a90f95e`](https://github.com/TanStack/db/commit/a90f95eaeb7cc334955ae5e8ffb98940fce1ecf1)
- [`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9)
- [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)
- [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)
- [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [[`1afb027`](https://github.com/TanStack/db/commit/1afb027dbf3e34292a418fc549f799c4e0ce8922)
- [`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`58f119a`](https://github.com/TanStack/db/commit/58f119ac4f1b05dbfff8617f59f53973abdb1920)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`8f746db`](https://github.com/TanStack/db/commit/8f746db61ff160eae9834e0b9d83c40ef315ae12)
- [`7aceffa`](https://github.com/TanStack/db/commit/7aceffa46e746cff3dee51230dd2f9e09cb24137)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)

--- packages/db-ivm/CHANGELOG.md ---
# @tanstack/db-ivm

## 0.1.14

### Patch Changes

- Use row keys for stable tie-breaking in ORDER BY operations instead of hash-based object IDs. ([#957](https://github.com/TanStack/db/pull/957))

  Previously, when multiple rows had equal ORDER BY values, tie-breaking used `globalObjectIdGenerator.getId(key)` which could produce hash collisions and wasn't stable across page reloads for object references. Now, the row key (which is always `string | number` and unique per row) is used directly for tie-breaking, ensuring deterministic and stable ordering.

  This also simplifies the internal `TaggedValue` type from a 3-tuple `[K, V, Tag]` to a 2-tuple `[K, V]`, removing unnecessary complexity.

## 0.1.13

### Patch Changes

- Fix Uint8Array/Buffer comparison to work by content instead of reference. This enables proper equality checks for binary IDs like ULIDs in WHERE clauses using the `eq` function. ([#779](https://github.com/TanStack/db/pull/779))

- Fix bug with setWindow on ordered queries that have no limit. ([#763](https://github.com/TanStack/db/pull/763))

## 0.1.12

### Patch Changes

- Fix bug with setWindow on ordered queries that have no limit. ([#701](https://github.com/TanStack/db/pull/701))

## 0.1.11

### Patch Changes

- Add `utils.setWindow()` method to live query collections to dynamically change limit and offset on ordered queries. ([#663](https://github.com/TanStack/db/pull/663))

  You can now change the pagination window of an ordered live query without recreating the collection:

  ```ts
  const users = createLiveQueryCollection((q) =>
    q
      .from({ user: usersCollection })
      .orderBy(({ user }) => user.name, 'asc')
      .limit(10)
      .offset(0),
  )

  users.utils.setWindow({ offset: 10, limit: 10 })
  ```

## 0.1.10

### Patch Changes

- Redesign of the join operators with direct algorithms for major performance improvements by replacing composition-based joins (inner+anti) with implementation using mass tracking. Delivers significant performance gains while maintaining full correctness for all join types (inner, left, right, full, anti). ([#571](https://github.com/TanStack/db/pull/571))

## 0.1.9

### Patch Changes

- Add support for Date objects to min/max aggregates and range queries when using an index. ([#428](https://github.com/TanStack/db/pull/428))

## 0.1.8

### Patch Changes

- Fix a bug with distinct operator ([#564](https://github.com/TanStack/db/pull/564))

- Change the ivm indexes to use a three level `key->prefix->hash->value` structure, only falling back to structural hashing when there are multiple values for a single prefix. This removes all hashing during the initial run of a query delivering a 2-3x speedup. ([#549](https://github.com/TanStack/db/pull/549))

## 0.1.7

### Patch Changes

- Fix memory leak that results in linear memory growth with incremental changes over time. Thanks to @sorenbs for finding and fixing this. ([#550](https://github.com/TanStack/db/pull/550))

## 0.1.6

### Patch Changes

- optimise key loading into query graph ([#526](https://github.com/TanStack/db/pull/526))

## 0.1.5

### Patch Changes

- Fix bug where different numbers would hash to the same value. This caused distinct not to work properly. ([#525](https://github.com/TanStack/db/pull/525))

## 0.1.4

### Patch Changes

- Check typeof Buffer before instanceof to avoid ReferenceError in browsers ([#519](https://github.com/TanStack/db/pull/519))

## 0.1.3

### Patch Changes

- fix count aggregate function (evaluate only not null field values like SQL count) ([#453](https://github.com/TanStack/db/pull/453))

- Hybrid index implementation to track values and their multiplicities ([#489](https://github.com/TanStack/db/pull/489))

- Replace JSON.stringify based hash function by structural hashing function. ([#491](https://github.com/TanStack/db/pull/491))

## 0.1.2

### Patch Changes

- Optimize order by to lazily load ordered data if a range index is available on the field that is being ordered on. ([#410](https://github.com/TanStack/db/pull/410))

- Optimize joins to use index on the join key when available. ([#335](https://github.com/TanStack/db/pull/335))

## 0.1.1

### Patch Changes

- Fix bug with orderBy that resulted in query results having less rows than the configured limit. ([#405](https://github.com/TanStack/db/pull/405))

## 0.1.0

### Minor Changes

- 0.1 release - first beta 🎉 ([#332](https://github.com/TanStack/db/pull/332))

### Patch Changes

- We have moved development of the differential dataflow implementation from @electric-sql/d2mini to a new @tanstack/db-ivm package inside the tanstack db monorepo to make development simpler. ([#330](https://github.com/TanStack/db/pull/330))


## Links discovered
- [#957](https://github.com/TanStack/db/pull/957)
- [#779](https://github.com/TanStack/db/pull/779)
- [#763](https://github.com/TanStack/db/pull/763)
- [#701](https://github.com/TanStack/db/pull/701)
- [#663](https://github.com/TanStack/db/pull/663)
- [#571](https://github.com/TanStack/db/pull/571)
- [#428](https://github.com/TanStack/db/pull/428)
- [#564](https://github.com/TanStack/db/pull/564)
- [#549](https://github.com/TanStack/db/pull/549)
- [#550](https://github.com/TanStack/db/pull/550)
- [#526](https://github.com/TanStack/db/pull/526)
- [#525](https://github.com/TanStack/db/pull/525)
- [#519](https://github.com/TanStack/db/pull/519)
- [#453](https://github.com/TanStack/db/pull/453)
- [#489](https://github.com/TanStack/db/pull/489)
- [#491](https://github.com/TanStack/db/pull/491)
- [#410](https://github.com/TanStack/db/pull/410)
- [#335](https://github.com/TanStack/db/pull/335)
- [#405](https://github.com/TanStack/db/pull/405)
- [#332](https://github.com/TanStack/db/pull/332)
- [#330](https://github.com/TanStack/db/pull/330)

--- packages/db/CHANGELOG.md ---
# @tanstack/db

## 0.5.12

### Patch Changes

- Enhanced LoadSubsetOptions with separate cursor expressions and offset for flexible pagination. ([#960](https://github.com/TanStack/db/pull/960))

  **⚠️ Breaking Change for Custom Sync Layers / Query Collections:**

  `LoadSubsetOptions.where` no longer includes cursor expressions for pagination. If you have a custom sync layer or query collection that implements `loadSubset`, you must now handle pagination separately:
  - **Cursor-based pagination:** Use the new `cursor` property (`cursor.whereFrom` and `cursor.whereCurrent`) and combine them with `where` yourself
  - **Offset-based pagination:** Use the new `offset` property

  Previously, cursor expressions were baked into the `where` clause. Now they are passed separately so sync layers can choose their preferred pagination strategy.

  **Changes:**
  - Added `CursorExpressions` type with `whereFrom`, `whereCurrent`, and optional `lastKey` properties
  - Added `cursor` to `LoadSubsetOptions` for cursor-based pagination (separate from `where`)
  - Added `offset` to `LoadSubsetOptions` for offset-based pagination support
  - Electric sync layer now makes two parallel `requestSnapshot` calls when cursor is present:
    - One for `whereCurrent` (all ties at boundary, no limit)
    - One for `whereFrom` (rows after cursor, with limit)
  - Query collection serialization now includes `offset` for query key generation
  - Added `truncate` event to collections, emitted when synced data is truncated (e.g., after `must-refetch`)
  - Fixed `setWindow` pagination: cursor expressions are now correctly built when paging through results
  - Fixed offset tracking: `loadNextItems` now passes the correct window offset to prevent incorrect deduplication
  - `CollectionSubscriber` now listens for `truncate` events to reset cursor tracking state

  **Benefits:**
  - Sync layers can choose between cursor-based or offset-based pagination strategies
  - Electric can efficiently handle tie-breaking with two targeted requests
  - Better separation of concerns between filtering (`where`) and pagination (`cursor`/`offset`)
  - `setWindow` correctly triggers backend loading for subsequent pages in multi-column orderBy queries
  - Cursor state is properly reset after truncation, preventing stale cursor data from being used

- Ensure deterministic iteration order for collections and indexes. ([#958](https://github.com/TanStack/db/pull/958))

  **SortedMap improvements:**
  - Added key-based tie-breaking when values compare as equal, ensuring deterministic ordering
  - Optimized to skip value comparison entirely when no comparator is provided (key-only sorting)
  - Extracted `compareKeys` utility to `utils/comparison.ts` for reuse

  **BTreeIndex improvements:**
  - Keys within the same indexed value are now returned in deterministic sorted order
  - Optimized with fast paths for empty sets and single-key sets to avoid unnecessary allocations

  **CollectionStateManager changes:**
  - Collections now always use `SortedMap` for `syncedData`, ensuring deterministic iteration order
  - When no `compare` function is provided, entries are sorted by key only

  This ensures that live queries with `orderBy` and `limit` produce stable, deterministic results even when multiple rows have equal sort values.

- Enhanced multi-column orderBy support with lazy loading and composite cursor optimization. ([#926](https://github.com/TanStack/db/pull/926))

  **Changes:**
  - Create index on first orderBy column even for multi-column orderBy queries, enabling lazy loading with first-column ordering
  - Pass multi-column orderBy to loadSubset with precise composite cursors (e.g., `or(gt(col1, v1), and(eq(col1, v1), gt(col2, v2)))`) for backend optimization
  - Use wide bounds (first column only) for local index operations to ensure no rows are missed
  - Use precise composite cursor for sync layer loadSubset to minimize data transfer

  **Benefits:**
  - Multi-column orderBy queries with limit now support lazy loading (previously disabled)
  - Sync implementations (like Electric) can optimize queries using composite indexes on the backend
  - Local collection uses first-column index efficiently while backend gets precise cursor

- Updated dependencies [[`52c29fa`](https://github.com/TanStack/db/commit/52c29fa83b390ac26341dbf93e79ce0d59543686)]:
  - @tanstack/db-ivm@0.1.14

## 0.5.11

### Patch Changes

- fix(db): compile filter expression once in createFilterFunctionFromExpression ([#954](https://github.com/TanStack/db/pull/954))

  Fixed a performance issue in `createFilterFunctionFromExpression` where the expression was being recompiled on every filter call. This only affected realtime change event filtering for pushed-down predicates at the collection level when using orderBy + limit. The core query engine was not affected as it already compiled predicates once.

- fix(query-db-collection): use deep equality for object field comparison in query observer ([#967](https://github.com/TanStack/db/pull/967))

  Fixed an issue where updating object fields (non-primitives) with `refetch: false` in `onUpdate` handlers would cause the value to rollback to the previous state every other update. The query observer was using shallow equality (`===`) to compare items, which compares object properties by reference rather than by value. This caused the observer to incorrectly detect differences and write stale data back to syncedData. Now uses `deepEquals` for proper value comparison.

## 0.5.10

### Patch Changes

- Type utils in collection options as specific type (e.g. ElectricCollectionUtils) instead of generic UtilsRecord. ([#940](https://github.com/TanStack/db/pull/940))

- Fix proxy to handle frozen objects correctly. Previously, creating a proxy for a frozen object (such as data from state management libraries that freeze their state) would throw a TypeError when attempting to modify properties via the proxy. The proxy now uses an unfrozen internal copy as the Proxy target, allowing modifications to be tracked correctly while preserving the immutability of the original object. ([#933](https://github.com/TanStack/db/pull/933))

  Also adds support for `Object.seal()` and `Object.preventExtensions()` on proxies, allowing these operations to work correctly on change-tracking proxies.

## 0.5.9

### Patch Changes

- Fix bulk insert not detecting duplicate keys within the same batch. Previously, when inserting multiple items with the same key in a single bulk insert operation, later items would silently overwrite earlier ones. Now, a `DuplicateKeyError` is thrown when duplicate keys are detected within the same batch. ([#929](https://github.com/TanStack/db/pull/929))

## 0.5.8

### Patch Changes

- Fix pagination with Date orderBy values when backend has higher precision than JavaScript's millisecond precision. When loading duplicate values during cursor-based pagination, Date values now use a 1ms range query (`gte`/`lt`) instead of exact equality (`eq`) to correctly match all rows that fall within the same millisecond, even if the backend (e.g., PostgreSQL) stores them with microsecond precision. ([#913](https://github.com/TanStack/db/pull/913))

- Fixed incorrect deduplication of limited queries with different where clauses. Previously, a query like `{where: searchFilter, limit: 10}` could be incorrectly deduplicated against a prior query `{where: undefined, limit: 10}`, causing search/filter results to only show cached data. Now, limited queries are only deduplicated when their where clauses are structurally equal. ([#914](https://github.com/TanStack/db/pull/914))

## 0.5.7

### Patch Changes

- Fix change tracking for array items accessed via iteration methods (find, forEach, for...of, etc.) ([#910](https://github.com/TanStack/db/pull/910))

  Previously, modifications to array items retrieved via iteration methods were not tracked by the change proxy because these methods returned raw array elements instead of proxied versions. This caused `getChanges()` to return an empty object, which in turn caused `createOptimisticAction`'s `mutationFn` to never be called when using patterns like:

  ```ts
  collection.update(id, (draft) => {
    const item = draft.items.find((x) => x.id === targetId)
    if (item) {
      item.value = newValue // This change was not tracked!
    }
  })
  ```

  The fix adds proxy handling for array iteration methods similar to how Map/Set iteration is already handled, ensuring that callbacks receive proxied elements and returned elements are properly proxied.

  Also refactors proxy.ts for improved readability by extracting helper functions and hoisting constants to module scope.

## 0.5.6

### Patch Changes

- Fix scheduler handling of lazy left-join/live-query dependencies: treat non-enqueued lazy deps as satisfied to avoid unresolved-dependency deadlocks, and block only when a dep actually has pending work. ([#898](https://github.com/TanStack/db/pull/898))

## 0.5.5

### Patch Changes

- Fix data loss on component remount by implementing reference counting for QueryObserver lifecycle ([#870](https://github.com/TanStack/db/pull/870))

  **What changed vs main:**

  Previously, when live query subscriptions unsubscribed, there was no tracking of which rows were still needed by other active queries. This caused data loss during remounts.

  This PR adds reference counting infrastructure to properly manage QueryObserver lifecycle:
  1. Pass same predicates to `unloadSubset` that were passed to `loadSubset`
  2. Use them to compute the queryKey (via `generateQueryKeyFromOptions`)
  3. Use existing machinery (`queryToRows` map) to find rows that query loaded
  4. Decrement the ref count
  5. GC rows where count reaches 0 (no longer referenced by any active query)

  **Impact:**
  - Navigation back to previously loaded pages shows cached data immediately
  - No unnecessary refetches during quick remounts (< gcTime)
  - Multiple live queries with identical predicates correctly share QueryObservers
  - Proper row-level cleanup when last subscriber leaves
  - TanStack Query's cache lifecycle (gcTime) is fully respected
  - No data leakage from in-flight requests when unsubscribing

## 0.5.4

### Patch Changes

- Fix progressive mode to use fetchSnapshot and atomic swap ([#852](https://github.com/TanStack/db/pull/852))

  Progressive mode was broken because `requestSnapshot()` injected snapshots into the stream in causally correct position, which didn't work properly with the `full` mode stream. This release fixes progressive mode by:

  **Core Changes:**
  - Use `fetchSnapshot()` during initial sync to fetch and apply snapshots immediately in sync transactions
  - Buffer all stream messages during initial sync (renamed flag to `isBufferingInitialSync`)
  - Perform atomic swap on first `up-to-date`: truncate snapshot data → apply buffered messages → mark ready
  - Track txids/snapshots only after atomic swap (enables correct optimistic transaction confirmation)

  **Test Infrastructure:**
  - Added `ELECTRIC_TEST_HOOKS` symbol for test control (hidden from public API)
  - Added `progressiveTestControl.releaseInitialSync()` to E2E test config for explicit transition control
  - Created comprehensive progressive mode E2E test suite (8 tests):
    - Explicit snapshot phase and atomic swap validation
    - Txid tracking behavior (Electric-only)
    - Multiple concurrent snapshots with deduplication
    - Incremental updates after swap
    - Predicate handling and resilience tests

  **Bug Fixes:**
  - Fixed type errors in test files
  - All 166 unit tests + 95 E2E tests passing

- Improved error messages when invalid source types are passed to `.from()` or `.join()` methods. When users mistakenly pass a string, null, array, or other invalid type instead of an object with a collection, they now receive a clear, actionable error message with an example of the correct usage (e.g., `.from({ todos: todosCollection })`). ([#875](https://github.com/TanStack/db/pull/875))

- Migrated paced mutations implementation from `@tanstack/pacer` to `@tanstack/pacer-lite`. The lite version provides the same core functionality with minimal overhead and no external dependencies, making it more suitable for library use. This is an internal implementation change with no impact on the public API - all paced mutation strategies (debounce, throttle, queue) continue to work exactly as before. ([#880](https://github.com/TanStack/db/pull/880))

- Add warning when calling `.preload()` on collections with `on-demand` syncMode. In on-demand mode, data is only loaded when queries request it, so calling `.preload()` on the collection itself is a no-op. Users should create a live query and call `.preload()` on that instead. ([#871](https://github.com/TanStack/db/pull/871))

## 0.5.3

### Patch Changes

- Pass all operators in where clauses to the collection's loadSubset function ([#851](https://github.com/TanStack/db/pull/851))

- Improve type of mutations in transactions ([#854](https://github.com/TanStack/db/pull/854))

## 0.5.2

### Patch Changes

- Fix localStorage collections to properly handle numeric and string IDs without collisions. Previously, operations could target the wrong item when using numeric IDs (e.g., `id: 1`, `id: 2`) after the page reloaded, due to a type mismatch between numeric keys in memory and stringified keys from localStorage. Keys are now encoded with type prefixes (`n:` for numbers, `s:` for strings) to prevent all possible collisions between different key types. ([#845](https://github.com/TanStack/db/pull/845))

## 0.5.1

### Patch Changes

- Upgrade @tanstack/pacer to v0.16.2 and fix AsyncQueuer API usage. The pacer package API changed significantly, requiring updates to how AsyncQueuer is constructed and items are queued in the queueStrategy implementation. ([#840](https://github.com/TanStack/db/pull/840))

## 0.5.0

### Minor Changes

- Implement 3-valued logic (true/false/unknown) for all comparison and logical operators. ([#765](https://github.com/TanStack/db/pull/765))
  Queries with null/undefined values now behave consistently with SQL databases, where UNKNOWN results exclude rows from WHERE clauses.

  **Breaking Change**: This changes the behavior of `WHERE` and `HAVING` clauses when dealing with `null` and `undefined` values.

  **Example 1: Equality checks with null**

  Previously, this query would return all persons with `age = null`:

  ```ts
  q.from(...).where(({ person }) => eq(person.age, null))
  ```

  With 3-valued logic, `eq(anything, null)` evaluates to `null` (UNKNOWN) and is filtered out. Use `isNull()` instead:

  ```ts
  q.from(...).where(({ person }) => isNull(person.age))
  ```

  **Example 2: Comparisons with null values**

  Previously, this query would return persons with `age < 18` OR `age = null`:

  ```ts
  q.from(...).where(({ person }) => lt(person.age, 18))
  ```

  With 3-valued logic, `lt(null, 18)` evaluates to `null` (UNKNOWN) and is filtered out. The same applies to `undefined` values. To include null values, combine with `isNull()`:

  ```ts
  q.from(...).where(({ person }) =>
    or(lt(person.age, 18), isNull(person.age))
  )
  ```

### Patch Changes

- Add optional compareOptions to collection configuration. ([#763](https://github.com/TanStack/db/pull/763))

- Add expression helper utilities for parsing LoadSubsetOptions in queryFn. ([#763](https://github.com/TanStack/db/pull/763))

  When using `syncMode: 'on-demand'`, TanStack DB now provides helper functions to easily parse where clauses, orderBy, and limit predicates into your API's format:
  - `parseWhereExpression`: Parse where clauses with custom handlers for each operator
  - `parseOrderByExpression`: Parse order by into simple array format
  - `extractSimpleComparisons`: Extract simple AND-ed filters
  - `parseLoadSubsetOptions`: Convenience function to parse all options at once
  - `walkExpression`, `extractFieldPath`, `extractValue`: Lower-level helpers

  **Example:**

  ```typescript
  import { parseLoadSubsetOptions } from '@tanstack/db'
  // or from "@tanstack/query-db-collection" (re-exported for convenience)

  queryFn: async (ctx) => {
    const { where, orderBy, limit } = ctx.meta.loadSubsetOptions

    const parsed = parseLoadSubsetOptions({ where, orderBy, limit })

    // Build API request from parsed filters
    const params = new URLSearchParams()
    parsed.filters.forEach(({ field, operator, value }) => {
      if (operator === 'eq') {
        params.set(field.join('.'), String(value))
      }
    })

    return fetch(`/api/products?${params}`).then((r) => r.json())
  }
  ```

  This eliminates the need to manually traverse expression AST trees when implementing predicate push-down.

- Fix Uint8Array/Buffer comparison to work by content instead of reference. This enables proper equality checks for binary IDs like ULIDs in WHERE clauses using the `eq` function. ([#779](https://github.com/TanStack/db/pull/779))

- Add predicate comparison and merging utilities (isWhereSubset, intersectWherePredicates, unionWherePredicates, and related functions) to support predicate push-down in collection sync operations, enabling efficient tracking of loaded data ranges and preventing redundant server requests. Includes performance optimizations for large primitive IN predicates and full support for Date objects in equality, range, and IN clause comparisons. ([#763](https://github.com/TanStack/db/pull/763))

- Add support for orderBy and limit in currentStateAsChanges function ([#763](https://github.com/TanStack/db/pull/763))

- Adds an onDeduplicate callback on the DeduplicatedLoadSubset class which is called when a loadSubset call is deduplicated ([#763](https://github.com/TanStack/db/pull/763))

- Updated dependencies [[`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)]:
  - @tanstack/db-ivm@0.1.13

## 0.4.20

### Patch Changes

- Fix type inference for findOne() when used with join operations ([#749](https://github.com/TanStack/db/pull/749))

  Previously, using `findOne()` with join operations (leftJoin, innerJoin, etc.) resulted in the query type being inferred as `never`, breaking TypeScript type checking:

  ```typescript
  const query = useLiveQuery(
    (q) =>
      q
        .from({ todo: todoCollection })
        .leftJoin({ todoOptions: todoOptionsCollection }, ...)
        .findOne() // Type became 'never'
  )
  ```

  **The Fix:**

  Fixed the `MergeContextWithJoinType` type definition to conditionally include the `singleResult` property only when it's explicitly `true`, avoiding type conflicts when `findOne()` is called after joins:

  ```typescript
  // Before (buggy):
  singleResult: TContext['singleResult'] extends true ? true : false

  // After (fixed):
  type PreserveSingleResultFlag<TFlag> = [TFlag] extends [true]
    ? { singleResult: true }
    : {}

  // Used as:
  } & PreserveSingleResultFlag<TContext['singleResult']>
  ```

  **Why This Works:**

  By using a conditional intersection that omits the property entirely when not needed, we avoid type conflicts. Intersecting `{} & { singleResult: true }` cleanly results in `{ singleResult: true }`, whereas the previous approach created conflicting property types resulting in `never`. The tuple wrapper (`[TFlag]`) ensures robust behavior even if the flag type becomes a union in the future.

  **Impact:**
  - ✅ `findOne()` now works correctly with all join types
  - ✅ Type inference works properly in `useLiveQuery` and other contexts
  - ✅ Both `findOne()` before and after joins work correctly
  - ✅ All tests pass with no breaking changes (8 new type tests added)

- Improve error messages for custom getKey with joined queries ([#717](https://github.com/TanStack/db/pull/717))

  Enhanced `DuplicateKeySyncError` to provide context-aware guidance when duplicate keys occur with custom `getKey` and joined queries.

  **The Issue:**

  When using custom `getKey` with joins, duplicate keys can occur if the join produces multiple rows with the same key value. This is valid for 1:1 relationships but problematic for 1:many relationships, and the previous error message didn't explain what went wrong or how to fix it.

  **What's New:**

  When a duplicate key error occurs in a live query collection that uses both custom `getKey` and joins, the error message now:
  - Explains that joined queries can produce multiple rows with the same key
  - Suggests using a composite key in your `getKey` function
  - Provides concrete examples of solutions
  - Helps distinguish between correctly structured 1:1 joins vs problematic 1:many joins

  **Example:**

  ```typescript
  // ✅ Valid - 1:1 relationship with unique keys
  const userProfiles = createLiveQueryCollection({
    query: (q) =>
      q
        .from({ profile: profiles })
        .join({ user: users }, ({ profile, user }) =>
          eq(profile.userId, user.id),
        ),
    getKey: (profile) => profile.id, // Each profile has unique ID
  })
  ```

  ```typescript
  // ⚠️ Problematic - 1:many relationship with duplicate keys
  const userComments = createLiveQueryCollection({
    query: (q) =>
      q
        .from({ user: users })
        .join({ comment: comments }, ({ user, comment }) =>
          eq(user.id, comment.userId),
        ),
    getKey: (item) => item.userId, // Multiple comments share same userId!
  })

  // Enhanced error message:
  // "Cannot insert document with key "user1" from sync because it already exists.
  // This collection uses a custom getKey with joined queries. Joined queries can
  // produce multiple rows with the same key when relationships are not 1:1.
  // Consider: (1) using a composite key in your getKey function (e.g., `${item.key1}-${item.key2}`),
  // (2) ensuring your join produces unique rows per key, or (3) removing the
  // custom getKey to use the default composite key behavior."
  ```

- Add QueryObserver state utilities and convert error utils to getters ([#742](https://github.com/TanStack/db/pull/742))

  Exposes TanStack Query's QueryObserver state through QueryCollectionUtils, providing visibility into sync status beyond just error states. Also converts existing error state utilities from methods to getters for consistency with TanStack DB/Query patterns.

  **Breaking Changes:**
  - `lastError()`, `isError()`, and `errorCount()` are now getters instead of methods
    - Before: `collection.utils.lastError()`
    - After: `collection.utils.lastError`

  **New Utilities:**
  - `isFetching` - Check if query is currently fetching (initial or background)
  - `isRefetching` - Check if query is refetching in background
  - `isLoading` - Check if query is loading for first time
  - `dataUpdatedAt` - Get timestamp of last successful data update
  - `fetchStatus` - Get current fetch status ('fetching' | 'paused' | 'idle')

  **Use Cases:**
  - Show loading indicators during background refetches
  - Implement "Last updated X minutes ago" UI patterns
  - Better understanding of query sync behavior

  **Example Usage:**

  ```ts
  const collection = queryCollectionOptions({
    // ... config
  })

  // Check sync status
  if (collection.utils.isFetching) {
    console.log('Syncing with server...')
  }

  if (collection.utils.isRefetching) {
    console.log('Background refresh in progress')
  }

  // Show last update time
  const lastUpdate = new Date(collection.utils.dataUpdatedAt)
  console.log(`Last synced: ${lastUpdate.toLocaleTimeString()}`)

  // Check error state (now using getters)
  if (collection.utils.isError) {
    console.error('Sync failed:', collection.utils.lastError)
    console.log(`Failed ${collection.utils.errorCount} times`)
  }
  ```

## 0.4.19

### Patch Changes

- Significantly improve localStorage collection performance during rapid mutations ([#760](https://github.com/TanStack/db/pull/760))

  Optimizes localStorage collections to eliminate redundant storage reads, providing dramatic performance improvements for use cases with rapid mutations (e.g., text input with live query rendering).

  **Performance Improvements:**
  - **67% reduction in localStorage I/O operations** - from 3 reads + 1 write per mutation down to just 1 write
  - Eliminated 2 JSON parse operations per mutation
  - Eliminated 1 full collection diff operation per mutation
  - Leverages in-memory cache (`lastKnownData`) instead of reading from storage on every mutation

  **What Changed:**
  1. **Mutation handlers** now use in-memory cache instead of loading from storage before mutations
  2. **Post-mutation sync** eliminated - no longer triggers redundant storage reads after local mutations
  3. **Manual transactions** (`acceptMutations`) optimized to use in-memory cache

  **Before:** Each mutation performed 3 I/O operations:
  - `loadFromStorage()` - read + JSON parse
  - Modify data
  - `saveToStorage()` - JSON stringify + write
  - `processStorageChanges()` - another read + parse + diff

  **After:** Each mutation performs 1 I/O operation:
  - Modify in-memory data ✨ No I/O!
  - `saveToStorage()` - JSON stringify + write

  **Safety:**
  - Cross-tab synchronization still works correctly via storage event listeners
  - All 50 tests pass including 8 new tests specifically for rapid mutations and edge cases
  - 92.3% code coverage on local-storage.ts
  - `lastKnownData` cache kept in sync with storage through initial load, mutations, and cross-tab events

  This optimization is particularly impactful for applications with:
  - Real-time text input with live query rendering
  - Frequent mutations to localStorage-backed collections
  - Multiple rapid sequential mutations

## 0.4.18

### Patch Changes

- Fix bug with orderBy that caused queries to skip duplicate values and/or stall on duplicate values. ([#713](https://github.com/TanStack/db/pull/713))

- Validate against duplicate collection aliases in subqueries. Prevents a bug where using the same alias for a collection in both parent and subquery causes empty results or incorrect aggregation values. Now throws a clear `DuplicateAliasInSubqueryError` when this pattern is detected, guiding users to rename the conflicting alias. ([#719](https://github.com/TanStack/db/pull/719))

## 0.4.17

### Patch Changes

- Add offline-transactions package with robust offline-first capabilities ([#559](https://github.com/TanStack/db/pull/559))

  New package `@tanstack/offline-transactions` provides a comprehensive offline-first transaction system with:

  **Core Features:**
  - Persistent outbox pattern for reliable transaction processing
  - Leader election for multi-tab coordination (Web Locks API with BroadcastChannel fallback)
  - Automatic storage capability detection with graceful degradation
  - Retry logic with exponential backoff and jitter
  - Sequential transaction processing (FIFO ordering)

  **Storage:**
  - Automatic fallback chain: IndexedDB → localStorage → online-only
  - Detects and handles private mode, SecurityError, QuotaExceededError
  - Custom storage adapter support
  - Diagnostic callbacks for storage failures

  **Developer Experience:**
  - TypeScript-first with full type safety
  - Comprehensive test suite (25 tests covering leader failover, storage failures, e2e scenarios)
  - Works in all modern browsers and server-side rendering environments

  **@tanstack/db improvements:**
  - Enhanced duplicate instance detection (dev-only, iframe-aware, with escape hatch)
  - Better environment detection for SSR and worker contexts

  Example usage:

  ```typescript
  import {
    startOfflineExecutor,
    IndexedDBAdapter,
  } from '@tanstack/offline-transactions'

  const executor = startOfflineExecutor({
    collections: { todos: todoCollection },
    storage: new IndexedDBAdapter(),
    mutationFns: {
      syncTodos: async ({ transaction, idempotencyKey }) => {
        // Sync mutations to backend
        await api.sync(transaction.mutations, idempotencyKey)
      },
    },
    onStorageFailure: (diagnostic) => {
      console.warn('Running in online-only mode:', diagnostic.message)
    },
  })

  // Create offline transaction
  const tx = executor.createOfflineTransaction({
    mutationFnName: 'syncTodos',
    autoCommit: false,
  })

  tx.mutate(() => {
    todoCollection.insert({ id: '1', text: 'Buy milk', completed: false })
  })

  await tx.commit() // Persists to outbox and syncs when online
  ```

## 0.4.16

### Patch Changes

- Enable auto-indexing for nested field paths ([#728](https://github.com/TanStack/db/pull/728))

  Previously, auto-indexes were only created for top-level fields. Queries filtering on nested fields like `vehicleDispatch.date` or `profile.score` were forced to perform full table scans, causing significant performance issues.

  Now, auto-indexes are automatically created for nested field paths of any depth when using `eq()`, `gt()`, `gte()`, `lt()`, `lte()`, or `in()` operations.

  **Performance Impact:**

  Before this fix, filtering on nested fields resulted in expensive full scans:
  - Query time: ~353ms for 39 executions (from issue #727)
  - "graph run" and "d2ts join" operations dominated execution time

  After this fix, nested field queries use indexes:
  - Query time: Sub-millisecond (typical indexed lookup)
  - Proper index utilization verified through query optimizer

  **Example:**

  ```typescript
  const collection = createCollection({
    getKey: (item) => item.id,
    autoIndex: 'eager', // default
    // ... sync config
  })

  // These now automatically create and use indexes:
  collection.subscribeChanges((items) => console.log(items), {
    whereExpression: eq(row.vehicleDispatch?.date, '2024-01-01'),
  })

  collection.subscribeChanges((items) => console.log(items), {
    whereExpression: gt(row.profile?.stats.rating, 4.5),
  })
  ```

  **Index Naming:**

  Auto-indexes for nested paths use the format `auto:field.path` to avoid naming conflicts:
  - `auto:status` for top-level field `status`
  - `auto:profile.score` for nested field `profile.score`
  - `auto:metadata.stats.views` for deeply nested field `metadata.stats.views`

  Fixes #727

- Fixed performance issue where using multiple `.where()` calls created multiple filter operators in the query pipeline. The optimizer now implements the missing final step (step 3) of combining remaining WHERE clauses into a single AND expression. This applies to both queries with and without joins: ([#732](https://github.com/TanStack/db/pull/732))
  - Queries without joins: Multiple WHERE clauses are now combined before compilation
  - Queries with joins: Remaining WHERE clauses after predicate pushdown are combined

  This reduces filter operators from N to 1, making chained `.where()` calls perform identically to using a single `.where()` with `and()`.

- Add paced mutations with pluggable timing strategies ([#704](https://github.com/TanStack/db/pull/704))

  Introduces a new paced mutations system that enables optimistic mutations with pluggable timing strategies. This provides fine-grained control over when and how mutations are persisted to the backend. Powered by [TanStack Pacer](https://github.com/TanStack/pacer).

  **Key Design:**
  - **Debounce/Throttle**: Only one pending transaction (collecting mutations) and one persisting transaction (writing to backend) at a time. Multiple rapid mutations automatically merge together.
  - **Queue**: Each mutation creates a separate transaction, guaranteed to run in the order they're made (FIFO by default, configurable to LIFO).

  **Core Features:**
  - **Pluggable Strategy System**: Choose from debounce, queue, or throttle strategies to control mutation timing
  - **Auto-merging Mutations**: Multiple rapid mutations on the same item automatically merge for efficiency (debounce/throttle only)
  - **Transaction Management**: Full transaction lifecycle tracking (pending → persisting → completed/failed)
  - **React Hook**: `usePacedMutations` for easy integration in React applications

  **Available Strategies:**
  - `debounceStrategy`: Wait for inactivity before persisting. Only final state is saved. (ideal for auto-save, search-as-you-type)
  - `queueStrategy`: Each mutation becomes a separate transaction, processed sequentially in order (defaults to FIFO, configurable to LIFO). All mutations are guaranteed to persist. (ideal for sequential workflows, rate-limited APIs)
  - `throttleStrategy`: Ensure minimum spacing between executions. Mutations between executions are merged. (ideal for analytics, progress updates)

  **Example Usage:**

  ```ts
  import { usePacedMutations, debounceStrategy } from '@tanstack/react-db'

  const mutate = usePacedMutations({
    mutationFn: async ({ transaction }) => {
      await api.save(transaction.mutations)
    },
    strategy: debounceStrategy({ wait: 500 }),
  })

  // Trigger a mutation
  const tx = mutate(() => {
    collection.update(id, (draft) => {
      draft.value = newValue
    })
  })

  // Optionally await persistence
  await tx.isPersisted.promise
  ```

## 0.4.15

### Patch Changes

- Added support for custom parsers/serializers like superjson in LocalStorage collections ([#730](https://github.com/TanStack/db/pull/730))

## 0.4.14

### Patch Changes

- Fix collection cleanup to fire status:change event with 'cleaned-up' status ([#714](https://github.com/TanStack/db/pull/714))

  Previously, when a collection was garbage collected, event handlers were removed before the status was changed to 'cleaned-up'. This prevented listeners from receiving the status:change event, breaking the collection factory pattern where collections listen for cleanup to remove themselves from a cache.

  Now, the cleanup process:
  1. Cleans up sync, state, changes, and indexes
  2. Sets status to 'cleaned-up' (fires the event)
  3. Finally cleans up event handlers

  This enables the collection factory pattern:

  ```typescript
  const cache = new Map<string, ReturnType<typeof createCollection>>()

  const getTodoCollection = (id: string) => {
    if (!cache.has(id)) {
      const collection = createCollection(/* ... */)

      collection.on('status:change', ({ status }) => {
        if (status === 'cleaned-up') {
          cache.delete(id) // This now works!
        }
      })

      cache.set(id, collection)
    }
    return cache.get(id)!
  }
  ```

## 0.4.13

### Patch Changes

- Fix synced propagation when preceding mutation was non-optimistic ([#715](https://github.com/TanStack/db/pull/715))

## 0.4.12

### Patch Changes

- Add in-memory fallback for localStorage collections in SSR environments ([#696](https://github.com/TanStack/db/pull/696))

  Prevents errors when localStorage collections are imported on the server by automatically falling back to an in-memory store. This allows isomorphic JavaScript applications to safely import localStorage collection modules without errors during module initialization.

  When localStorage is not available (e.g., in server-side rendering environments), the collection automatically uses an in-memory storage implementation. Data will not persist across page reloads or be shared across tabs when using the in-memory fallback, but the collection will function normally otherwise.

  Fixes #691

- Add support for orderBy and limit in currentStateAsChanges function ([#701](https://github.com/TanStack/db/pull/701))

- Updated dependencies [[`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)]:
  - @tanstack/db-ivm@0.1.12

## 0.4.11

### Patch Changes

- Add support for pre-created live query collections in useLiveInfiniteQuery, enabling router loader patterns where live queries can be created, preloaded, and passed to components. ([#684](https://github.com/TanStack/db/pull/684))

## 0.4.10

### Patch Changes

- Add `utils.setWindow()` method to live query collections to dynamically change limit and offset on ordered queries. ([#663](https://github.com/TanStack/db/pull/663))

  You can now change the pagination window of an ordered live query without recreating the collection:

  ```ts
  const users = createLiveQueryCollection((q) =>
    q
      .from({ user: usersCollection })
      .orderBy(({ user }) => user.name, 'asc')
      .limit(10)
      .offset(0),
  )

  users.utils.setWindow({ offset: 10, limit: 10 })
  ```

- Added comprehensive loading state tracking and configurable sync modes to collections and live queries: ([#669](https://github.com/TanStack/db/pull/669))
  - Added `isLoadingSubset` property and `loadingSubset:change` events to all collections for tracking when data is being loaded
  - Added `syncMode` configuration option to collections:
    - `'eager'` (default): Loads all data immediately during initial sync
    - `'on-demand'`: Only loads data as requested via `loadSubset` calls
  - Added comprehensive status tracking to collection subscriptions with `status` property (`'ready'` | `'loadingSubset'`) and events (`status:change`, `status:ready`, `status:loadingSubset`, `unsubscribed`)
  - Live queries automatically reflect loading state from their source collection subscriptions, with each query maintaining isolated loading state to prevent status "bleed" between independent queries
  - Enhanced `setWindow` utility to return `Promise<void>` when loading is triggered, allowing callers to await data loading completion
  - Added `subscription` parameter to `loadSubset` handler for advanced sync implementations that need to track subscription lifecycle

- Updated dependencies [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a)]:
  - @tanstack/db-ivm@0.1.11

## 0.4.9

### Patch Changes

- Fix self-join bug by implementing per-alias subscriptions in live queries ([#625](https://github.com/TanStack/db/pull/625))

- Stop pushing where clauses that target renamed subquery projections so alias remapping stays intact, preventing a bug where a where clause would not be executed correctly. ([#654](https://github.com/TanStack/db/pull/654))

- Add a scheduler that ensures that if a transaction touches multiple collections that feed into a single live query, the live query only emits a single batch of updates. This fixes an issue where multiple renders could be triggered from a live query under this situation. ([#628](https://github.com/TanStack/db/pull/628))

- Updated dependencies [[`eeb05d4`](https://github.com/TanStack/db/commit/eeb05d449defbaaac584f4bb8febcb8946cfdf21)]:
  - @tanstack/db-ivm@0.1.10

## 0.4.8

### Patch Changes

- Fixed critical bug where optimistic mutations were lost when their async handlers completed during a truncate operation. The fix captures a snapshot of optimistic state when `truncate()` is called and restores it during commit, then overlays any still-active transactions to handle late-arriving mutations. This ensures client-side optimistic state is preserved through server-initiated must-refetch scenarios. ([#659](https://github.com/TanStack/db/pull/659))

- Refactored live queries to execute eagerly during sync. Live queries now materialize their results immediately as data arrives from source collections, even while those collections are still in a "loading" state, rather than waiting for all sources to be "ready" before executing. ([#658](https://github.com/TanStack/db/pull/658))

## 0.4.7

### Patch Changes

- Add acceptMutations utility for local collections in manual transactions. Local-only and local-storage collections now expose `utils.acceptMutations(transaction, collection)` that must be called in manual transaction `mutationFn` to persist mutations. ([#638](https://github.com/TanStack/db/pull/638))

## 0.4.6

### Patch Changes

- Push predicates down to sync layer ([#617](https://github.com/TanStack/db/pull/617))

- prefix logs and errors with collection id, when available ([#655](https://github.com/TanStack/db/pull/655))

## 0.4.5

### Patch Changes

- Fixed race condition which could result in a live query throwing and becoming stuck after multiple mutations complete asynchronously. ([#650](https://github.com/TanStack/db/pull/650))

## 0.4.4

### Patch Changes

- Fix live queries getting stuck during long-running sync commits by always ([#631](https://github.com/TanStack/db/pull/631))
  clearing the batching flag on forced emits, tolerating duplicate insert echoes,
  and allowing optimistic recomputes to run while commits are still applying. Adds
  regression coverage for concurrent optimistic inserts, queued updates, and the
  offline-transactions example to ensure everything stays in sync.

- Fixed bug where orderBy would fail when a collection alias had the same name as one of its schema fields. For example, .from({ email: emailCollection }).orderBy(({ email }) => email.createdAt) now works correctly even when the collection has an email field in its schema. ([#637](https://github.com/TanStack/db/pull/637))

- Optimization: reverse the index when the direction does not match. ([#627](https://github.com/TanStack/db/pull/627))

- Fixed a bug that could result in a duplicate delete event for a row ([#621](https://github.com/TanStack/db/pull/621))

- Fix bug where optimized queries would use the wrong index because the index is on the right column but was built using different comparison options (e.g. different direction, string sort, or null ordering). ([#623](https://github.com/TanStack/db/pull/623))

## 0.4.3

### Patch Changes

- Remove circular imports to fix compatibility with Metro bundler ([#605](https://github.com/TanStack/db/pull/605))

## 0.4.2

### Patch Changes

- Add support for Date objects to min/max aggregates and range queries when using an index. ([#428](https://github.com/TanStack/db/pull/428))

- Prevent pushing down of where clauses that only touch the namespace of a source, rather than a prop on that namespace. This ensures that the semantics of the query are maintained for things such as `isUndefined(namespace)` after a join. ([#600](https://github.com/TanStack/db/pull/600))

- Fix joins using conditions with computed values (such as `concat()`) ([#595](https://github.com/TanStack/db/pull/595))

- Fix repeated renders when markReady called when the collection was already ready. This would occur after each long poll on an Electric collection. ([#604](https://github.com/TanStack/db/pull/604))

- Updated dependencies [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a)]:
  - @tanstack/db-ivm@0.1.9

## 0.4.1

### Patch Changes

- Implement idle cleanup for collection garbage collection ([#590](https://github.com/TanStack/db/pull/590))

  Collection cleanup operations now use `requestIdleCallback()` to prevent blocking the UI thread during garbage collection. This improvement ensures better performance by scheduling cleanup during browser idle time rather than immediately when collections have no active subscribers.

  **Key improvements:**
  - Non-blocking cleanup operations that don't interfere with user interactions
  - Automatic fallback to `setTimeout` for older browsers without `requestIdleCallback` support
  - Proper callback management to prevent race conditions during cleanup rescheduling
  - Maintains full backward compatibility with existing collection lifecycle behavior

  This addresses performance concerns where collection cleanup could cause UI thread blocking during active application usage.

## 0.4.0

### Minor Changes

- Let collection.subscribeChanges return a subscription object. Move all data loading code related to optimizations into that subscription object. ([#564](https://github.com/TanStack/db/pull/564))

### Patch Changes

- optimise the live query graph execution by removing recursive calls to graph.run ([#564](https://github.com/TanStack/db/pull/564))

- Refactor the main Collection class into smaller classes to make it easier to maintain. ([#560](https://github.com/TanStack/db/pull/560))

- Updated dependencies [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58), [`89b1c41`](https://github.com/TanStack/db/commit/89b1c414937b021186cf128300d279d1cb4f51fe)]:
  - @tanstack/db-ivm@0.1.8

## 0.3.2

### Patch Changes

- Added a new events system for subscribing to status changes and other internal events. ([#555](https://github.com/TanStack/db/pull/555))

## 0.3.1

### Patch Changes

- Fix `stateWhenReady()` and `toArrayWhenReady()` methods to consistently wait for collections to be ready by using `preload()` internally. This ensures the collection starts loading if needed rather than just waiting passively. ([#565](https://github.com/TanStack/db/pull/565))

## 0.3.0

### Minor Changes

- Fix transaction error handling to match documented behavior and preserve error identity ([#558](https://github.com/TanStack/db/pull/558))

  ### Breaking Changes
  - `commit()` now throws errors when the mutation function fails (previously returned a failed transaction)

  ### Bug Fixes
  1. **Fixed commit() not throwing errors** - The `commit()` method now properly throws errors when the mutation function fails, matching the documented behavior. Both `await tx.commit()` and `await tx.isPersisted.promise` now work correctly in try/catch blocks.

  ### Migration Guide

  If you were catching errors from `commit()` by checking the transaction state:

  ```js
  // Before - commit() didn't throw
  await tx.commit()
  if (tx.state === 'failed') {
    console.error('Failed:', tx.error)
  }

  // After - commit() now throws
  try {
    await tx.commit()
  } catch (error) {
    console.error('Failed:', error)
  }
  ```

### Patch Changes

- Improve mutation merging from crude replacement to sophisticated merge logic ([#557](https://github.com/TanStack/db/pull/557))

  Previously, mutations were simply replaced when operating on the same item. Now mutations are intelligently merged based on their operation types (insert vs update vs delete), reducing network overhead and better preserving user intent.

## 0.2.5

### Patch Changes

- Refactor of the types of collection config factories for better type inference. ([#530](https://github.com/TanStack/db/pull/530))

- Define BaseCollectionConfig interface and let all collections extend it. ([#531](https://github.com/TanStack/db/pull/531))

- Updated dependencies [[`c58cec9`](https://github.com/TanStack/db/commit/c58cec9eb3f5fc72453793cfd6842387621a63d3)]:
  - @tanstack/db-ivm@0.1.7

## 0.2.4

### Patch Changes

- optimise key loading into query graph ([#526](https://github.com/TanStack/db/pull/526))

- Fix a bug where selecting a prop that used a built in object such as a Date would result in incorrect types in the result object. ([#524](https://github.com/TanStack/db/pull/524))

- Updated dependencies [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256)]:
  - @tanstack/db-ivm@0.1.6

## 0.2.3

### Patch Changes

- Fixed a bug where a live query could get stuck in "loading" state, or show incomplete data, when an electric "must-refetch" message arrived before the first "up-to-date". ([#532](https://github.com/TanStack/db/pull/532))

- Updated dependencies [[`a9878ad`](https://github.com/TanStack/db/commit/a9878ad58b71c3a2d10c03d75179a793bccf4ffc)]:
  - @tanstack/db-ivm@0.1.5

## 0.2.2

### Patch Changes

- fix a bug where a live query with a custom getKey would not update correctly because the source key was being used instead of the custom key for presence checks. ([#521](https://github.com/TanStack/db/pull/521))

- Updated dependencies [[`c11eb51`](https://github.com/TanStack/db/commit/c11eb51fe24bb1c4c8529bcd34467af4e6542c71)]:
  - @tanstack/db-ivm@0.1.4

## 0.2.1

### Patch Changes

- export the new `isUndefined` and `isNull` query builder functions ([#515](https://github.com/TanStack/db/pull/515))

## 0.2.0

### Minor Changes

- ## Enhanced Ref System with Nested Optional Properties ([#386](https://github.com/TanStack/db/pull/386))

  Comprehensive refactor of the ref system to properly support nested structures and optionality, aligning the type system with JavaScript's optional chaining behavior.

  ### ✨ New Features
  - **Nested Optional Properties**: Full support for deeply nested optional objects (`employees.profile?.bio`, `orders.customer?.address?.street`)
  - **Enhanced Type Safety**: Optional types now correctly typed as `RefProxy<T> | undefined` with optionality outside the ref
  - **New Query Functions**: Added `isUndefined`, `isNull` for proper null/undefined checks
  - **Improved JOIN Handling**: Fixed optionality in JOIN operations and multiple GROUP BY support

  ### ⚠️ Breaking Changes

  **IMPORTANT**: Code that previously ignored optionality now requires proper optional chaining syntax.

  ```typescript
  // Before (worked but type-unsafe)
  employees.profile.bio // ❌ Now throws type error

  // After (correct and type-safe)
  employees.profile?.bio // ✅ Required syntax
  ```

  ### Migration

  Add `?.` when accessing potentially undefined nested properties

### Patch Changes

- fix count aggregate function (evaluate only not null field values like SQL count) ([#453](https://github.com/TanStack/db/pull/453))

- fix a bug where distinct was not applied to queries using a join ([#510](https://github.com/TanStack/db/pull/510))

- Fix bug where too much data would be loaded when the lazy collection of a join contains an offset and/or limit clause. ([#508](https://github.com/TanStack/db/pull/508))

- Refactored `select` improving spread (`...obj`) support and enabling nested projection. ([#389](https://github.com/TanStack/db/pull/389))

- fix a bug that prevented chaining joins (joining collectionB to collectionA, then collectionC to collectionB) within one query without using a subquery ([#511](https://github.com/TanStack/db/pull/511))

- Updated dependencies [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6), [`0f6fb37`](https://github.com/TanStack/db/commit/0f6fb373d56177282552be5fb61e5bb32aeb09bb), [`0be4e2c`](https://github.com/TanStack/db/commit/0be4e2cf2b57a5e204f43c04457ddacc3532bd08)]:
  - @tanstack/db-ivm@0.1.3

## 0.1.12

### Patch Changes

- Fixes a bug where optimized joins would miss data ([#501](https://github.com/TanStack/db/pull/501))

## 0.1.11

### Patch Changes

- fix: improve InvalidSourceError message clarity ([#488](https://github.com/TanStack/db/pull/488))

  The InvalidSourceError now provides a clear, actionable error message that:
  - Explicitly states the problem is passing a non-Collection/non-subquery to a live query
  - Includes the alias name to help identify which source is problematic
  - Provides guidance on what should be passed instead (Collection instances or QueryBuilder subqueries)

  This replaces the generic "Invalid source" message with helpful debugging information.

## 0.1.10

### Patch Changes

- Fixed an optimization bug where orderBy clauses using a single-column array were not recognized as optimizable. Queries that order by a single column are now correctly optimized even when specified as an array. ([#477](https://github.com/TanStack/db/pull/477))

- fix an bug where a live query that used joins could become stuck empty when its remounted/resubscribed ([#484](https://github.com/TanStack/db/pull/484))

- fixed a bug where a pending sync transaction could be applied early when an optimistic mutation was resolved or rolled back ([#482](https://github.com/TanStack/db/pull/482))

- Add support for queries to order results based on aggregated values ([#481](https://github.com/TanStack/db/pull/481))

## 0.1.9

### Patch Changes

- Fix handling of Temporal objects in proxy's deepClone and deepEqual functions ([#434](https://github.com/TanStack/db/pull/434))
  - Temporal objects (like Temporal.ZonedDateTime) are now properly preserved during cloning instead of being converted to empty objects
  - Added detection for all Temporal API object types via Symbol.toStringTag
  - Temporal objects are returned directly from deepClone since they're immutable
  - Added proper equality checking for Temporal objects using their built-in equals() method
  - Prevents unnecessary proxy creation for immutable Temporal objects

## 0.1.8

### Patch Changes

- Fix bug that caused initial query results to have too few rows when query has orderBy, limit, and where clauses. ([#461](https://github.com/TanStack/db/pull/461))

- fix disabling of gc by setting `gcTime: 0` on the collection options ([#463](https://github.com/TanStack/db/pull/463))

- docs: electric-collection reference page ([#429](https://github.com/TanStack/db/pull/429))

## 0.1.7

### Patch Changes

- fix a race condition that could result in the initial state of a joined collection being sent to the live query pipeline twice, this would result in incorrect join results. ([#451](https://github.com/TanStack/db/pull/451))

- Refactor live query collection ([#432](https://github.com/TanStack/db/pull/432))

- Fix infinite loop bug with queries that use orderBy clause with a limit ([#450](https://github.com/TanStack/db/pull/450))

- mark item drafts as a `mutable` type ([#408](https://github.com/TanStack/db/pull/408))

- Fix query optimizer to preserve outer join semantics by keeping residual WHERE clauses when pushing predicates to subqueries. ([#442](https://github.com/TanStack/db/pull/442))

## 0.1.6

### Patch Changes

- fix for a performance regression when syncing large collections due to a look up of previously deleted keys ([#430](https://github.com/TanStack/db/pull/430))

## 0.1.5

### Patch Changes

- Ensure that a new d2 graph is used for live queries that are cleaned up by the gc process. Fixes the "Graph already finalized" error. ([#419](https://github.com/TanStack/db/pull/419))

## 0.1.4

### Patch Changes

- Ensure that the ready status is correctly returned from a live query ([#390](https://github.com/TanStack/db/pull/390))

- Optimize order by to lazily load ordered data if a range index is available on the field that is being ordered on. ([#410](https://github.com/TanStack/db/pull/410))

- Add a new truncate method to the sync handler to enable a collections state to be reset from a sync transaction. ([#412](https://github.com/TanStack/db/pull/412))

- Ensure LiveQueryCollections are properly transitioning to ready state when source collections are preloaded after creation of the live query collection ([#395](https://github.com/TanStack/db/pull/395))

- Optimize joins to use index on the join key when available. ([#335](https://github.com/TanStack/db/pull/335))

- Updated dependencies [[`6c1c19c`](https://github.com/TanStack/db/commit/6c1c19cedbc1d9d98396948e8e43fa0515bb8919), [`68538b4`](https://github.com/TanStack/db/commit/68538b4c446abeb992e24964f811c8900749f141)]:
  - @tanstack/db-ivm@0.1.2

## 0.1.3

### Patch Changes

- Fix bug with orderBy that resulted in query results having less rows than the configured limit. ([#405](https://github.com/TanStack/db/pull/405))

- Updated dependencies [[`0cb7699`](https://github.com/TanStack/db/commit/0cb76999e5d6df5916694a5afeb31b928eab68e4)]:
  - @tanstack/db-ivm@0.1.1

## 0.1.2

### Patch Changes

- Ensure that you can use optional properties in the `select` and `join` clauses of a query, and fix an issue where standard schemas were not properly carried through to live queries. ([#377](https://github.com/TanStack/db/pull/377))

- Add option to configure how orderBy compares values. This includes ascending/descending order, ordering of null values, and lexical vs locale comparison for strings. ([#314](https://github.com/TanStack/db/pull/314))

## 0.1.1

### Patch Changes

- Cleanup transactions after they complete to prevent memory leak and performance degradation ([#371](https://github.com/TanStack/db/pull/371))

- Fix the types on `localOnlyCollectionOptions` and `localStorageCollectionOptions` so that they correctly infer the types from a passed in schema ([#372](https://github.com/TanStack/db/pull/372))

## 0.1.0

### Minor Changes

- 0.1 release - first beta 🎉 ([#332](https://github.com/TanStack/db/pull/332))

### Patch Changes

- We have moved development of the differential dataflow implementation from @electric-sql/d2mini to a new @tanstack/db-ivm package inside the tanstack db monorepo to make development simpler. ([#330](https://github.com/TanStack/db/pull/330))

- Updated dependencies [[`7d2f4be`](https://github.com/TanStack/db/commit/7d2f4be95c43aad29fb61e80e5a04c58c859322b), [`f0eda36`](https://github.com/TanStack/db/commit/f0eda36cb36350399bc8835686a6c4b6ad297e45)]:
  - @tanstack/db-ivm@0.1.0

## 0.0.33

### Patch Changes

- bump d2mini to latest which has a significant speedup ([#321](https://github.com/TanStack/db/pull/321))

## 0.0.32

### Patch Changes

- Fix LiveQueryCollection hanging when source collections have no data ([#309](https://github.com/TanStack/db/pull/309))

  Fixed an issue where `LiveQueryCollection.preload()` would hang indefinitely when source collections call `markReady()` without data changes (e.g., when queryFn returns empty array).

  The fix implements a proper event-based solution:
  - Collections now emit empty change events when becoming ready with no data
  - WHERE clause filtered subscriptions now correctly pass through empty ready signals
  - Both regular and WHERE clause optimized LiveQueryCollections now work correctly with empty source collections

## 0.0.31

### Patch Changes

- Fix UI responsiveness issue with rapid user interactions in collections ([#308](https://github.com/TanStack/db/pull/308))

  Fixed a critical issue where rapid user interactions (like clicking multiple checkboxes quickly) would cause the UI to become unresponsive when using collections with slow backend responses. The problem occurred when optimistic updates would back up and the UI would stop reflecting user actions.

  **Root Causes:**
  - Event filtering logic was blocking ALL events for keys with recent sync operations, including user-initiated actions
  - Event batching was queuing user actions instead of immediately updating the UI during high-frequency operations

  **Solution:**
  - Added `triggeredByUserAction` parameter to `recomputeOptimisticState()` to distinguish user actions from sync operations
  - Modified event filtering to allow user-initiated actions to bypass sync status checks
  - Enhanced `emitEvents()` with `forceEmit` parameter to skip batching for immediate user action feedback
  - Updated all user action code paths to properly identify themselves as user-triggered

  This ensures the UI remains responsive during rapid user interactions while maintaining the performance benefits of event batching and duplicate event filtering for sync operations.

## 0.0.30

### Patch Changes

- Remove OrderedIndex in favor of more efficient BTree index. ([#302](https://github.com/TanStack/db/pull/302))

## 0.0.29

### Patch Changes

- Automatically restart collections from cleaned-up state when operations are called ([#285](https://github.com/TanStack/db/pull/285))

  Collections in a `cleaned-up` state now automatically restart when operations like `insert()`, `update()`, or `delete()` are called on them. This matches the behavior of other collection access patterns and provides a better developer experience by avoiding unnecessary errors.

- Add collection index system for optimized queries and subscriptions ([#257](https://github.com/TanStack/db/pull/257))

  This release introduces a comprehensive index system for collections that enables fast lookups and query optimization:

- Enabled live queries to use the collection indexes ([#258](https://github.com/TanStack/db/pull/258))

  Live queries now use the collection indexes for many queries, using the optimized query pipeline to push where clauses to the collection, which is then able to use the index to filter the data.

- Added an auto-indexing system that creates indexes on collection eagerly when querying, this is a performance optimization that can be disabled by setting the autoIndex option to `off`. ([#292](https://github.com/TanStack/db/pull/292))

- feat: Replace string-based errors with named error classes for better error handling ([#297](https://github.com/TanStack/db/pull/297))

  This comprehensive update replaces all string-based error throws throughout the TanStack DB codebase with named error classes, providing better type safety and developer experience.

  ## New Features
  - **Root `TanStackDBError` class** - all errors inherit from a common base for unified error handling
  - **Named error classes** organized by package and functional area
  - **Type-safe error handling** using `instanceof` checks instead of string matching
  - **Package-specific error definitions** - each adapter has its own error classes
  - **Better IDE support** with autocomplete for error types

  ## Package Structure

  ### Core Package (`@tanstack/db`)

  Contains generic errors used across the ecosystem:
  - Collection configuration, state, and operation errors
  - Transaction lifecycle and mutation errors
  - Query building, compilation, and execution errors
  - Storage and serialization errors

  ### Adapter Packages

  Each adapter now exports its own specific error classes:
  - **`@tanstack/electric-db-collection`**: Electric-specific errors
  - **`@tanstack/trailbase-db-collection`**: TrailBase-specific errors
  - **`@tanstack/query-db-collection`**: Query collection specific errors

  ## Breaking Changes
  - Error handling code using string matching will need to be updated to use `instanceof` checks
  - Some error messages may have slight formatting changes
  - Adapter-specific errors now need to be imported from their respective packages

  ## Migration Guide

  ### Core DB Errors

  **Before:**

  ```ts
  try {
    collection.insert(data)
  } catch (error) {
    if (error.message.includes('already exists')) {
      // Handle duplicate key error
    }
  }
  ```

  **After:**

  ```ts
  import { DuplicateKeyError } from '@tanstack/db'

  try {
    collection.insert(data)
  } catch (error) {
    if (error instanceof DuplicateKeyError) {
      // Type-safe error handling
    }
  }
  ```

  ### Adapter-Specific Errors

  **Before:**

  ```ts
  // Electric collection errors were imported from @tanstack/db
  import { ElectricInsertHandlerMustReturnTxIdError } from '@tanstack/db'
  ```

  **After:**

  ```ts
  // Now import from the specific adapter package
  import { ElectricInsertHandlerMustReturnTxIdError } from '@tanstack/electric-db-collection'
  ```

  ### Unified Error Handling

  **New:**

  ```ts
  import { TanStackDBError } from '@tanstack/db'

  try {
    // Any TanStack DB operation
  } catch (error) {
    if (error instanceof TanStackDBError) {
      // Handle all TanStack DB errors uniformly
      console.log('TanStack DB error:', error.message)
    }
  }
  ```

  ## Benefits
  - **Type Safety**: All errors now have specific types that can be caught with `instanceof`
  - **Unified Error Handling**: Root `TanStackDBError` class allows catching all library errors with a single check
  - **Better Package Separation**: Each adapter manages its own error types
  - **Developer Experience**: Better IDE support with autocomplete for error types
  - **Maintainability**: Error definitions are co-located with their usage
  - **Consistency**: Uniform error handling patterns across the entire codebase

  All error classes maintain the same error messages and behavior while providing better structure and package separation.

## 0.0.28

### Patch Changes

- fixed an issue with joins where a specific order of references in the `eq()` expression was required, and added additional validation ([#291](https://github.com/TanStack/db/pull/291))

- Add comprehensive documentation for creating collection options creators ([#284](https://github.com/TanStack/db/pull/284))

  This adds a new documentation page `collection-options-creator.md` that provides detailed guidance for developers building collection options creators. The documentation covers:
  - Core requirements and configuration interfaces
  - Sync implementation patterns with transaction lifecycle (begin, write, commit, markReady)
  - Data parsing and type conversion using field-specific conversions
  - Two distinct mutation handler patterns:
    - Pattern A: User-provided handlers (ElectricSQL, Query style)
    - Pattern B: Built-in handlers (Trailbase, WebSocket style)
  - Complete WebSocket collection example with full round-trip flow
  - Managing optimistic state with various strategies (transaction IDs, ID-based tracking, refetch, timestamps)
  - Best practices for deduplication, error handling, and testing
  - Row update modes and advanced configuration options

  The documentation helps developers understand when to create custom collections versus using the query collection, and provides practical examples following the established patterns from existing collection implementations.

## 0.0.27

### Patch Changes

- fix arktype schemas for collections ([#279](https://github.com/TanStack/db/pull/279))

## 0.0.26

### Patch Changes

- Add initial release of TrailBase collection for TanStack DB. TrailBase is a blazingly fast, open-source alternative to Firebase built on Rust, SQLite, and V8. It provides type-safe REST and realtime APIs with sub-millisecond latencies, integrated authentication, and flexible access control - all in a single executable. This collection type enables seamless integration with TrailBase backends for high-performance real-time applications. ([#228](https://github.com/TanStack/db/pull/228))

## 0.0.25

### Patch Changes

- Fix iterator-based change tracking in proxy system ([#271](https://github.com/TanStack/db/pull/271))

  This fixes several issues with iterator-based change tracking for Maps and Sets:
  - **Map.entries()** now correctly updates actual Map entries instead of creating duplicate keys
  - **Map.values()** now tracks back to original Map keys using value-to-key mapping instead of using symbol placeholders
  - **Set iterators** now properly replace objects in Set when modified instead of creating symbol-keyed entries
  - **forEach()** methods continue to work correctly

  The implementation now uses a sophisticated parent-child tracking system with specialized `updateMap` and `updateSet` functions to ensure that changes made to objects accessed through iterators are properly attributed to the correct collection entries.

  This brings the proxy system in line with how mature libraries like Immer handle iterator-based change tracking, using method interception rather than trying to proxy all property access.

- Add explicit collection readiness detection with `isReady()` and `markReady()` ([#270](https://github.com/TanStack/db/pull/270))
  - Add `isReady()` method to check if a collection is ready for use
  - Add `onFirstReady()` method to register callbacks for when collection becomes ready
  - Add `markReady()` to SyncConfig interface for sync implementations to explicitly signal readiness
  - Replace `onFirstCommit()` with `onFirstReady()` for better semantics
  - Update status state machine to allow `loading` → `ready` transition for cases with no data to commit
  - Update all sync implementations (Electric, Query, Local-only, Local-storage) to use `markReady()`
  - Improve error handling by allowing collections to be marked ready even when sync errors occur

  This provides a more intuitive and ergonomic API for determining collection readiness, replacing the previous approach of using commits as a readiness signal.

## 0.0.24

### Patch Changes

- Add query optimizer with predicate pushdown ([#256](https://github.com/TanStack/db/pull/256))

  Implements automatic query optimization that moves WHERE clauses closer to data sources, reducing intermediate result sizes and improving performance for queries with joins.

- Add `leftJoin`, `rightJoin`, `innerJoin` and `fullJoin` aliases of the main `join` method on the query builder. ([#269](https://github.com/TanStack/db/pull/269))

- • Add proper tracking for array mutating methods (push, pop, shift, unshift, splice, sort, reverse, fill, copyWithin) ([#267](https://github.com/TanStack/db/pull/267))
  • Fix existing array tests that were misleadingly named but didn't actually call the methods they claimed to test
  • Add comprehensive test coverage for all supported array mutating methods

## 0.0.23

### Patch Changes

- Ensure schemas can apply defaults when inserting ([#209](https://github.com/TanStack/db/pull/209))

## 0.0.22

### Patch Changes

- New distinct operator for queries. ([#244](https://github.com/TanStack/db/pull/244))

## 0.0.21

### Patch Changes

- Move Collections to their own packages ([#252](https://github.com/TanStack/db/pull/252))
  - Move local-only and local-storage collections to main `@tanstack/db` package
  - Create new `@tanstack/electric-db-collection` package for ElectricSQL integration
  - Create new `@tanstack/query-db-collection` package for TanStack Query integration
  - Delete `@tanstack/db-collections` package (removed from repo)
  - Update example app and documentation to use new package structure

  Why?
  - Better separation of concerns
  - Independent versioning for each collection type
  - Cleaner dependencies (electric collections don't need query deps, etc.)
  - Easier to add more collection types moving forward

## 0.0.20

### Patch Changes

- Add non-optimistic mutations support ([#250](https://github.com/TanStack/db/pull/250))
  - Add `optimistic` option to insert, update, and delete operations
  - Default `optimistic: true` maintains backward compatibility
  - When `optimistic: false`, mutations only apply after server confirmation
  - Enables better control for server-validated operations and confirmation workflows

## 0.0.19

### Patch Changes

- - [Breaking change for the Electric Collection]: Use numbers for txid ([#245](https://github.com/TanStack/db/pull/245))
  - misc type fixes

## 0.0.18

### Patch Changes

- Improve jsdocs ([#243](https://github.com/TanStack/db/pull/243))

## 0.0.17

### Patch Changes

- Upgrade d2mini to 0.1.6 ([#239](https://github.com/TanStack/db/pull/239))

## 0.0.16

### Patch Changes

- add support for composable queries ([#232](https://github.com/TanStack/db/pull/232))

## 0.0.15

### Patch Changes

- add a sequence number to transactions to when sorting we can ensure that those created in the same ms are sorted in the correct order ([#230](https://github.com/TanStack/db/pull/230))

- Ensure that all transactions are given an id, fixes a potential bug with direct mutations ([#230](https://github.com/TanStack/db/pull/230))

## 0.0.14

### Patch Changes

- fixed the types on the onInsert/Update/Delete transactions ([#218](https://github.com/TanStack/db/pull/218))

## 0.0.13

### Patch Changes

- feat: implement Collection Lifecycle Management ([#198](https://github.com/TanStack/db/pull/198))

  Adds automatic lifecycle management for collections to optimize resource usage.

  **New Features:**
  - Added `startSync` option (defaults to `false`, set to `true` to start syncing immediately)
  - Automatic garbage collection after `gcTime` (default 5 minutes) of inactivity
  - Collection status tracking: "idle" | "loading" | "ready" | "error" | "cleaned-up"
  - Manual `preload()` and `cleanup()` methods for lifecycle control

  **Usage:**

  ```typescript
  const collection = createCollection({
    startSync: false, // Enable lazy loading
    gcTime: 300000, // Cleanup timeout (default: 5 minutes)
  })

  console.log(collection.status) // Current state
  await collection.preload() // Ensure ready
  await collection.cleanup() // Manual cleanup
  ```

- Refactored the way we compute change events over the synced state and the optimistic changes. This fixes a couple of issues where the change events were not being emitted correctly. ([#206](https://github.com/TanStack/db/pull/206))

- Add createOptimisticAction helper that replaces useOptimisticMutation ([#210](https://github.com/TanStack/db/pull/210))

  An example of converting a `useOptimisticMutation` hook to `createOptimisticAction`. Now all optimistic & server mutation logic are consolidated.

  ```diff
  -import { useOptimisticMutation } from '@tanstack/react-db'
  +import { createOptimisticAction } from '@tanstack/react-db'
  +
  +// Create the `addTodo` action, passing in your `mutationFn` and `onMutate`.
  +const addTodo = createOptimisticAction<string>({
  +  onMutate: (text) => {
  +    // Instantly applies the local optimistic state.
  +    todoCollection.insert({
  +      id: uuid(),
  +      text,
  +      completed: false
  +    })
  +  },
  +  mutationFn: async (text) => {
  +    // Persist the todo to your backend
  +    const response = await fetch('/api/todos', {
  +      method: 'POST',
  +      body: JSON.stringify({ text, completed: false }),
  +    })
  +    return response.json()
  +  }
  +})

   const Todo = () => {
  -  // Create the `addTodo` mutator, passing in your `mutationFn`.
  -  const addTodo = useOptimisticMutation({ mutationFn })
  -
     const handleClick = () => {
  -    // Triggers the mutationFn
  -    addTodo.mutate(() =>
  -      // Instantly applies the local optimistic state.
  -      todoCollection.insert({
  -        id: uuid(),
  -        text: '🔥 Make app faster',
  -        completed: false
  -      })
  -    )
  +    // Triggers the onMutate and then the mutationFn
  +    addTodo('🔥 Make app faster')
     }

     return <Button onClick={ handleClick } />
   }
  ```

## 0.0.12

### Patch Changes

- If a schema is passed, use that for the collection type. ([#186](https://github.com/TanStack/db/pull/186))

  You now must either pass an explicit type or schema - passing both will conflict.

## 0.0.11

### Patch Changes

- change the query engine to use d2mini, and simplified version of the d2ts differential dataflow library ([#175](https://github.com/TanStack/db/pull/175))

- Export `ElectricCollectionUtils` & allow passing generic to `createTransaction` ([#179](https://github.com/TanStack/db/pull/179))

## 0.0.10

### Patch Changes

- If collection.update is called and nothing is changed, return a transaction instead of throwing ([#174](https://github.com/TanStack/db/pull/174))

## 0.0.9

### Patch Changes

- Allow arrays in type of RHS in where clause when using set membership operators ([#149](https://github.com/TanStack/db/pull/149))

## 0.0.8

### Patch Changes

- Type PendingMutation whenever possible ([#163](https://github.com/TanStack/db/pull/163))

- refactor the live query comparator and fix an issue with sorting with a null/undefined value in a column of non-null values ([#167](https://github.com/TanStack/db/pull/167))

- A large refactor of the core `Collection` with: ([#155](https://github.com/TanStack/db/pull/155))
  - a change to not use Store internally and emit fine grade changes with `subscribeChanges` and `subscribeKeyChanges` methods.
  - changes to the `Collection` api to be more `Map` like for reads, with `get`, `has`, `size`, `entries`, `keys`, and `values`.
  - renames `config.getId` to `config.getKey` for consistency with the `Map` like api.

- Fix ordering of ts update overloads & fix a lot of type errors in tests ([#166](https://github.com/TanStack/db/pull/166))

- fix string comparison when sorting in descending order ([#165](https://github.com/TanStack/db/pull/165))

- update to the latest d2ts, this brings improvements to the hashing of changes in the d2 pipeline ([#168](https://github.com/TanStack/db/pull/168))

## 0.0.7

### Patch Changes

- Expose utilities on collection instances ([#161](https://github.com/TanStack/db/pull/161))

  Implemented a utility exposure pattern for TanStack DB collections that allows utility functions to be passed as part of collection options and exposes them under a `.utils` namespace, with full TypeScript typing.
  - Refactored `createCollection` in packages/db/src/collection.ts to accept options with utilities directly
  - Added `utils` property to CollectionImpl
  - Added TypeScript types for utility functions and utility records
  - Changed Collection from a class to a type, updating all usages to use createCollection() instead
  - Updated Electric/Query implementations
  - Utilities are now ergonomically accessible under `.utils`
  - Full TypeScript typing is preserved for both collection data and utilities
  - API is clean and straightforward - users can call `createCollection(optionsCreator(config))` directly
  - Zero-boilerplate TypeScript pattern that infers utility types automatically

## 0.0.6

### Patch Changes

- live query where clauses can now be a callback function that receives each row as a context object allowing full javascript access to the row data for filtering ([#152](https://github.com/TanStack/db/pull/152))

- the live query select clause can now be a callback function that receives each row as a context object returning a new object with the selected fields. This also allows the for the callback to make more expressive changes to the returned data. ([#154](https://github.com/TanStack/db/pull/154))

- This change introduces a more streamlined and intuitive API for handling mutations by allowing `onInsert`, `onUpdate`, and `onDelete` handlers to be defined directly on the collection configuration. ([#156](https://github.com/TanStack/db/pull/156))

  When `collection.insert()`, `.update()`, or `.delete()` are called outside of an explicit transaction (i.e., not within `useOptimisticMutation`), the library now automatically creates a single-operation transaction and invokes the corresponding handler to persist the change.

  Key changes:
  - **`@tanstack/db`**: The `Collection` class now supports `onInsert`, `onUpdate`, and `onDelete` in its configuration. Direct calls to mutation methods will throw an error if the corresponding handler is not defined.
  - **`@tanstack/db-collections`**:
    - `queryCollectionOptions` now accepts the new handlers and will automatically `refetch` the collection's query after a handler successfully completes. This behavior can be disabled if the handler returns `{ refetch: false }`.
    - `electricCollectionOptions` also accepts the new handlers. These handlers are now required to return an object with a transaction ID (`{ txid: string }`). The collection then automatically waits for this `txid` to be synced back before resolving the mutation, ensuring consistency.
  - **Breaking Change**: Calling `collection.insert()`, `.update()`, or `.delete()` without being inside a `useOptimisticMutation` callback and without a corresponding persistence handler (`onInsert`, etc.) configured on the collection will now throw an error.

  This new pattern simplifies the most common use cases, making the code more declarative. The `useOptimisticMutation` hook remains available for more complex scenarios, such as transactions involving multiple mutations across different collections.

  ***

  The documentation and the React Todo example application have been significantly refactored to adopt the new direct persistence handler pattern as the primary way to perform mutations.
  - The `README.md` and `docs/overview.md` files have been updated to de-emphasize `useOptimisticMutation` for simple writes. They now showcase the much simpler API of calling `collection.insert()` directly and defining persistence logic in the collection's configuration.
  - The React Todo example (`examples/react/todo/src/App.tsx`) has been completely overhauled. All instances of `useOptimisticMutation` have been removed and replaced with the new `onInsert`, `onUpdate`, and `onDelete` handlers, resulting in cleaner and more concise code.

## 0.0.5

### Patch Changes

- Collections must have a getId function & use an id for update/delete operators ([#134](https://github.com/TanStack/db/pull/134))

- the select operator is not optional on a query, it will default to returning the whole row for a basic query, and a namespaced object when there are joins ([#148](https://github.com/TanStack/db/pull/148))

- the `keyBy` query operator has been removed, keying withing the query pipeline is now automatic ([#144](https://github.com/TanStack/db/pull/144))

- update d2ts to to latest version that improves hashing performance ([#136](https://github.com/TanStack/db/pull/136))

- Switch to Collection options factories instead of extending the Collection class ([#145](https://github.com/TanStack/db/pull/145))

  This refactors `ElectricCollection` and `QueryCollection` into factory functions (`electricCollectionOptions` and `queryCollectionOptions`) that return standard `CollectionConfig` objects and utility functions. Also adds a `createCollection` function to standardize collection instantiation.

## 0.0.4

### Patch Changes

- fix a bug where optimistic operations could be applied to the wrong collection ([#113](https://github.com/TanStack/db/pull/113))

## 0.0.3

### Patch Changes

- fix a bug where query results would not correctly update ([#87](https://github.com/TanStack/db/pull/87))

## 0.0.2

### Patch Changes

- Fixed an issue with injecting the optimistic state removal into the reactive live query. ([#78](https://github.com/TanStack/db/pull/78))

## 0.0.3

### Patch Changes

- Make transactions first class & move ownership of mutationFn from collections to transactions ([#53](https://github.com/TanStack/db/pull/53))

## 0.0.2

### Patch Changes

- make mutationFn optional for read-only collections ([#12](https://github.com/TanStack/db/pull/12))

- Improve test coverage ([#10](https://github.com/TanStack/db/pull/10))

## 0.0.1

### Patch Changes

- feat: Initial release ([#2](https://github.com/TanStack/db/pull/2))


## Links discovered
- [#960](https://github.com/TanStack/db/pull/960)
- [#958](https://github.com/TanStack/db/pull/958)
- [#926](https://github.com/TanStack/db/pull/926)
- [[`52c29fa`](https://github.com/TanStack/db/commit/52c29fa83b390ac26341dbf93e79ce0d59543686)
- [#954](https://github.com/TanStack/db/pull/954)
- [#967](https://github.com/TanStack/db/pull/967)
- [#940](https://github.com/TanStack/db/pull/940)
- [#933](https://github.com/TanStack/db/pull/933)
- [#929](https://github.com/TanStack/db/pull/929)
- [#913](https://github.com/TanStack/db/pull/913)
- [#914](https://github.com/TanStack/db/pull/914)
- [#910](https://github.com/TanStack/db/pull/910)
- [#898](https://github.com/TanStack/db/pull/898)
- [#870](https://github.com/TanStack/db/pull/870)
- [#852](https://github.com/TanStack/db/pull/852)
- [#875](https://github.com/TanStack/db/pull/875)
- [#880](https://github.com/TanStack/db/pull/880)
- [#871](https://github.com/TanStack/db/pull/871)
- [#851](https://github.com/TanStack/db/pull/851)
- [#854](https://github.com/TanStack/db/pull/854)
- [#845](https://github.com/TanStack/db/pull/845)
- [#840](https://github.com/TanStack/db/pull/840)
- [#765](https://github.com/TanStack/db/pull/765)
- [#763](https://github.com/TanStack/db/pull/763)
- [#779](https://github.com/TanStack/db/pull/779)
- [[`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [#749](https://github.com/TanStack/db/pull/749)
- [#717](https://github.com/TanStack/db/pull/717)
- [#742](https://github.com/TanStack/db/pull/742)
- [#760](https://github.com/TanStack/db/pull/760)
- [#713](https://github.com/TanStack/db/pull/713)
- [#719](https://github.com/TanStack/db/pull/719)
- [#559](https://github.com/TanStack/db/pull/559)
- [#728](https://github.com/TanStack/db/pull/728)
- [#732](https://github.com/TanStack/db/pull/732)
- [#704](https://github.com/TanStack/db/pull/704)
- [TanStack Pacer](https://github.com/TanStack/pacer)
- [#730](https://github.com/TanStack/db/pull/730)
- [#714](https://github.com/TanStack/db/pull/714)
- [#715](https://github.com/TanStack/db/pull/715)
- [#696](https://github.com/TanStack/db/pull/696)
- [#701](https://github.com/TanStack/db/pull/701)
- [[`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)
- [#684](https://github.com/TanStack/db/pull/684)
- [#663](https://github.com/TanStack/db/pull/663)
- [#669](https://github.com/TanStack/db/pull/669)
- [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a)
- [#625](https://github.com/TanStack/db/pull/625)
- [#654](https://github.com/TanStack/db/pull/654)
- [#628](https://github.com/TanStack/db/pull/628)
- [[`eeb05d4`](https://github.com/TanStack/db/commit/eeb05d449defbaaac584f4bb8febcb8946cfdf21)
- [#659](https://github.com/TanStack/db/pull/659)
- [#658](https://github.com/TanStack/db/pull/658)
- [#638](https://github.com/TanStack/db/pull/638)
- [#617](https://github.com/TanStack/db/pull/617)
- [#655](https://github.com/TanStack/db/pull/655)
- [#650](https://github.com/TanStack/db/pull/650)
- [#631](https://github.com/TanStack/db/pull/631)
- [#637](https://github.com/TanStack/db/pull/637)
- [#627](https://github.com/TanStack/db/pull/627)
- [#621](https://github.com/TanStack/db/pull/621)
- [#623](https://github.com/TanStack/db/pull/623)
- [#605](https://github.com/TanStack/db/pull/605)
- [#428](https://github.com/TanStack/db/pull/428)
- [#600](https://github.com/TanStack/db/pull/600)
- [#595](https://github.com/TanStack/db/pull/595)
- [#604](https://github.com/TanStack/db/pull/604)
- [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a)
- [#590](https://github.com/TanStack/db/pull/590)
- [#564](https://github.com/TanStack/db/pull/564)
- [#560](https://github.com/TanStack/db/pull/560)
- [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [`89b1c41`](https://github.com/TanStack/db/commit/89b1c414937b021186cf128300d279d1cb4f51fe)
- [#555](https://github.com/TanStack/db/pull/555)
- [#565](https://github.com/TanStack/db/pull/565)
- [#558](https://github.com/TanStack/db/pull/558)
- [#557](https://github.com/TanStack/db/pull/557)
- [#530](https://github.com/TanStack/db/pull/530)
- [#531](https://github.com/TanStack/db/pull/531)
- [[`c58cec9`](https://github.com/TanStack/db/commit/c58cec9eb3f5fc72453793cfd6842387621a63d3)
- [#526](https://github.com/TanStack/db/pull/526)
- [#524](https://github.com/TanStack/db/pull/524)
- [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256)
- [#532](https://github.com/TanStack/db/pull/532)
- [[`a9878ad`](https://github.com/TanStack/db/commit/a9878ad58b71c3a2d10c03d75179a793bccf4ffc)
- [#521](https://github.com/TanStack/db/pull/521)
- [[`c11eb51`](https://github.com/TanStack/db/commit/c11eb51fe24bb1c4c8529bcd34467af4e6542c71)
- [#515](https://github.com/TanStack/db/pull/515)
- [#386](https://github.com/TanStack/db/pull/386)
- [#453](https://github.com/TanStack/db/pull/453)
- [#510](https://github.com/TanStack/db/pull/510)
- [#508](https://github.com/TanStack/db/pull/508)
- [#389](https://github.com/TanStack/db/pull/389)
- [#511](https://github.com/TanStack/db/pull/511)
- [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6)
- [`0f6fb37`](https://github.com/TanStack/db/commit/0f6fb373d56177282552be5fb61e5bb32aeb09bb)
- [`0be4e2c`](https://github.com/TanStack/db/commit/0be4e2cf2b57a5e204f43c04457ddacc3532bd08)
- [#501](https://github.com/TanStack/db/pull/501)
- [#488](https://github.com/TanStack/db/pull/488)

--- packages/electric-db-collection/CHANGELOG.md ---
# @tanstack/electric-db-collection

## 0.2.13

### Patch Changes

- Enhanced LoadSubsetOptions with separate cursor expressions and offset for flexible pagination. ([#960](https://github.com/TanStack/db/pull/960))

  **⚠️ Breaking Change for Custom Sync Layers / Query Collections:**

  `LoadSubsetOptions.where` no longer includes cursor expressions for pagination. If you have a custom sync layer or query collection that implements `loadSubset`, you must now handle pagination separately:
  - **Cursor-based pagination:** Use the new `cursor` property (`cursor.whereFrom` and `cursor.whereCurrent`) and combine them with `where` yourself
  - **Offset-based pagination:** Use the new `offset` property

  Previously, cursor expressions were baked into the `where` clause. Now they are passed separately so sync layers can choose their preferred pagination strategy.

  **Changes:**
  - Added `CursorExpressions` type with `whereFrom`, `whereCurrent`, and optional `lastKey` properties
  - Added `cursor` to `LoadSubsetOptions` for cursor-based pagination (separate from `where`)
  - Added `offset` to `LoadSubsetOptions` for offset-based pagination support
  - Electric sync layer now makes two parallel `requestSnapshot` calls when cursor is present:
    - One for `whereCurrent` (all ties at boundary, no limit)
    - One for `whereFrom` (rows after cursor, with limit)
  - Query collection serialization now includes `offset` for query key generation
  - Added `truncate` event to collections, emitted when synced data is truncated (e.g., after `must-refetch`)
  - Fixed `setWindow` pagination: cursor expressions are now correctly built when paging through results
  - Fixed offset tracking: `loadNextItems` now passes the correct window offset to prevent incorrect deduplication
  - `CollectionSubscriber` now listens for `truncate` events to reset cursor tracking state

  **Benefits:**
  - Sync layers can choose between cursor-based or offset-based pagination strategies
  - Electric can efficiently handle tie-breaking with two targeted requests
  - Better separation of concerns between filtering (`where`) and pagination (`cursor`/`offset`)
  - `setWindow` correctly triggers backend loading for subsequent pages in multi-column orderBy queries
  - Cursor state is properly reset after truncation, preventing stale cursor data from being used

- Updated dependencies [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0), [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435), [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)]:
  - @tanstack/db@0.5.12

## 0.2.12

### Patch Changes

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)]:
  - @tanstack/db@0.5.11

## 0.2.11

### Patch Changes

- Type utils in collection options as specific type (e.g. ElectricCollectionUtils) instead of generic UtilsRecord. ([#940](https://github.com/TanStack/db/pull/940))

- fix: Add BigInt support to pg-serializer and fix error message for non-JSON-serializable values ([#932](https://github.com/TanStack/db/pull/932))
  - Added support for serializing BigInt values to strings in the `serialize` function
  - Fixed the error message when encountering unsupported types to handle values that cannot be serialized by `JSON.stringify` (like BigInt), preventing a secondary error from masking the original issue

- Updated dependencies [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd), [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)]:
  - @tanstack/db@0.5.10

## 0.2.10

### Patch Changes

- Updated dependencies [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)]:
  - @tanstack/db@0.5.9

## 0.2.9

### Patch Changes

- Fix eager mode incorrectly committing data on `snapshot-end` before receiving the first `up-to-date` message. The `snapshot-end` in the Electric log can be from a significant period before the stream is actually up to date, so commits should only occur on `up-to-date` (or on `snapshot-end` after the first `up-to-date` has been received). This change does not affect `on-demand` mode where `snapshot-end` correctly triggers commits, or `progressive` mode which was already protected by its buffering mechanism. ([#924](https://github.com/TanStack/db/pull/924))

## 0.2.8

### Patch Changes

- Updated dependencies [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60), [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)]:
  - @tanstack/db@0.5.8

## 0.2.7

### Patch Changes

- Updated dependencies [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)]:
  - @tanstack/db@0.5.7

## 0.2.6

### Patch Changes

- Updated dependencies [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)]:
  - @tanstack/db@0.5.6

## 0.2.5

### Patch Changes

- Updated dependencies [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)]:
  - @tanstack/db@0.5.5

## 0.2.4

### Patch Changes

- Fixed bug where `like()` and `ilike()` operators were not working in on-demand mode. The SQL compiler was incorrectly treating these operators as function calls (`LIKE(column, pattern)`) instead of binary operators (`column LIKE pattern`). Now `like()` and `ilike()` correctly compile to SQL binary operator syntax, enabling search queries with pattern matching in on-demand mode. This fix supports patterns like `like(lower(offers.title), '%search%')` and combining multiple conditions with `or()`. ([#884](https://github.com/TanStack/db/pull/884))

- Fix progressive mode to use fetchSnapshot and atomic swap ([#852](https://github.com/TanStack/db/pull/852))

  Progressive mode was broken because `requestSnapshot()` injected snapshots into the stream in causally correct position, which didn't work properly with the `full` mode stream. This release fixes progressive mode by:

  **Core Changes:**
  - Use `fetchSnapshot()` during initial sync to fetch and apply snapshots immediately in sync transactions
  - Buffer all stream messages during initial sync (renamed flag to `isBufferingInitialSync`)
  - Perform atomic swap on first `up-to-date`: truncate snapshot data → apply buffered messages → mark ready
  - Track txids/snapshots only after atomic swap (enables correct optimistic transaction confirmation)

  **Test Infrastructure:**
  - Added `ELECTRIC_TEST_HOOKS` symbol for test control (hidden from public API)
  - Added `progressiveTestControl.releaseInitialSync()` to E2E test config for explicit transition control
  - Created comprehensive progressive mode E2E test suite (8 tests):
    - Explicit snapshot phase and atomic swap validation
    - Txid tracking behavior (Electric-only)
    - Multiple concurrent snapshots with deduplication
    - Incremental updates after swap
    - Predicate handling and resilience tests

  **Bug Fixes:**
  - Fixed type errors in test files
  - All 166 unit tests + 95 E2E tests passing

- Updated dependencies [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938), [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe), [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116), [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)]:
  - @tanstack/db@0.5.4

## 0.2.3

### Patch Changes

- Improve type of mutations in transactions ([#854](https://github.com/TanStack/db/pull/854))

- Updated dependencies [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9), [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)]:
  - @tanstack/db@0.5.3

## 0.2.2

### Patch Changes

- Updated dependencies [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)]:
  - @tanstack/db@0.5.2

## 0.2.1

### Patch Changes

- Updated dependencies [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)]:
  - @tanstack/db@0.5.1

## 0.2.0

### Minor Changes

- Add timeout support to electricCollectionOptions matching strategies. You can now specify a custom timeout when returning txids from mutation handlers (onInsert, onUpdate, onDelete). ([#798](https://github.com/TanStack/db/pull/798))

  Previously, users could only customize timeouts when manually calling `collection.utils.awaitTxId()`, but not when using the automatic txid matching strategy.

  **Example:**

  ```ts
  const collection = createCollection(
    electricCollectionOptions({
      // ... other config
      onInsert: async ({ transaction }) => {
        const newItem = transaction.mutations[0].modified
        const result = await api.todos.create({ data: newItem })
        // Specify custom timeout (in milliseconds)
        return { txid: result.txid, timeout: 10000 }
      },
    }),
  )
  ```

  The timeout parameter is optional and defaults to 5000ms when not specified. It works with both single txids and arrays of txids.

### Patch Changes

- Fix array txid handling in electric collection handlers. When returning `{ txid: [txid1, txid2] }` from an `onInsert`, `onUpdate`, or `onDelete` handler, the system would timeout with `TimeoutWaitingForTxIdError` instead of properly waiting for all txids. The bug was caused by passing array indices as timeout parameters when calling `awaitTxId` via `.map()`. ([#795](https://github.com/TanStack/db/pull/795))

- Handle predicates that are pushed down. ([#763](https://github.com/TanStack/db/pull/763))

- Updated dependencies [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/db@0.5.0

## 0.1.44

### Patch Changes

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20

## 0.1.43

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19

## 0.1.42

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18

## 0.1.41

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17

## 0.1.40

### Patch Changes

- Updated dependencies [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110), [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b), [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)]:
  - @tanstack/db@0.4.16

## 0.1.39

### Patch Changes

- Updated dependencies [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)]:
  - @tanstack/db@0.4.15

## 0.1.38

### Patch Changes

- Updated dependencies [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)]:
  - @tanstack/db@0.4.14

## 0.1.37

### Patch Changes

- Updated dependencies [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)]:
  - @tanstack/db@0.4.13

## 0.1.36

### Patch Changes

- Updated dependencies [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477), [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)]:
  - @tanstack/db@0.4.12

## 0.1.35

### Patch Changes

- Updated dependencies [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)]:
  - @tanstack/db@0.4.11

## 0.1.34

### Patch Changes

- Updated dependencies [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a), [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)]:
  - @tanstack/db@0.4.10

## 0.1.33

### Patch Changes

- Updated dependencies [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47), [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13), [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)]:
  - @tanstack/db@0.4.9

## 0.1.32

### Patch Changes

- Updated dependencies [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450), [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)]:
  - @tanstack/db@0.4.8

## 0.1.31

### Patch Changes

- feat: Add awaitMatch utility and reduce default timeout (#402) ([#499](https://github.com/TanStack/db/pull/499))

  Adds a new `awaitMatch` utility function to support custom synchronization matching logic when transaction IDs (txids) are not available. Also reduces the default timeout for `awaitTxId` from 30 seconds to 5 seconds for faster feedback.

  **New Features:**
  - New utility method: `collection.utils.awaitMatch(matchFn, timeout?)` - Wait for custom match logic
  - Export `isChangeMessage` and `isControlMessage` helper functions for custom match functions
  - Type: `MatchFunction<T>` for custom match functions

  **Changes:**
  - Default timeout for `awaitTxId` reduced from 30 seconds to 5 seconds

  **Example Usage:**

  ```typescript
  import { isChangeMessage } from '@tanstack/electric-db-collection'

  const todosCollection = createCollection(
    electricCollectionOptions({
      onInsert: async ({ transaction, collection }) => {
        const newItem = transaction.mutations[0].modified
        await api.todos.create(newItem)

        // Wait for sync using custom match logic
        await collection.utils.awaitMatch(
          (message) =>
            isChangeMessage(message) &&
            message.headers.operation === 'insert' &&
            message.value.text === newItem.text,
          5000, // timeout in ms (optional, defaults to 5000)
        )
      },
    }),
  )
  ```

  **Benefits:**
  - Supports backends that can't provide transaction IDs
  - Flexible heuristic-based matching
  - Faster feedback on sync issues with reduced timeout

- Updated dependencies [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)]:
  - @tanstack/db@0.4.7

## 0.1.30

### Patch Changes

- prefix logs and errors with collection id, when available ([#655](https://github.com/TanStack/db/pull/655))

- Updated dependencies [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113), [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)]:
  - @tanstack/db@0.4.6

## 0.1.29

### Patch Changes

- The awaitTxId utility now resolves transaction IDs based on snapshot-end message metadata (xmin, xmax, xip_list) in addition to explicit txid arrays, enabling matching on the initial snapshot at the start of a new shape. ([#648](https://github.com/TanStack/db/pull/648))

- Updated dependencies [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)]:
  - @tanstack/db@0.4.5

## 0.1.28

### Patch Changes

- Updated dependencies [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888), [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd), [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627), [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c), [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)]:
  - @tanstack/db@0.4.4

## 0.1.27

### Patch Changes

- Updated dependencies [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)]:
  - @tanstack/db@0.4.3

## 0.1.26

### Patch Changes

- Fix repeated renders when markReady called when the collection was already ready. This would occur after each long poll on an Electric collection. ([#604](https://github.com/TanStack/db/pull/604))

- Updated dependencies [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a), [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534), [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b), [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)]:
  - @tanstack/db@0.4.2

## 0.1.25

### Patch Changes

- Updated dependencies [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)]:
  - @tanstack/db@0.4.1

## 0.1.24

### Patch Changes

- Refactor the main Collection class into smaller classes to make it easier to maintain. ([#560](https://github.com/TanStack/db/pull/560))

- Updated dependencies [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58), [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f), [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)]:
  - @tanstack/db@0.4.0

## 0.1.23

### Patch Changes

- Pull in the latest version of @electric-sql/client instead of pinning it ([#572](https://github.com/TanStack/db/pull/572))

- Updated dependencies [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)]:
  - @tanstack/db@0.3.2

## 0.1.22

### Patch Changes

- Updated dependencies [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)]:
  - @tanstack/db@0.3.1

## 0.1.21

### Patch Changes

- Updated dependencies [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc), [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)]:
  - @tanstack/db@0.3.0

## 0.1.20

### Patch Changes

- Refactor of the types of collection config factories for better type inference. ([#530](https://github.com/TanStack/db/pull/530))

- Define BaseCollectionConfig interface and let all collections extend it. ([#531](https://github.com/TanStack/db/pull/531))

- Updated dependencies [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5), [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)]:
  - @tanstack/db@0.2.5

## 0.1.19

### Patch Changes

- Updated dependencies [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256), [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)]:
  - @tanstack/db@0.2.4

## 0.1.18

### Patch Changes

- Fixed a bug where a live query could get stuck in "loading" state, or show incomplete data, when an electric "must-refetch" message arrived before the first "up-to-date". ([#532](https://github.com/TanStack/db/pull/532))

- Updated dependencies [[`b162556`](https://github.com/TanStack/db/commit/b1625565df44b0824501297f7ef14ae1cd450b49)]:
  - @tanstack/db@0.2.3

## 0.1.17

### Patch Changes

- fix AbortController re-initialization after a collection is garbage collected ([#523](https://github.com/TanStack/db/pull/523))

## 0.1.16

### Patch Changes

- Updated dependencies [[`33515c6`](https://github.com/TanStack/db/commit/33515c69befc557add2cf828354ee378100f3977)]:
  - @tanstack/db@0.2.2

## 0.1.15

### Patch Changes

- Updated dependencies [[`620ebea`](https://github.com/TanStack/db/commit/620ebea96eb3fbeec66701b949de9920c4084c17)]:
  - @tanstack/db@0.2.1

## 0.1.14

### Patch Changes

- Updated dependencies [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6), [`bafeaa1`](https://github.com/TanStack/db/commit/bafeaa1e9f161ac2200ce86537e442b2aa8e2a5b), [`1814f8c`](https://github.com/TanStack/db/commit/1814f8cc3c0e831c82f8053b86fbbbd737e4f34b), [`31acdf2`](https://github.com/TanStack/db/commit/31acdf2a96411da327f93f0d30fa78d884422969), [`e41ed7e`](https://github.com/TanStack/db/commit/e41ed7e1ff1d94dd3ce0c48b6321f66b8ea044fd), [`51954d8`](https://github.com/TanStack/db/commit/51954d8c5d64291d136159bce293e0ad00a19f88)]:
  - @tanstack/db@0.2.0

## 0.1.13

### Patch Changes

- Updated dependencies [[`cc4c34a`](https://github.com/TanStack/db/commit/cc4c34a6b40c81c83aa10c8d00dfc0a3d33c56db)]:
  - @tanstack/db@0.1.12

## 0.1.12

### Patch Changes

- Updated dependencies [[`b869f68`](https://github.com/TanStack/db/commit/b869f68f0109b3126509f202a38855cee38b4276)]:
  - @tanstack/db@0.1.11

## 0.1.11

### Patch Changes

- Updated dependencies [[`eb8fd18`](https://github.com/TanStack/db/commit/eb8fd18c50ee03b72cb06e4d7ef25f214367950b), [`e59a355`](https://github.com/TanStack/db/commit/e59a3551e75bac9dd166e14c911d9491e3a67b9a), [`074aab0`](https://github.com/TanStack/db/commit/074aab0477a7c55e9e0f19a705b96ed2619e2afb), [`d469c39`](https://github.com/TanStack/db/commit/d469c39a7bdc034fa4fbc533010573b3515f239f)]:
  - @tanstack/db@0.1.10

## 0.1.10

### Patch Changes

- Updated dependencies [[`d64b4a8`](https://github.com/TanStack/db/commit/d64b4a8b692a213c7ad58faaf66f5f5fd50bef66)]:
  - @tanstack/db@0.1.9

## 0.1.9

### Patch Changes

- fix the handling of an electric must-refetch message so that the truncate is handled in the same transaction as the next up-to-date, ensuring you don't get a momentary empty collection. ([#460](https://github.com/TanStack/db/pull/460))

- fix disabling of gc by setting `gcTime: 0` on the collection options ([#463](https://github.com/TanStack/db/pull/463))

- Updated dependencies [[`1c5e206`](https://github.com/TanStack/db/commit/1c5e206d00d0a99f8419f0d00429b5a3c6cdc76e), [`4d20004`](https://github.com/TanStack/db/commit/4d2000488b9b5abf85c05801633297528af0eff6), [`968602e`](https://github.com/TanStack/db/commit/968602e4ffc597eaa559219daf22d6ef6321162a)]:
  - @tanstack/db@0.1.8

## 0.1.8

### Patch Changes

- bump electric version ([#454](https://github.com/TanStack/db/pull/454))

## 0.1.7

### Patch Changes

- Updated dependencies [[`48d0889`](https://github.com/TanStack/db/commit/48d088996a3f18df026aa7d2d1e7f27d1151345b), [`aecbcc3`](https://github.com/TanStack/db/commit/aecbcc32012561f1645df0bdf89a6c259058d888), [`a937f4c`](https://github.com/TanStack/db/commit/a937f4c7a5f4fc20c255e86692c5e2e80d5ebbec), [`3d60fad`](https://github.com/TanStack/db/commit/3d60fadbb9e8a1b62a9bcde947e282d653a2a270), [`79c95a3`](https://github.com/TanStack/db/commit/79c95a36f60087ffc3f9a02b76975c8bdf40acc7)]:
  - @tanstack/db@0.1.7

## 0.1.6

### Patch Changes

- Updated dependencies [[`ad33e9e`](https://github.com/TanStack/db/commit/ad33e9e535ca6197c2e00e2dbb59bf8e8f9bb51e)]:
  - @tanstack/db@0.1.6

## 0.1.5

### Patch Changes

- Updated dependencies [[`9a5a20c`](https://github.com/TanStack/db/commit/9a5a20c21fbf8286ab90e1db6d6f3315f8344a4e)]:
  - @tanstack/db@0.1.5

## 0.1.4

### Patch Changes

- Add must-refetch message handling to clear synced data and re-sync collection data from server. ([#412](https://github.com/TanStack/db/pull/412))

- Export the `AwaitTxIdFn` type to ensure that building with types works correctly. ([#398](https://github.com/TanStack/db/pull/398))

- Updated dependencies [[`c90b4d8`](https://github.com/TanStack/db/commit/c90b4d85822f94f7fe72286d5c7ee07b087d0e20), [`6c1c19c`](https://github.com/TanStack/db/commit/6c1c19cedbc1d9d98396948e8e43fa0515bb8919), [`69a6d2d`](https://github.com/TanStack/db/commit/69a6d2d94c7a5510568c8b652356c62bd2b3cc76), [`6250a92`](https://github.com/TanStack/db/commit/6250a92c8045ef2fd69c107a94e05179471681d7), [`68538b4`](https://github.com/TanStack/db/commit/68538b4c446abeb992e24964f811c8900749f141)]:
  - @tanstack/db@0.1.4

## 0.1.3

### Patch Changes

- Updated dependencies [[`0cb7699`](https://github.com/TanStack/db/commit/0cb76999e5d6df5916694a5afeb31b928eab68e4)]:
  - @tanstack/db@0.1.3

## 0.1.2

### Patch Changes

- Ensure that you can use optional properties in the `select` and `join` clauses of a query, and fix an issue where standard schemas were not properly carried through to live queries. ([#377](https://github.com/TanStack/db/pull/377))

- Updated dependencies [[`bb5d50e`](https://github.com/TanStack/db/commit/bb5d50e255d9114ef32b8f52eef6b15399255327), [`97b595e`](https://github.com/TanStack/db/commit/97b595e9617b1abb05c14489e3d608b314da08e8)]:
  - @tanstack/db@0.1.2

## 0.1.1

### Patch Changes

- Updated dependencies [[`bc2f204`](https://github.com/TanStack/db/commit/bc2f204b8cb8a4870ade00757d10f846524e2090), [`bda3f24`](https://github.com/TanStack/db/commit/bda3f24cc41504f60be0c5e071698b7735f75e28)]:
  - @tanstack/db@0.1.1

## 0.1.0

### Minor Changes

- 0.1 release - first beta 🎉 ([#332](https://github.com/TanStack/db/pull/332))

### Patch Changes

- Updated dependencies [[`7d2f4be`](https://github.com/TanStack/db/commit/7d2f4be95c43aad29fb61e80e5a04c58c859322b), [`f0eda36`](https://github.com/TanStack/db/commit/f0eda36cb36350399bc8835686a6c4b6ad297e45)]:
  - @tanstack/db@0.1.0

## 0.0.15

### Patch Changes

- Updated dependencies [[`6e8d7f6`](https://github.com/TanStack/db/commit/6e8d7f660050118e050d575913733e469e3daa8c)]:
  - @tanstack/db@0.0.33

## 0.0.14

### Patch Changes

- Updated dependencies [[`e04bd12`](https://github.com/TanStack/db/commit/e04bd1252f612d4638104368d17cb644cc85295b)]:
  - @tanstack/db@0.0.32

## 0.0.13

### Patch Changes

- Updated dependencies [[`3e9a36d`](https://github.com/TanStack/db/commit/3e9a36d2600c4f700ca7bc4f720c189a5a29387a)]:
  - @tanstack/db@0.0.31

## 0.0.12

### Patch Changes

- Updated dependencies [[`6bdde55`](https://github.com/TanStack/db/commit/6bdde554f36f54c0c4f4dacb74bef5da45811855)]:
  - @tanstack/db@0.0.30

## 0.0.11

### Patch Changes

- feat: Replace string-based errors with named error classes for better error handling ([#297](https://github.com/TanStack/db/pull/297))

  This comprehensive update replaces all string-based error throws throughout the TanStack DB codebase with named error classes, providing better type safety and developer experience.

  ## New Features
  - **Root `TanStackDBError` class** - all errors inherit from a common base for unified error handling
  - **Named error classes** organized by package and functional area
  - **Type-safe error handling** using `instanceof` checks instead of string matching
  - **Package-specific error definitions** - each adapter has its own error classes
  - **Better IDE support** with autocomplete for error types

  ## Package Structure

  ### Core Package (`@tanstack/db`)

  Contains generic errors used across the ecosystem:
  - Collection configuration, state, and operation errors
  - Transaction lifecycle and mutation errors
  - Query building, compilation, and execution errors
  - Storage and serialization errors

  ### Adapter Packages

  Each adapter now exports its own specific error classes:
  - **`@tanstack/electric-db-collection`**: Electric-specific errors
  - **`@tanstack/trailbase-db-collection`**: TrailBase-specific errors
  - **`@tanstack/query-db-collection`**: Query collection specific errors

  ## Breaking Changes
  - Error handling code using string matching will need to be updated to use `instanceof` checks
  - Some error messages may have slight formatting changes
  - Adapter-specific errors now need to be imported from their respective packages

  ## Migration Guide

  ### Core DB Errors

  **Before:**

  ```ts
  try {
    collection.insert(data)
  } catch (error) {
    if (error.message.includes('already exists')) {
      // Handle duplicate key error
    }
  }
  ```

  **After:**

  ```ts
  import { DuplicateKeyError } from '@tanstack/db'

  try {
    collection.insert(data)
  } catch (error) {
    if (error instanceof DuplicateKeyError) {
      // Type-safe error handling
    }
  }
  ```

  ### Adapter-Specific Errors

  **Before:**

  ```ts
  // Electric collection errors were imported from @tanstack/db
  import { ElectricInsertHandlerMustReturnTxIdError } from '@tanstack/db'
  ```

  **After:**

  ```ts
  // Now import from the specific adapter package
  import { ElectricInsertHandlerMustReturnTxIdError } from '@tanstack/electric-db-collection'
  ```

  ### Unified Error Handling

  **New:**

  ```ts
  import { TanStackDBError } from '@tanstack/db'

  try {
    // Any TanStack DB operation
  } catch (error) {
    if (error instanceof TanStackDBError) {
      // Handle all TanStack DB errors uniformly
      console.log('TanStack DB error:', error.message)
    }
  }
  ```

  ## Benefits
  - **Type Safety**: All errors now have specific types that can be caught with `instanceof`
  - **Unified Error Handling**: Root `TanStackDBError` class allows catching all library errors with a single check
  - **Better Package Separation**: Each adapter manages its own error types
  - **Developer Experience**: Better IDE support with autocomplete for error types
  - **Maintainability**: Error definitions are co-located with their usage
  - **Consistency**: Uniform error handling patterns across the entire codebase

  All error classes maintain the same error messages and behavior while providing better structure and package separation.

- Updated dependencies [[`ced0657`](https://github.com/TanStack/db/commit/ced0657e72646e35343dfea8389d96e213710cdf), [`dcfef51`](https://github.com/TanStack/db/commit/dcfef51d4d94c756bf77e40e7015e47b7982c09a), [`360b0df`](https://github.com/TanStack/db/commit/360b0dfa411ba9f8a93f6b737aa1df8fb37dd036), [`608be0c`](https://github.com/TanStack/db/commit/608be0c14dc5ae9577deebf436557a1eace46733), [`5260ee3`](https://github.com/TanStack/db/commit/5260ee3098d12eccc58a5cf903ea479908681402)]:
  - @tanstack/db@0.0.29

## 0.0.10

### Patch Changes

- Updated dependencies [[`bb85522`](https://github.com/TanStack/db/commit/bb8552210a97dd05d3ca6fdd080a3fd25c1023a6), [`e9e8e5e`](https://github.com/TanStack/db/commit/e9e8e5e20c23fb7f98865d6b8aab05ad5322e5f7)]:
  - @tanstack/db@0.0.28

## 0.0.9

### Patch Changes

- Updated dependencies [[`bec8620`](https://github.com/TanStack/db/commit/bec862004deef5fdd560f70107ebd59f7c27656e)]:
  - @tanstack/db@0.0.27

## 0.0.8

### Patch Changes

- Add initial release of TrailBase collection for TanStack DB. TrailBase is a blazingly fast, open-source alternative to Firebase built on Rust, SQLite, and V8. It provides type-safe REST and realtime APIs with sub-millisecond latencies, integrated authentication, and flexible access control - all in a single executable. This collection type enables seamless integration with TrailBase backends for high-performance real-time applications. ([#228](https://github.com/TanStack/db/pull/228))

- Updated dependencies [[`09c6995`](https://github.com/TanStack/db/commit/09c6995ea9c8e6979d077ca63cbdd6215054ae78)]:
  - @tanstack/db@0.0.26

## 0.0.7

### Patch Changes

- Add explicit collection readiness detection with `isReady()` and `markReady()` ([#270](https://github.com/TanStack/db/pull/270))
  - Add `isReady()` method to check if a collection is ready for use
  - Add `onFirstReady()` method to register callbacks for when collection becomes ready
  - Add `markReady()` to SyncConfig interface for sync implementations to explicitly signal readiness
  - Replace `onFirstCommit()` with `onFirstReady()` for better semantics
  - Update status state machine to allow `loading` → `ready` transition for cases with no data to commit
  - Update all sync implementations (Electric, Query, Local-only, Local-storage) to use `markReady()`
  - Improve error handling by allowing collections to be marked ready even when sync errors occur

  This provides a more intuitive and ergonomic API for determining collection readiness, replacing the previous approach of using commits as a readiness signal.

- Updated dependencies [[`1758eda`](https://github.com/TanStack/db/commit/1758edab9608383d9d1470156021ee632f043e51), [`20f810e`](https://github.com/TanStack/db/commit/20f810e13a7d802bf56da6f0df89b34312ebb2fd)]:
  - @tanstack/db@0.0.25

## 0.0.6

### Patch Changes

- Updated dependencies [[`11215d9`](https://github.com/TanStack/db/commit/11215d9544d02e9dc6258c661ba4b5e439e479ed), [`fe42591`](https://github.com/TanStack/db/commit/fe42591bd7ea9955d67ecec4471b44cb7808e74b), [`665efe6`](https://github.com/TanStack/db/commit/665efe660c1aed68139326a2a33904968622a882)]:
  - @tanstack/db@0.0.24

## 0.0.5

### Patch Changes

- Updated dependencies [[`056609e`](https://github.com/TanStack/db/commit/056609ed2926e12df5ee08be5fad0a6333e787f3)]:
  - @tanstack/db@0.0.23

## 0.0.4

### Patch Changes

- Updated dependencies [[`aeee9a1`](https://github.com/TanStack/db/commit/aeee9a13411527bd0ebfc0a0c06989bdb904b650)]:
  - @tanstack/db@0.0.22

## 0.0.3

### Patch Changes

- Move Collections to their own packages ([#252](https://github.com/TanStack/db/pull/252))
  - Move local-only and local-storage collections to main `@tanstack/db` package
  - Create new `@tanstack/electric-db-collection` package for ElectricSQL integration
  - Create new `@tanstack/query-db-collection` package for TanStack Query integration
  - Delete `@tanstack/db-collections` package (removed from repo)
  - Update example app and documentation to use new package structure

  Why?
  - Better separation of concerns
  - Independent versioning for each collection type
  - Cleaner dependencies (electric collections don't need query deps, etc.)
  - Easier to add more collection types moving forward

- Updated dependencies [[`8e23322`](https://github.com/TanStack/db/commit/8e233229b25eabed07cdaf12948ba913786bf4f9)]:
  - @tanstack/db@0.0.21


## Links discovered
- [#960](https://github.com/TanStack/db/pull/960)
- [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0)
- [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435)
- [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [#940](https://github.com/TanStack/db/pull/940)
- [#932](https://github.com/TanStack/db/pull/932)
- [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd)
- [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)
- [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)
- [#924](https://github.com/TanStack/db/pull/924)
- [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60)
- [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)
- [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)
- [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)
- [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)
- [#884](https://github.com/TanStack/db/pull/884)
- [#852](https://github.com/TanStack/db/pull/852)
- [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938)
- [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe)
- [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116)
- [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)
- [#854](https://github.com/TanStack/db/pull/854)
- [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9)
- [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)
- [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)
- [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [#798](https://github.com/TanStack/db/pull/798)
- [#795](https://github.com/TanStack/db/pull/795)
- [#763](https://github.com/TanStack/db/pull/763)
- [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)
- [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45)
- [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a)
- [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)
- [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)
- [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9)
- [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)
- [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)
- [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110)
- [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b)
- [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)
- [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)
- [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)
- [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)
- [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477)
- [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)
- [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)
- [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a)
- [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)
- [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47)
- [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13)
- [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)
- [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450)
- [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)
- [#499](https://github.com/TanStack/db/pull/499)
- [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)
- [#655](https://github.com/TanStack/db/pull/655)
- [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113)
- [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)
- [#648](https://github.com/TanStack/db/pull/648)
- [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)
- [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888)
- [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd)
- [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627)
- [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c)
- [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)
- [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)
- [#604](https://github.com/TanStack/db/pull/604)
- [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a)
- [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534)
- [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b)
- [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)
- [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)
- [#560](https://github.com/TanStack/db/pull/560)
- [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f)
- [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [#572](https://github.com/TanStack/db/pull/572)
- [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)
- [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)
- [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc)
- [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)
- [#530](https://github.com/TanStack/db/pull/530)
- [#531](https://github.com/TanStack/db/pull/531)
- [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5)
- [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)
- [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256)
- [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)
- [#532](https://github.com/TanStack/db/pull/532)
- [[`b162556`](https://github.com/TanStack/db/commit/b1625565df44b0824501297f7ef14ae1cd450b49)
- [#523](https://github.com/TanStack/db/pull/523)
- [[`33515c6`](https://github.com/TanStack/db/commit/33515c69befc557add2cf828354ee378100f3977)
- [[`620ebea`](https://github.com/TanStack/db/commit/620ebea96eb3fbeec66701b949de9920c4084c17)
- [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6)

--- packages/offline-transactions/CHANGELOG.md ---
# @tanstack/offline-transactions

## 1.0.2

### Patch Changes

- Updated dependencies [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0), [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435), [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)]:
  - @tanstack/db@0.5.12

## 1.0.1

### Patch Changes

- Use regular dependency for @tanstack/db instead of peerDependency to match the standard pattern used by other TanStack DB packages and prevent duplicate installations ([#952](https://github.com/TanStack/db/pull/952))

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)]:
  - @tanstack/db@0.5.11

## 1.0.0

### Patch Changes

- Updated dependencies [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/db@0.5.0

## 0.1.3

### Patch Changes

- Fix dependency bundling issues by moving @tanstack/db to peerDependencies ([#766](https://github.com/TanStack/db/pull/766))

  **What Changed:**

  Moved `@tanstack/db` from regular dependencies to peerDependencies in:
  - `@tanstack/offline-transactions`
  - `@tanstack/query-db-collection`

  Removed `@opentelemetry/api` dependency from `@tanstack/offline-transactions`.

  **Why:**

  These extension packages incorrectly declared `@tanstack/db` as both a regular dependency AND a peerDependency simultaneously. This caused lock files to develop conflicting versions, resulting in multiple instances of `@tanstack/db` being installed in consuming applications.

  The fix removes `@tanstack/db` from regular dependencies and keeps it only as a peerDependency. This ensures only one version of `@tanstack/db` is installed in the dependency tree, preventing version conflicts.

  For local development, `@tanstack/db` remains in devDependencies so the packages can be built and tested independently.

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20

## 0.1.2

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19

## 0.1.1

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18

## 0.1.0

### Minor Changes

- Add offline-transactions package with robust offline-first capabilities ([#559](https://github.com/TanStack/db/pull/559))

  New package `@tanstack/offline-transactions` provides a comprehensive offline-first transaction system with:

  **Core Features:**
  - Persistent outbox pattern for reliable transaction processing
  - Leader election for multi-tab coordination (Web Locks API with BroadcastChannel fallback)
  - Automatic storage capability detection with graceful degradation
  - Retry logic with exponential backoff and jitter
  - Sequential transaction processing (FIFO ordering)

  **Storage:**
  - Automatic fallback chain: IndexedDB → localStorage → online-only
  - Detects and handles private mode, SecurityError, QuotaExceededError
  - Custom storage adapter support
  - Diagnostic callbacks for storage failures

  **Developer Experience:**
  - TypeScript-first with full type safety
  - Comprehensive test suite (25 tests covering leader failover, storage failures, e2e scenarios)
  - Works in all modern browsers and server-side rendering environments

  **@tanstack/db improvements:**
  - Enhanced duplicate instance detection (dev-only, iframe-aware, with escape hatch)
  - Better environment detection for SSR and worker contexts

  Example usage:

  ```typescript
  import {
    startOfflineExecutor,
    IndexedDBAdapter,
  } from '@tanstack/offline-transactions'

  const executor = startOfflineExecutor({
    collections: { todos: todoCollection },
    storage: new IndexedDBAdapter(),
    mutationFns: {
      syncTodos: async ({ transaction, idempotencyKey }) => {
        // Sync mutations to backend
        await api.sync(transaction.mutations, idempotencyKey)
      },
    },
    onStorageFailure: (diagnostic) => {
      console.warn('Running in online-only mode:', diagnostic.message)
    },
  })

  // Create offline transaction
  const tx = executor.createOfflineTransaction({
    mutationFnName: 'syncTodos',
    autoCommit: false,
  })

  tx.mutate(() => {
    todoCollection.insert({ id: '1', text: 'Buy milk', completed: false })
  })

  await tx.commit() // Persists to outbox and syncs when online
  ```

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17


## Links discovered
- [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0)
- [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435)
- [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)
- [#952](https://github.com/TanStack/db/pull/952)
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)
- [#766](https://github.com/TanStack/db/pull/766)
- [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45)
- [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a)
- [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)
- [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)
- [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9)
- [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)
- [#559](https://github.com/TanStack/db/pull/559)
- [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)

--- packages/powersync-db-collection/CHANGELOG.md ---
# @tanstack/powersync-db-collection

## 0.1.16

### Patch Changes

- Updated dependencies [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0), [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435), [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)]:
  - @tanstack/db@0.5.12

## 0.1.15

### Patch Changes

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)]:
  - @tanstack/db@0.5.11

## 0.1.14

### Patch Changes

- Updated dependencies [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd), [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)]:
  - @tanstack/db@0.5.10

## 0.1.13

### Patch Changes

- Updated dependencies [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)]:
  - @tanstack/db@0.5.9

## 0.1.12

### Patch Changes

- Updated dependencies [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60), [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)]:
  - @tanstack/db@0.5.8

## 0.1.11

### Patch Changes

- Updated dependencies [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)]:
  - @tanstack/db@0.5.7

## 0.1.10

### Patch Changes

- Updated dependencies [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)]:
  - @tanstack/db@0.5.6

## 0.1.9

### Patch Changes

- Updated dependencies [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)]:
  - @tanstack/db@0.5.5

## 0.1.8

### Patch Changes

- Updated dependencies [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938), [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe), [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116), [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)]:
  - @tanstack/db@0.5.4

## 0.1.7

### Patch Changes

- Updated dependencies [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9), [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)]:
  - @tanstack/db@0.5.3

## 0.1.6

### Patch Changes

- Updated dependencies [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)]:
  - @tanstack/db@0.5.2

## 0.1.5

### Patch Changes

- Updated dependencies [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)]:
  - @tanstack/db@0.5.1

## 0.1.4

### Patch Changes

- Updated dependencies [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/db@0.5.0

## 0.1.3

### Patch Changes

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20

## 0.1.2

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19

## 0.1.1

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18

## 0.1.0

### Minor Changes

- Initial Release ([#747](https://github.com/TanStack/db/pull/747))

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17


## Links discovered
- [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0)
- [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435)
- [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd)
- [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)
- [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)
- [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60)
- [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)
- [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)
- [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)
- [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)
- [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938)
- [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe)
- [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116)
- [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)
- [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9)
- [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)
- [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)
- [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)
- [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45)
- [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a)
- [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)
- [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)
- [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9)
- [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)
- [#747](https://github.com/TanStack/db/pull/747)
- [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)

--- packages/query-db-collection/CHANGELOG.md ---
# @tanstack/query-db-collection

## 1.0.7

### Patch Changes

- Enhanced LoadSubsetOptions with separate cursor expressions and offset for flexible pagination. ([#960](https://github.com/TanStack/db/pull/960))

  **⚠️ Breaking Change for Custom Sync Layers / Query Collections:**

  `LoadSubsetOptions.where` no longer includes cursor expressions for pagination. If you have a custom sync layer or query collection that implements `loadSubset`, you must now handle pagination separately:
  - **Cursor-based pagination:** Use the new `cursor` property (`cursor.whereFrom` and `cursor.whereCurrent`) and combine them with `where` yourself
  - **Offset-based pagination:** Use the new `offset` property

  Previously, cursor expressions were baked into the `where` clause. Now they are passed separately so sync layers can choose their preferred pagination strategy.

  **Changes:**
  - Added `CursorExpressions` type with `whereFrom`, `whereCurrent`, and optional `lastKey` properties
  - Added `cursor` to `LoadSubsetOptions` for cursor-based pagination (separate from `where`)
  - Added `offset` to `LoadSubsetOptions` for offset-based pagination support
  - Electric sync layer now makes two parallel `requestSnapshot` calls when cursor is present:
    - One for `whereCurrent` (all ties at boundary, no limit)
    - One for `whereFrom` (rows after cursor, with limit)
  - Query collection serialization now includes `offset` for query key generation
  - Added `truncate` event to collections, emitted when synced data is truncated (e.g., after `must-refetch`)
  - Fixed `setWindow` pagination: cursor expressions are now correctly built when paging through results
  - Fixed offset tracking: `loadNextItems` now passes the correct window offset to prevent incorrect deduplication
  - `CollectionSubscriber` now listens for `truncate` events to reset cursor tracking state

  **Benefits:**
  - Sync layers can choose between cursor-based or offset-based pagination strategies
  - Electric can efficiently handle tie-breaking with two targeted requests
  - Better separation of concerns between filtering (`where`) and pagination (`cursor`/`offset`)
  - `setWindow` correctly triggers backend loading for subsequent pages in multi-column orderBy queries
  - Cursor state is properly reset after truncation, preventing stale cursor data from being used

- Updated dependencies [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0), [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435), [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)]:
  - @tanstack/db@0.5.12

## 1.0.6

### Patch Changes

- fix(query-db-collection): use deep equality for object field comparison in query observer ([#967](https://github.com/TanStack/db/pull/967))

  Fixed an issue where updating object fields (non-primitives) with `refetch: false` in `onUpdate` handlers would cause the value to rollback to the previous state every other update. The query observer was using shallow equality (`===`) to compare items, which compares object properties by reference rather than by value. This caused the observer to incorrectly detect differences and write stale data back to syncedData. Now uses `deepEquals` for proper value comparison.

- Use regular dependency for @tanstack/db instead of peerDependency to match the standard pattern used by other TanStack DB packages and prevent duplicate installations ([#952](https://github.com/TanStack/db/pull/952))

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)]:
  - @tanstack/db@0.5.11

## 1.0.5

### Patch Changes

- fix: ensure ctx.meta.loadSubsetOptions type-safety works automatically ([#869](https://github.com/TanStack/db/pull/869))

  The module augmentation for ctx.meta.loadSubsetOptions is now guaranteed to load automatically when importing from @tanstack/query-db-collection. Previously, users needed to explicitly import QueryCollectionMeta or use @ts-ignore to pass ctx.meta?.loadSubsetOptions to parseLoadSubsetOptions.

  Additionally, QueryCollectionMeta is now an interface (instead of a type alias), enabling users to safely extend meta with custom properties via declaration merging:

  ```typescript
  declare module '@tanstack/query-db-collection' {
    interface QueryCollectionMeta {
      myCustomProperty: string
    }
  }
  ```

- Updated dependencies [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)]:
  - @tanstack/db@0.5.6

## 1.0.4

### Patch Changes

- Fix data loss on component remount by implementing reference counting for QueryObserver lifecycle ([#870](https://github.com/TanStack/db/pull/870))

  **What changed vs main:**

  Previously, when live query subscriptions unsubscribed, there was no tracking of which rows were still needed by other active queries. This caused data loss during remounts.

  This PR adds reference counting infrastructure to properly manage QueryObserver lifecycle:
  1. Pass same predicates to `unloadSubset` that were passed to `loadSubset`
  2. Use them to compute the queryKey (via `generateQueryKeyFromOptions`)
  3. Use existing machinery (`queryToRows` map) to find rows that query loaded
  4. Decrement the ref count
  5. GC rows where count reaches 0 (no longer referenced by any active query)

  **Impact:**
  - Navigation back to previously loaded pages shows cached data immediately
  - No unnecessary refetches during quick remounts (< gcTime)
  - Multiple live queries with identical predicates correctly share QueryObservers
  - Proper row-level cleanup when last subscriber leaves
  - TanStack Query's cache lifecycle (gcTime) is fully respected
  - No data leakage from in-flight requests when unsubscribing

- Updated dependencies [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)]:
  - @tanstack/db@0.5.5

## 1.0.3

### Patch Changes

- Improved the type of the queryFn's ctx.meta property of the Query Collection to include the loadSubsetOptions ([#857](https://github.com/TanStack/db/pull/857))

- Fixed bug where optimistic state leaked into syncedData when using writeInsert inside onInsert handlers. Previously, when syncing server-generated fields (like IDs or timestamps) using writeInsert within an onInsert handler, the QueryClient cache was updated with combined visible state (including optimistic changes), which triggered the query observer to write optimistic values back to syncedData. Now the cache is correctly updated with only server-confirmed state, ensuring syncedData maintains separation from optimistic state. ([#879](https://github.com/TanStack/db/pull/879))

- Updated dependencies [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938), [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe), [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116), [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)]:
  - @tanstack/db@0.5.4

## 1.0.2

### Patch Changes

- Automatically append predicates to static queryKey in on-demand mode. ([#800](https://github.com/TanStack/db/pull/800))

  When using a static `queryKey` with `syncMode: 'on-demand'`, the system now automatically appends serialized LoadSubsetOptions to create unique cache keys for different predicate combinations. This fixes an issue where all live queries with different predicates would share the same TanStack Query cache entry, causing data to be overwritten.

  **Before:**

  ```typescript
  // This would cause conflicts between different queries
  queryCollectionOptions({
    queryKey: ['products'], // Static key
    syncMode: 'on-demand',
    queryFn: async (ctx) => {
      const { where, limit } = ctx.meta.loadSubsetOptions
      return fetch(`/api/products?...`).then((r) => r.json())
    },
  })
  ```

  With different live queries filtering by `category='A'` and `category='B'`, both would share the same cache key `['products']`, causing the last query to overwrite the first.

  **After:**
  Static queryKeys now work correctly in on-demand mode! The system automatically creates unique cache keys:
  - Query with `category='A'` → `['products', '{"where":{...A...}}']`
  - Query with `category='B'` → `['products', '{"where":{...B...}}']`

  **Key behaviors:**
  - ✅ Static queryKeys now work correctly with on-demand mode (automatic serialization)
  - ✅ Function-based queryKeys continue to work as before (no change)
  - ✅ Eager mode with static queryKeys unchanged (no automatic serialization)
  - ✅ Identical predicates correctly reuse the same cache entry

  This makes the documentation example work correctly without requiring users to manually implement function-based queryKeys for predicate push-down.

- Updated dependencies [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9), [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)]:
  - @tanstack/db@0.5.3

## 1.0.1

### Patch Changes

- Temporarily remove `loadSubset` call deduplication in query collection. We need to revisit our approach to deduplication to ensure correctness. See https://github.com/TanStack/db/issues/836 for discussion on the proper implementation strategy. ([#840](https://github.com/TanStack/db/pull/840))

- Updated dependencies [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)]:
  - @tanstack/db@0.5.1

## 1.0.0

### Patch Changes

- Add expression helper utilities for parsing LoadSubsetOptions in queryFn. ([#763](https://github.com/TanStack/db/pull/763))

  When using `syncMode: 'on-demand'`, TanStack DB now provides helper functions to easily parse where clauses, orderBy, and limit predicates into your API's format:
  - `parseWhereExpression`: Parse where clauses with custom handlers for each operator
  - `parseOrderByExpression`: Parse order by into simple array format
  - `extractSimpleComparisons`: Extract simple AND-ed filters
  - `parseLoadSubsetOptions`: Convenience function to parse all options at once
  - `walkExpression`, `extractFieldPath`, `extractValue`: Lower-level helpers

  **Example:**

  ```typescript
  import { parseLoadSubsetOptions } from '@tanstack/db'
  // or from "@tanstack/query-db-collection" (re-exported for convenience)

  queryFn: async (ctx) => {
    const { where, orderBy, limit } = ctx.meta.loadSubsetOptions

    const parsed = parseLoadSubsetOptions({ where, orderBy, limit })

    // Build API request from parsed filters
    const params = new URLSearchParams()
    parsed.filters.forEach(({ field, operator, value }) => {
      if (operator === 'eq') {
        params.set(field.join('.'), String(value))
      }
    })

    return fetch(`/api/products?${params}`).then((r) => r.json())
  }
  ```

  This eliminates the need to manually traverse expression AST trees when implementing predicate push-down.

- Handle pushed-down predicates ([#763](https://github.com/TanStack/db/pull/763))

- Updated dependencies [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/db@0.5.0

## 0.3.0

### Minor Changes

- Add QueryObserver state utilities and convert error utils to getters ([#742](https://github.com/TanStack/db/pull/742))

  Exposes TanStack Query's QueryObserver state through QueryCollectionUtils, providing visibility into sync status beyond just error states. Also converts existing error state utilities from methods to getters for consistency with TanStack DB/Query patterns.

  **Breaking Changes:**
  - `lastError()`, `isError()`, and `errorCount()` are now getters instead of methods
    - Before: `collection.utils.lastError()`
    - After: `collection.utils.lastError`

  **New Utilities:**
  - `isFetching` - Check if query is currently fetching (initial or background)
  - `isRefetching` - Check if query is refetching in background
  - `isLoading` - Check if query is loading for first time
  - `dataUpdatedAt` - Get timestamp of last successful data update
  - `fetchStatus` - Get current fetch status ('fetching' | 'paused' | 'idle')

  **Use Cases:**
  - Show loading indicators during background refetches
  - Implement "Last updated X minutes ago" UI patterns
  - Better understanding of query sync behavior

  **Example Usage:**

  ```ts
  const collection = queryCollectionOptions({
    // ... config
  })

  // Check sync status
  if (collection.utils.isFetching) {
    console.log('Syncing with server...')
  }

  if (collection.utils.isRefetching) {
    console.log('Background refresh in progress')
  }

  // Show last update time
  const lastUpdate = new Date(collection.utils.dataUpdatedAt)
  console.log(`Last synced: ${lastUpdate.toLocaleTimeString()}`)

  // Check error state (now using getters)
  if (collection.utils.isError) {
    console.error('Sync failed:', collection.utils.lastError)
    console.log(`Failed ${collection.utils.errorCount} times`)
  }
  ```

### Patch Changes

- Fix dependency bundling issues by moving @tanstack/db to peerDependencies ([#766](https://github.com/TanStack/db/pull/766))

  **What Changed:**

  Moved `@tanstack/db` from regular dependencies to peerDependencies in:
  - `@tanstack/offline-transactions`
  - `@tanstack/query-db-collection`

  Removed `@opentelemetry/api` dependency from `@tanstack/offline-transactions`.

  **Why:**

  These extension packages incorrectly declared `@tanstack/db` as both a regular dependency AND a peerDependency simultaneously. This caused lock files to develop conflicting versions, resulting in multiple instances of `@tanstack/db` being installed in consuming applications.

  The fix removes `@tanstack/db` from regular dependencies and keeps it only as a peerDependency. This ensures only one version of `@tanstack/db` is installed in the dependency tree, preventing version conflicts.

  For local development, `@tanstack/db` remains in devDependencies so the packages can be built and tested independently.

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20

## 0.2.42

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19

## 0.2.41

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18

## 0.2.40

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17

## 0.2.39

### Patch Changes

- Updated dependencies [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110), [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b), [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)]:
  - @tanstack/db@0.4.16

## 0.2.38

### Patch Changes

- Updated dependencies [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)]:
  - @tanstack/db@0.4.15

## 0.2.37

### Patch Changes

- **Behavior change**: `utils.refetch()` now uses exact query key targeting (previously used prefix matching). This prevents unintended cascading refetches of related queries. For example, refetching `['todos', 'project-1']` will no longer trigger refetches of `['todos']` or `['todos', 'project-2']`. ([#552](https://github.com/TanStack/db/pull/552))

  Additionally, `utils.refetch()` now bypasses `enabled: false` to support manual/imperative refetch patterns (matching TanStack Query hook behavior) and returns `QueryObserverResult` instead of `void` for better DX.

## 0.2.36

### Patch Changes

- Updated dependencies [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)]:
  - @tanstack/db@0.4.14

## 0.2.35

### Patch Changes

- Updated dependencies [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)]:
  - @tanstack/db@0.4.13

## 0.2.34

### Patch Changes

- Fix queryCollectionOptions to respect QueryClient defaultOptions when not overridden ([#707](https://github.com/TanStack/db/pull/707))

  Previously, when creating a QueryClient with defaultOptions (e.g., staleTime, retry, refetchOnWindowFocus), these options were ignored by queryCollectionOptions unless explicitly specified again in the collection config. This required duplicating configuration and prevented users from setting global defaults.

  Now, queryCollectionOptions properly respects the QueryClient's defaultOptions as fallbacks. Options explicitly provided in queryCollectionOptions will still override the defaults.

  Example - this now works as expected:

  ```typescript
  const dbQueryClient = new QueryClient({
    defaultOptions: {
      queries: {
        refetchOnWindowFocus: false,
        staleTime: Infinity,
      },
    },
  })

  queryCollectionOptions({
    id: 'wallet-accounts',
    queryKey: ['wallet-accounts'],
    queryClient: dbQueryClient,
    // staleTime: Infinity is now inherited from defaultOptions
  })
  ```

- Fix writeDelete/writeUpdate validation to check synced store only ([#708](https://github.com/TanStack/db/pull/708))

  Fixed issue where calling `writeDelete()` or `writeUpdate()` inside mutation handlers (like `onDelete`) would throw errors when optimistic updates were active. These write operations now correctly validate against the synced store only, not the combined view (synced + optimistic).

  This allows patterns like calling `writeDelete()` inside an `onDelete` handler to work correctly, enabling users to write directly to the synced store while the mutation is being persisted to the backend.

  Fixes #706

## 0.2.33

### Patch Changes

- Updated dependencies [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477), [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)]:
  - @tanstack/db@0.4.12

## 0.2.32

### Patch Changes

- Updated dependencies [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)]:
  - @tanstack/db@0.4.11

## 0.2.31

### Patch Changes

- Updated dependencies [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a), [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)]:
  - @tanstack/db@0.4.10

## 0.2.30

### Patch Changes

- Updated dependencies [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47), [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13), [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)]:
  - @tanstack/db@0.4.9

## 0.2.29

### Patch Changes

- Updated dependencies [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450), [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)]:
  - @tanstack/db@0.4.8

## 0.2.28

### Patch Changes

- Updated dependencies [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)]:
  - @tanstack/db@0.4.7

## 0.2.27

### Patch Changes

- Updated dependencies [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113), [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)]:
  - @tanstack/db@0.4.6

## 0.2.26

### Patch Changes

- Updated dependencies [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)]:
  - @tanstack/db@0.4.5

## 0.2.25

### Patch Changes

- Fix collection.preload() hanging when called without startSync or subscribers. The QueryObserver now subscribes immediately when sync starts (from preload(), startSync, or first subscriber), while maintaining the staleTime behavior by dynamically unsubscribing when subscriber count drops to zero. ([#635](https://github.com/TanStack/db/pull/635))

- Updated dependencies [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888), [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd), [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627), [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c), [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)]:
  - @tanstack/db@0.4.4

## 0.2.24

### Patch Changes

- Updated dependencies [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)]:
  - @tanstack/db@0.4.3

## 0.2.23

### Patch Changes

- Fix `staleTime` behavior by automatically subscribing/unsubscribing from TanStack Query based on collection subscriber count. ([#462](https://github.com/TanStack/db/pull/462))

  Previously, query collections kept a QueryObserver permanently subscribed, which broke TanStack Query's `staleTime` and window-focus refetch behavior. Now the QueryObserver properly goes inactive when the collection has no subscribers, restoring normal `staleTime`/`gcTime` semantics.

- query-collection now supports a `select` function to transform raw query results into an array of items. This is useful for APIs that return data with metadata or nested structures, ensuring metadata remains cached while collections work with the unwrapped array. ([#551](https://github.com/TanStack/db/pull/551))

- Updated dependencies [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a), [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534), [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b), [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)]:
  - @tanstack/db@0.4.2

## 0.2.22

### Patch Changes

- Updated dependencies [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)]:
  - @tanstack/db@0.4.1

## 0.2.21

### Patch Changes

- Refactor the main Collection class into smaller classes to make it easier to maintain. ([#560](https://github.com/TanStack/db/pull/560))

- Updated dependencies [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58), [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f), [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)]:
  - @tanstack/db@0.4.0

## 0.2.20

### Patch Changes

- Updated dependencies [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)]:
  - @tanstack/db@0.3.2

## 0.2.19

### Patch Changes

- Updated dependencies [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)]:
  - @tanstack/db@0.3.1

## 0.2.18

### Patch Changes

- Updated dependencies [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc), [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)]:
  - @tanstack/db@0.3.0

## 0.2.17

### Patch Changes

- Refactor of the types of collection config factories for better type inference. ([#530](https://github.com/TanStack/db/pull/530))

- Define BaseCollectionConfig interface and let all collections extend it. ([#531](https://github.com/TanStack/db/pull/531))

- Updated dependencies [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5), [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)]:
  - @tanstack/db@0.2.5

## 0.2.16

### Patch Changes

- Add error tracking and retry methods to query collection utils. ([#441](https://github.com/TanStack/db/pull/441))

- Updated dependencies [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256), [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)]:
  - @tanstack/db@0.2.4

## 0.2.15

### Patch Changes

- Updated dependencies [[`b162556`](https://github.com/TanStack/db/commit/b1625565df44b0824501297f7ef14ae1cd450b49)]:
  - @tanstack/db@0.2.3

## 0.2.14

### Patch Changes

- Updated dependencies [[`33515c6`](https://github.com/TanStack/db/commit/33515c69befc557add2cf828354ee378100f3977)]:
  - @tanstack/db@0.2.2

## 0.2.13

### Patch Changes

- Updated dependencies [[`620ebea`](https://github.com/TanStack/db/commit/620ebea96eb3fbeec66701b949de9920c4084c17)]:
  - @tanstack/db@0.2.1

## 0.2.12

### Patch Changes

- Updated dependencies [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6), [`bafeaa1`](https://github.com/TanStack/db/commit/bafeaa1e9f161ac2200ce86537e442b2aa8e2a5b), [`1814f8c`](https://github.com/TanStack/db/commit/1814f8cc3c0e831c82f8053b86fbbbd737e4f34b), [`31acdf2`](https://github.com/TanStack/db/commit/31acdf2a96411da327f93f0d30fa78d884422969), [`e41ed7e`](https://github.com/TanStack/db/commit/e41ed7e1ff1d94dd3ce0c48b6321f66b8ea044fd), [`51954d8`](https://github.com/TanStack/db/commit/51954d8c5d64291d136159bce293e0ad00a19f88)]:
  - @tanstack/db@0.2.0

## 0.2.11

### Patch Changes

- fix: race condition creating a collection from a query that has already loaded ([#495](https://github.com/TanStack/db/pull/495))

- Updated dependencies [[`cc4c34a`](https://github.com/TanStack/db/commit/cc4c34a6b40c81c83aa10c8d00dfc0a3d33c56db)]:
  - @tanstack/db@0.1.12

## 0.2.10

### Patch Changes

- Updated dependencies [[`b869f68`](https://github.com/TanStack/db/commit/b869f68f0109b3126509f202a38855cee38b4276)]:
  - @tanstack/db@0.1.11

## 0.2.9

### Patch Changes

- Updated dependencies [[`eb8fd18`](https://github.com/TanStack/db/commit/eb8fd18c50ee03b72cb06e4d7ef25f214367950b), [`e59a355`](https://github.com/TanStack/db/commit/e59a3551e75bac9dd166e14c911d9491e3a67b9a), [`074aab0`](https://github.com/TanStack/db/commit/074aab0477a7c55e9e0f19a705b96ed2619e2afb), [`d469c39`](https://github.com/TanStack/db/commit/d469c39a7bdc034fa4fbc533010573b3515f239f)]:
  - @tanstack/db@0.1.10

## 0.2.8

### Patch Changes

- Updated dependencies [[`d64b4a8`](https://github.com/TanStack/db/commit/d64b4a8b692a213c7ad58faaf66f5f5fd50bef66)]:
  - @tanstack/db@0.1.9

## 0.2.7

### Patch Changes

- Updated dependencies [[`1c5e206`](https://github.com/TanStack/db/commit/1c5e206d00d0a99f8419f0d00429b5a3c6cdc76e), [`4d20004`](https://github.com/TanStack/db/commit/4d2000488b9b5abf85c05801633297528af0eff6), [`968602e`](https://github.com/TanStack/db/commit/968602e4ffc597eaa559219daf22d6ef6321162a)]:
  - @tanstack/db@0.1.8

## 0.2.6

### Patch Changes

- Updated dependencies [[`48d0889`](https://github.com/TanStack/db/commit/48d088996a3f18df026aa7d2d1e7f27d1151345b), [`aecbcc3`](https://github.com/TanStack/db/commit/aecbcc32012561f1645df0bdf89a6c259058d888), [`a937f4c`](https://github.com/TanStack/db/commit/a937f4c7a5f4fc20c255e86692c5e2e80d5ebbec), [`3d60fad`](https://github.com/TanStack/db/commit/3d60fadbb9e8a1b62a9bcde947e282d653a2a270), [`79c95a3`](https://github.com/TanStack/db/commit/79c95a36f60087ffc3f9a02b76975c8bdf40acc7)]:
  - @tanstack/db@0.1.7

## 0.2.5

### Patch Changes

- Updated dependencies [[`ad33e9e`](https://github.com/TanStack/db/commit/ad33e9e535ca6197c2e00e2dbb59bf8e8f9bb51e)]:
  - @tanstack/db@0.1.6

## 0.2.4

### Patch Changes

- Add type inference of the collection type from the query collection config `queryFn` return type ([#403](https://github.com/TanStack/db/pull/403))

- Updated dependencies [[`9a5a20c`](https://github.com/TanStack/db/commit/9a5a20c21fbf8286ab90e1db6d6f3315f8344a4e)]:
  - @tanstack/db@0.1.5

## 0.2.3

### Patch Changes

- Updated dependencies [[`c90b4d8`](https://github.com/TanStack/db/commit/c90b4d85822f94f7fe72286d5c7ee07b087d0e20), [`6c1c19c`](https://github.com/TanStack/db/commit/6c1c19cedbc1d9d98396948e8e43fa0515bb8919), [`69a6d2d`](https://github.com/TanStack/db/commit/69a6d2d94c7a5510568c8b652356c62bd2b3cc76), [`6250a92`](https://github.com/TanStack/db/commit/6250a92c8045ef2fd69c107a94e05179471681d7), [`68538b4`](https://github.com/TanStack/db/commit/68538b4c446abeb992e24964f811c8900749f141)]:
  - @tanstack/db@0.1.4

## 0.2.2

### Patch Changes

- Updated dependencies [[`0cb7699`](https://github.com/TanStack/db/commit/0cb76999e5d6df5916694a5afeb31b928eab68e4)]:
  - @tanstack/db@0.1.3

## 0.2.1

### Patch Changes

- Ensure that you can use optional properties in the `select` and `join` clauses of a query, and fix an issue where standard schemas were not properly carried through to live queries. ([#377](https://github.com/TanStack/db/pull/377))

- Updated dependencies [[`bb5d50e`](https://github.com/TanStack/db/commit/bb5d50e255d9114ef32b8f52eef6b15399255327), [`97b595e`](https://github.com/TanStack/db/commit/97b595e9617b1abb05c14489e3d608b314da08e8)]:
  - @tanstack/db@0.1.2

## 0.2.0

### Minor Changes

- Improve writeBatch API to use callback pattern ([#378](https://github.com/TanStack/db/pull/378))
  - Changed `writeBatch` from accepting an array of operations to accepting a callback function
  - Write operations called within the callback are automatically batched together
  - This provides a more intuitive API similar to database transactions
  - Added comprehensive documentation for Query Collections including direct writes feature

## 0.1.3

### Patch Changes

- Add meta support to QueryCollectionConfig to allow passing additional context to queryFn. ([#363](https://github.com/TanStack/db/pull/363))

- Updated dependencies [[`bc2f204`](https://github.com/TanStack/db/commit/bc2f204b8cb8a4870ade00757d10f846524e2090), [`bda3f24`](https://github.com/TanStack/db/commit/bda3f24cc41504f60be0c5e071698b7735f75e28)]:
  - @tanstack/db@0.1.1

## 0.1.2

### Patch Changes

- Move @tanstack/query-core from dependencies to peerDependencies to avoid version conflicts when users already have react-query or query-core installed. This is a non-breaking change as the package will continue to work with any 5.x version of query-core. ([#351](https://github.com/TanStack/db/pull/351))

## 0.1.1

### Patch Changes

- Add manual write methods to QueryCollectionUtils interface to enable direct state updates from external sources. Introduces writeInsert, writeUpdate, writeDelete, writeUpsert, and writeBatch methods that bypass the normal optimistic update flow for WebSocket/real-time scenarios. All methods include proper transaction handling, data validation, and automatic query cache synchronization. ([#303](https://github.com/TanStack/db/pull/303))

## 0.1.0

### Minor Changes

- 0.1 release - first beta 🎉 ([#332](https://github.com/TanStack/db/pull/332))

### Patch Changes

- Updated dependencies [[`7d2f4be`](https://github.com/TanStack/db/commit/7d2f4be95c43aad29fb61e80e5a04c58c859322b), [`f0eda36`](https://github.com/TanStack/db/commit/f0eda36cb36350399bc8835686a6c4b6ad297e45)]:
  - @tanstack/db@0.1.0

## 0.0.15

### Patch Changes

- Updated dependencies [[`6e8d7f6`](https://github.com/TanStack/db/commit/6e8d7f660050118e050d575913733e469e3daa8c)]:
  - @tanstack/db@0.0.33

## 0.0.14

### Patch Changes

- Fix LiveQueryCollection hanging when source collections have no data ([#309](https://github.com/TanStack/db/pull/309))

  Fixed an issue where `LiveQueryCollection.preload()` would hang indefinitely when source collections call `markReady()` without data changes (e.g., when queryFn returns empty array).

  The fix implements a proper event-based solution:
  - Collections now emit empty change events when becoming ready with no data
  - WHERE clause filtered subscriptions now correctly pass through empty ready signals
  - Both regular and WHERE clause optimized LiveQueryCollections now work correctly with empty source collections

- Updated dependencies [[`e04bd12`](https://github.com/TanStack/db/commit/e04bd1252f612d4638104368d17cb644cc85295b)]:
  - @tanstack/db@0.0.32

## 0.0.13

### Patch Changes

- Updated dependencies [[`3e9a36d`](https://github.com/TanStack/db/commit/3e9a36d2600c4f700ca7bc4f720c189a5a29387a)]:
  - @tanstack/db@0.0.31

## 0.0.12

### Patch Changes

- Updated dependencies [[`6bdde55`](https://github.com/TanStack/db/commit/6bdde554f36f54c0c4f4dacb74bef5da45811855)]:
  - @tanstack/db@0.0.30

## 0.0.11

### Patch Changes

- feat: Replace string-based errors with named error classes for better error handling ([#297](https://github.com/TanStack/db/pull/297))

  This comprehensive update replaces all string-based error throws throughout the TanStack DB codebase with named error classes, providing better type safety and developer experience.

  ## New Features
  - **Root `TanStackDBError` class** - all errors inherit from a common base for unified error handling
  - **Named error classes** organized by package and functional area
  - **Type-safe error handling** using `instanceof` checks instead of string matching
  - **Package-specific error definitions** - each adapter has its own error classes
  - **Better IDE support** with autocomplete for error types

  ## Package Structure

  ### Core Package (`@tanstack/db`)

  Contains generic errors used across the ecosystem:
  - Collection configuration, state, and operation errors
  - Transaction lifecycle and mutation errors
  - Query building, compilation, and execution errors
  - Storage and serialization errors

  ### Adapter Packages

  Each adapter now exports its own specific error classes:
  - **`@tanstack/electric-db-collection`**: Electric-specific errors
  - **`@tanstack/trailbase-db-collection`**: TrailBase-specific errors
  - **`@tanstack/query-db-collection`**: Query collection specific errors

  ## Breaking Changes
  - Error handling code using string matching will need to be updated to use `instanceof` checks
  - Some error messages may have slight formatting changes
  - Adapter-specific errors now need to be imported from their respective packages

  ## Migration Guide

  ### Core DB Errors

  **Before:**

  ```ts
  try {
    collection.insert(data)
  } catch (error) {
    if (error.message.includes('already exists')) {
      // Handle duplicate key error
    }
  }
  ```

  **After:**

  ```ts
  import { DuplicateKeyError } from '@tanstack/db'

  try {
    collection.insert(data)
  } catch (error) {
    if (error instanceof DuplicateKeyError) {
      // Type-safe error handling
    }
  }
  ```

  ### Adapter-Specific Errors

  **Before:**

  ```ts
  // Electric collection errors were imported from @tanstack/db
  import { ElectricInsertHandlerMustReturnTxIdError } from '@tanstack/db'
  ```

  **After:**

  ```ts
  // Now import from the specific adapter package
  import { ElectricInsertHandlerMustReturnTxIdError } from '@tanstack/electric-db-collection'
  ```

  ### Unified Error Handling

  **New:**

  ```ts
  import { TanStackDBError } from '@tanstack/db'

  try {
    // Any TanStack DB operation
  } catch (error) {
    if (error instanceof TanStackDBError) {
      // Handle all TanStack DB errors uniformly
      console.log('TanStack DB error:', error.message)
    }
  }
  ```

  ## Benefits
  - **Type Safety**: All errors now have specific types that can be caught with `instanceof`
  - **Unified Error Handling**: Root `TanStackDBError` class allows catching all library errors with a single check
  - **Better Package Separation**: Each adapter manages its own error types
  - **Developer Experience**: Better IDE support with autocomplete for error types
  - **Maintainability**: Error definitions are co-located with their usage
  - **Consistency**: Uniform error handling patterns across the entire codebase

  All error classes maintain the same error messages and behavior while providing better structure and package separation.

- Updated dependencies [[`ced0657`](https://github.com/TanStack/db/commit/ced0657e72646e35343dfea8389d96e213710cdf), [`dcfef51`](https://github.com/TanStack/db/commit/dcfef51d4d94c756bf77e40e7015e47b7982c09a), [`360b0df`](https://github.com/TanStack/db/commit/360b0dfa411ba9f8a93f6b737aa1df8fb37dd036), [`608be0c`](https://github.com/TanStack/db/commit/608be0c14dc5ae9577deebf436557a1eace46733), [`5260ee3`](https://github.com/TanStack/db/commit/5260ee3098d12eccc58a5cf903ea479908681402)]:
  - @tanstack/db@0.0.29

## 0.0.10

### Patch Changes

- Updated dependencies [[`bb85522`](https://github.com/TanStack/db/commit/bb8552210a97dd05d3ca6fdd080a3fd25c1023a6), [`e9e8e5e`](https://github.com/TanStack/db/commit/e9e8e5e20c23fb7f98865d6b8aab05ad5322e5f7)]:
  - @tanstack/db@0.0.28

## 0.0.9

### Patch Changes

- Updated dependencies [[`bec8620`](https://github.com/TanStack/db/commit/bec862004deef5fdd560f70107ebd59f7c27656e)]:
  - @tanstack/db@0.0.27

## 0.0.8

### Patch Changes

- Add initial release of TrailBase collection for TanStack DB. TrailBase is a blazingly fast, open-source alternative to Firebase built on Rust, SQLite, and V8. It provides type-safe REST and realtime APIs with sub-millisecond latencies, integrated authentication, and flexible access control - all in a single executable. This collection type enables seamless integration with TrailBase backends for high-performance real-time applications. ([#228](https://github.com/TanStack/db/pull/228))

- Updated dependencies [[`09c6995`](https://github.com/TanStack/db/commit/09c6995ea9c8e6979d077ca63cbdd6215054ae78)]:
  - @tanstack/db@0.0.26

## 0.0.7

### Patch Changes

- Add explicit collection readiness detection with `isReady()` and `markReady()` ([#270](https://github.com/TanStack/db/pull/270))
  - Add `isReady()` method to check if a collection is ready for use
  - Add `onFirstReady()` method to register callbacks for when collection becomes ready
  - Add `markReady()` to SyncConfig interface for sync implementations to explicitly signal readiness
  - Replace `onFirstCommit()` with `onFirstReady()` for better semantics
  - Update status state machine to allow `loading` → `ready` transition for cases with no data to commit
  - Update all sync implementations (Electric, Query, Local-only, Local-storage) to use `markReady()`
  - Improve error handling by allowing collections to be marked ready even when sync errors occur

  This provides a more intuitive and ergonomic API for determining collection readiness, replacing the previous approach of using commits as a readiness signal.

- Updated dependencies [[`1758eda`](https://github.com/TanStack/db/commit/1758edab9608383d9d1470156021ee632f043e51), [`20f810e`](https://github.com/TanStack/db/commit/20f810e13a7d802bf56da6f0df89b34312ebb2fd)]:
  - @tanstack/db@0.0.25

## 0.0.6

### Patch Changes

- Updated dependencies [[`11215d9`](https://github.com/TanStack/db/commit/11215d9544d02e9dc6258c661ba4b5e439e479ed), [`fe42591`](https://github.com/TanStack/db/commit/fe42591bd7ea9955d67ecec4471b44cb7808e74b), [`665efe6`](https://github.com/TanStack/db/commit/665efe660c1aed68139326a2a33904968622a882)]:
  - @tanstack/db@0.0.24

## 0.0.5

### Patch Changes

- Updated dependencies [[`056609e`](https://github.com/TanStack/db/commit/056609ed2926e12df5ee08be5fad0a6333e787f3)]:
  - @tanstack/db@0.0.23

## 0.0.4

### Patch Changes

- Updated dependencies [[`aeee9a1`](https://github.com/TanStack/db/commit/aeee9a13411527bd0ebfc0a0c06989bdb904b650)]:
  - @tanstack/db@0.0.22

## 0.0.3

### Patch Changes

- Move Collections to their own packages ([#252](https://github.com/TanStack/db/pull/252))
  - Move local-only and local-storage collections to main `@tanstack/db` package
  - Create new `@tanstack/electric-db-collection` package for ElectricSQL integration
  - Create new `@tanstack/query-db-collection` package for TanStack Query integration
  - Delete `@tanstack/db-collections` package (removed from repo)
  - Update example app and documentation to use new package structure

  Why?
  - Better separation of concerns
  - Independent versioning for each collection type
  - Cleaner dependencies (electric collections don't need query deps, etc.)
  - Easier to add more collection types moving forward

- Updated dependencies [[`8e23322`](https://github.com/TanStack/db/commit/8e233229b25eabed07cdaf12948ba913786bf4f9)]:
  - @tanstack/db@0.0.21


## Links discovered
- [#960](https://github.com/TanStack/db/pull/960)
- [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0)
- [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435)
- [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)
- [#967](https://github.com/TanStack/db/pull/967)
- [#952](https://github.com/TanStack/db/pull/952)
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [#869](https://github.com/TanStack/db/pull/869)
- [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)
- [#870](https://github.com/TanStack/db/pull/870)
- [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)
- [#857](https://github.com/TanStack/db/pull/857)
- [#879](https://github.com/TanStack/db/pull/879)
- [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938)
- [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe)
- [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116)
- [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)
- [#800](https://github.com/TanStack/db/pull/800)
- [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9)
- [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)
- [#840](https://github.com/TanStack/db/pull/840)
- [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [#763](https://github.com/TanStack/db/pull/763)
- [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)
- [#742](https://github.com/TanStack/db/pull/742)
- [#766](https://github.com/TanStack/db/pull/766)
- [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45)
- [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a)
- [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)
- [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)
- [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9)
- [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)
- [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)
- [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110)
- [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b)
- [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)
- [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)
- [#552](https://github.com/TanStack/db/pull/552)
- [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)
- [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)
- [#707](https://github.com/TanStack/db/pull/707)
- [#708](https://github.com/TanStack/db/pull/708)
- [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477)
- [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)
- [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)
- [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a)
- [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)
- [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47)
- [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13)
- [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)
- [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450)
- [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)
- [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)
- [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113)
- [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)
- [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)
- [#635](https://github.com/TanStack/db/pull/635)
- [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888)
- [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd)
- [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627)
- [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c)
- [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)
- [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)
- [#462](https://github.com/TanStack/db/pull/462)
- [#551](https://github.com/TanStack/db/pull/551)
- [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a)
- [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534)
- [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b)
- [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)
- [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)
- [#560](https://github.com/TanStack/db/pull/560)
- [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f)
- [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)
- [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)
- [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc)
- [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)
- [#530](https://github.com/TanStack/db/pull/530)
- [#531](https://github.com/TanStack/db/pull/531)
- [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5)
- [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)
- [#441](https://github.com/TanStack/db/pull/441)
- [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256)
- [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)
- [[`b162556`](https://github.com/TanStack/db/commit/b1625565df44b0824501297f7ef14ae1cd450b49)
- [[`33515c6`](https://github.com/TanStack/db/commit/33515c69befc557add2cf828354ee378100f3977)
- [[`620ebea`](https://github.com/TanStack/db/commit/620ebea96eb3fbeec66701b949de9920c4084c17)
- [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6)
- [`bafeaa1`](https://github.com/TanStack/db/commit/bafeaa1e9f161ac2200ce86537e442b2aa8e2a5b)
- [`1814f8c`](https://github.com/TanStack/db/commit/1814f8cc3c0e831c82f8053b86fbbbd737e4f34b)
- [`31acdf2`](https://github.com/TanStack/db/commit/31acdf2a96411da327f93f0d30fa78d884422969)
- [`e41ed7e`](https://github.com/TanStack/db/commit/e41ed7e1ff1d94dd3ce0c48b6321f66b8ea044fd)
- [`51954d8`](https://github.com/TanStack/db/commit/51954d8c5d64291d136159bce293e0ad00a19f88)

--- packages/react-db/CHANGELOG.md ---
# @tanstack/react-db

## 0.1.56

### Patch Changes

- Updated dependencies [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0), [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435), [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)]:
  - @tanstack/db@0.5.12

## 0.1.55

### Patch Changes

- Fixed `isReady` to return `true` for disabled queries in `useLiveQuery`/`injectLiveQuery` across all framework packages. When a query function returns `null` or `undefined` (disabling the query), there's no async operation to wait for, so the hook should be considered "ready" immediately. ([#886](https://github.com/TanStack/db/pull/886))

  Additionally, all frameworks now have proper TypeScript overloads that explicitly support returning `undefined | null` from query functions, making the disabled query pattern type-safe.

  This fixes the common pattern where users conditionally enable queries and don't want to show loading states when the query is disabled.

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)]:
  - @tanstack/db@0.5.11

## 0.1.54

### Patch Changes

- Updated dependencies [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd), [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)]:
  - @tanstack/db@0.5.10

## 0.1.53

### Patch Changes

- Updated dependencies [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)]:
  - @tanstack/db@0.5.9

## 0.1.52

### Patch Changes

- Updated dependencies [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60), [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)]:
  - @tanstack/db@0.5.8

## 0.1.51

### Patch Changes

- Updated dependencies [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)]:
  - @tanstack/db@0.5.7

## 0.1.50

### Patch Changes

- Updated dependencies [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)]:
  - @tanstack/db@0.5.6

## 0.1.49

### Patch Changes

- Updated dependencies [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)]:
  - @tanstack/db@0.5.5

## 0.1.48

### Patch Changes

- Updated dependencies [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938), [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe), [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116), [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)]:
  - @tanstack/db@0.5.4

## 0.1.47

### Patch Changes

- Updated dependencies [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9), [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)]:
  - @tanstack/db@0.5.3

## 0.1.46

### Patch Changes

- Updated dependencies [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)]:
  - @tanstack/db@0.5.2

## 0.1.45

### Patch Changes

- Updated dependencies [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)]:
  - @tanstack/db@0.5.1

## 0.1.44

### Patch Changes

- Updated dependencies [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/db@0.5.0

## 0.1.43

### Patch Changes

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20

## 0.1.42

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19

## 0.1.41

### Patch Changes

- Add `useLiveSuspenseQuery` hook for React Suspense support ([#697](https://github.com/TanStack/db/pull/697))

  Introduces a new `useLiveSuspenseQuery` hook that integrates with React Suspense and Error Boundaries, following TanStack Query's `useSuspenseQuery` pattern.

  **Key features:**
  - React 18+ compatible using the throw promise pattern
  - Type-safe API with guaranteed data (never undefined)
  - Automatic error handling via Error Boundaries
  - Reactive updates after initial load via useSyncExternalStore
  - Support for dependency-based re-suspension
  - Works with query functions, config objects, and pre-created collections

  **Example usage:**

  ```tsx
  import { Suspense } from 'react'
  import { useLiveSuspenseQuery } from '@tanstack/react-db'

  function TodoList() {
    // Data is guaranteed to be defined - no isLoading needed
    const { data } = useLiveSuspenseQuery((q) =>
      q
        .from({ todos: todosCollection })
        .where(({ todos }) => eq(todos.completed, false)),
    )

    return (
      <ul>
        {data.map((todo) => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>
    )
  }

  function App() {
    return (
      <Suspense fallback={<div>Loading...</div>}>
        <TodoList />
      </Suspense>
    )
  }
  ```

  **Implementation details:**
  - Throws promises when collection is loading (caught by Suspense)
  - Throws errors when collection fails (caught by Error Boundary)
  - Reuses promise across re-renders to prevent infinite loops
  - Detects dependency changes and creates new collection/promise
  - Same TypeScript overloads as useLiveQuery for consistency

  **Documentation:**
  - Comprehensive guide in live-queries.md covering usage patterns and when to use each hook
  - Comparison with useLiveQuery showing different approaches to loading/error states
  - Router loader pattern recommendation for React Router/TanStack Router users
  - Error handling examples with Suspense and Error Boundaries

  Resolves #692

## 0.1.40

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18

## 0.1.39

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17

## 0.1.38

### Patch Changes

- Add paced mutations with pluggable timing strategies ([#704](https://github.com/TanStack/db/pull/704))

  Introduces a new paced mutations system that enables optimistic mutations with pluggable timing strategies. This provides fine-grained control over when and how mutations are persisted to the backend. Powered by [TanStack Pacer](https://github.com/TanStack/pacer).

  **Key Design:**
  - **Debounce/Throttle**: Only one pending transaction (collecting mutations) and one persisting transaction (writing to backend) at a time. Multiple rapid mutations automatically merge together.
  - **Queue**: Each mutation creates a separate transaction, guaranteed to run in the order they're made (FIFO by default, configurable to LIFO).

  **Core Features:**
  - **Pluggable Strategy System**: Choose from debounce, queue, or throttle strategies to control mutation timing
  - **Auto-merging Mutations**: Multiple rapid mutations on the same item automatically merge for efficiency (debounce/throttle only)
  - **Transaction Management**: Full transaction lifecycle tracking (pending → persisting → completed/failed)
  - **React Hook**: `usePacedMutations` for easy integration in React applications

  **Available Strategies:**
  - `debounceStrategy`: Wait for inactivity before persisting. Only final state is saved. (ideal for auto-save, search-as-you-type)
  - `queueStrategy`: Each mutation becomes a separate transaction, processed sequentially in order (defaults to FIFO, configurable to LIFO). All mutations are guaranteed to persist. (ideal for sequential workflows, rate-limited APIs)
  - `throttleStrategy`: Ensure minimum spacing between executions. Mutations between executions are merged. (ideal for analytics, progress updates)

  **Example Usage:**

  ```ts
  import { usePacedMutations, debounceStrategy } from '@tanstack/react-db'

  const mutate = usePacedMutations({
    mutationFn: async ({ transaction }) => {
      await api.save(transaction.mutations)
    },
    strategy: debounceStrategy({ wait: 500 }),
  })

  // Trigger a mutation
  const tx = mutate(() => {
    collection.update(id, (draft) => {
      draft.value = newValue
    })
  })

  // Optionally await persistence
  await tx.isPersisted.promise
  ```

- Updated dependencies [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110), [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b), [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)]:
  - @tanstack/db@0.4.16

## 0.1.37

### Patch Changes

- Updated dependencies [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)]:
  - @tanstack/db@0.4.15

## 0.1.36

### Patch Changes

- Updated dependencies [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)]:
  - @tanstack/db@0.4.14

## 0.1.35

### Patch Changes

- Updated dependencies [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)]:
  - @tanstack/db@0.4.13

## 0.1.34

### Patch Changes

- Updated dependencies [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477), [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)]:
  - @tanstack/db@0.4.12

## 0.1.33

### Patch Changes

- Add support for pre-created live query collections in useLiveInfiniteQuery, enabling router loader patterns where live queries can be created, preloaded, and passed to components. ([#684](https://github.com/TanStack/db/pull/684))

- Updated dependencies [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)]:
  - @tanstack/db@0.4.11

## 0.1.32

### Patch Changes

- Add `useLiveInfiniteQuery` hook for infinite scrolling with live updates. ([#669](https://github.com/TanStack/db/pull/669))

  The new `useLiveInfiniteQuery` hook provides an infinite query pattern similar to TanStack Query's `useInfiniteQuery`, but with live updates from your local collection. It uses `liveQueryCollection.utils.setWindow()` internally to efficiently paginate through ordered data without recreating the query on each page fetch.

  **Key features:**
  - Automatic live updates as data changes in the collection
  - Efficient pagination using dynamic window adjustment
  - Peek-ahead mechanism to detect when more pages are available
  - Compatible with TanStack Query's infinite query API patterns

  **Example usage:**

  ```tsx
  import { useLiveInfiniteQuery } from '@tanstack/react-db'

  function PostList() {
    const { data, pages, fetchNextPage, hasNextPage, isLoading } =
      useLiveInfiniteQuery(
        (q) =>
          q
            .from({ posts: postsCollection })
            .orderBy(({ posts }) => posts.createdAt, 'desc'),
        {
          pageSize: 20,
          getNextPageParam: (lastPage, allPages) =>
            lastPage.length === 20 ? allPages.length : undefined,
        },
      )

    if (isLoading) return <div>Loading...</div>

    return (
      <div>
        {pages.map((page, i) => (
          <div key={i}>
            {page.map((post) => (
              <PostCard key={post.id} post={post} />
            ))}
          </div>
        ))}
        {hasNextPage && (
          <button onClick={() => fetchNextPage()}>Load More</button>
        )}
      </div>
    )
  }
  ```

  **Requirements:**
  - Query must include `.orderBy()` for the window mechanism to work
  - Returns flattened `data` array and `pages` array for flexible rendering
  - Automatically detects new pages when data is synced to the collection

- Updated dependencies [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a), [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)]:
  - @tanstack/db@0.4.10

## 0.1.31

### Patch Changes

- Updated dependencies [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47), [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13), [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)]:
  - @tanstack/db@0.4.9

## 0.1.30

### Patch Changes

- Refactored live queries to execute eagerly during sync. Live queries now materialize their results immediately as data arrives from source collections, even while those collections are still in a "loading" state, rather than waiting for all sources to be "ready" before executing. ([#658](https://github.com/TanStack/db/pull/658))

- Updated dependencies [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450), [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)]:
  - @tanstack/db@0.4.8

## 0.1.29

### Patch Changes

- Updated dependencies [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)]:
  - @tanstack/db@0.4.7

## 0.1.28

### Patch Changes

- Updated dependencies [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113), [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)]:
  - @tanstack/db@0.4.6

## 0.1.27

### Patch Changes

- Updated dependencies [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)]:
  - @tanstack/db@0.4.5

## 0.1.26

### Patch Changes

- Updated dependencies [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888), [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd), [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627), [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c), [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)]:
  - @tanstack/db@0.4.4

## 0.1.25

### Patch Changes

- Updated dependencies [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)]:
  - @tanstack/db@0.4.3

## 0.1.24

### Patch Changes

- Updated dependencies [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a), [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534), [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b), [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)]:
  - @tanstack/db@0.4.2

## 0.1.23

### Patch Changes

- Updated dependencies [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)]:
  - @tanstack/db@0.4.1

## 0.1.22

### Patch Changes

- Let collection.subscribeChanges return a subscription object. Move all data loading code related to optimizations into that subscription object. ([#564](https://github.com/TanStack/db/pull/564))

- Updated dependencies [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58), [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f), [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)]:
  - @tanstack/db@0.4.0

## 0.1.21

### Patch Changes

- Expand `useLiveQuery` callback to support conditional queries and additional return types, enabling the ability to temporarily disable the query. ([#535](https://github.com/TanStack/db/pull/535))

  **New Features:**
  - Callback can now return `undefined` or `null` to temporarily disable the query
  - Callback can return a pre-created `Collection` instance to use it directly
  - Callback can return a `LiveQueryCollectionConfig` object for advanced configuration
  - When disabled (returning `undefined`/`null`), the hook returns a specific idle state

  **Usage Examples:**

  ```ts
  // Conditional queries - disable when not ready
  const enabled = useState(false)
  const { data, state, isIdle } = useLiveQuery((q) => {
    if (!enabled) return undefined  // Disables the query
    return q.from({ users }).where(...)
  }, [enabled])

  /**
   * When disabled, returns:
   * {
   *   state: undefined,
   *   data: undefined,
   *   isIdle: true,
   *   ...
   * }
   */

  // Return pre-created Collection
  const { data } = useLiveQuery((q) => {
    if (usePrebuilt) return myCollection  // Use existing collection
    return q.from({ items }).select(...)
  }, [usePrebuilt])

  // Return LiveQueryCollectionConfig
  const { data } = useLiveQuery((q) => {
    return {
      query: q.from({ items }).select(...),
      id: `my-collection`,
    }
  })
  ```

- Updated dependencies [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)]:
  - @tanstack/db@0.3.2

## 0.1.20

### Patch Changes

- Updated dependencies [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)]:
  - @tanstack/db@0.3.1

## 0.1.19

### Patch Changes

- Updated dependencies [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc), [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)]:
  - @tanstack/db@0.3.0

## 0.1.18

### Patch Changes

- Updated dependencies [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5), [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)]:
  - @tanstack/db@0.2.5

## 0.1.17

### Patch Changes

- Updated dependencies [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256), [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)]:
  - @tanstack/db@0.2.4

## 0.1.16

### Patch Changes

- Updated dependencies [[`b162556`](https://github.com/TanStack/db/commit/b1625565df44b0824501297f7ef14ae1cd450b49)]:
  - @tanstack/db@0.2.3

## 0.1.15

### Patch Changes

- Updated dependencies [[`33515c6`](https://github.com/TanStack/db/commit/33515c69befc557add2cf828354ee378100f3977)]:
  - @tanstack/db@0.2.2

## 0.1.14

### Patch Changes

- Updated dependencies [[`620ebea`](https://github.com/TanStack/db/commit/620ebea96eb3fbeec66701b949de9920c4084c17)]:
  - @tanstack/db@0.2.1

## 0.1.13

### Patch Changes

- Updated dependencies [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6), [`bafeaa1`](https://github.com/TanStack/db/commit/bafeaa1e9f161ac2200ce86537e442b2aa8e2a5b), [`1814f8c`](https://github.com/TanStack/db/commit/1814f8cc3c0e831c82f8053b86fbbbd737e4f34b), [`31acdf2`](https://github.com/TanStack/db/commit/31acdf2a96411da327f93f0d30fa78d884422969), [`e41ed7e`](https://github.com/TanStack/db/commit/e41ed7e1ff1d94dd3ce0c48b6321f66b8ea044fd), [`51954d8`](https://github.com/TanStack/db/commit/51954d8c5d64291d136159bce293e0ad00a19f88)]:
  - @tanstack/db@0.2.0

## 0.1.12

### Patch Changes

- Updated dependencies [[`cc4c34a`](https://github.com/TanStack/db/commit/cc4c34a6b40c81c83aa10c8d00dfc0a3d33c56db)]:
  - @tanstack/db@0.1.12

## 0.1.11

### Patch Changes

- Fixed a bug where a race condition could cause initial results not to be rendered when using `useLiveQuery`. ([#485](https://github.com/TanStack/db/pull/485))

- Updated dependencies [[`b869f68`](https://github.com/TanStack/db/commit/b869f68f0109b3126509f202a38855cee38b4276)]:
  - @tanstack/db@0.1.11

## 0.1.10

### Patch Changes

- Updated dependencies [[`eb8fd18`](https://github.com/TanStack/db/commit/eb8fd18c50ee03b72cb06e4d7ef25f214367950b), [`e59a355`](https://github.com/TanStack/db/commit/e59a3551e75bac9dd166e14c911d9491e3a67b9a), [`074aab0`](https://github.com/TanStack/db/commit/074aab0477a7c55e9e0f19a705b96ed2619e2afb), [`d469c39`](https://github.com/TanStack/db/commit/d469c39a7bdc034fa4fbc533010573b3515f239f)]:
  - @tanstack/db@0.1.10

## 0.1.9

### Patch Changes

- Updated dependencies [[`d64b4a8`](https://github.com/TanStack/db/commit/d64b4a8b692a213c7ad58faaf66f5f5fd50bef66)]:
  - @tanstack/db@0.1.9

## 0.1.8

### Patch Changes

- Updated dependencies [[`1c5e206`](https://github.com/TanStack/db/commit/1c5e206d00d0a99f8419f0d00429b5a3c6cdc76e), [`4d20004`](https://github.com/TanStack/db/commit/4d2000488b9b5abf85c05801633297528af0eff6), [`968602e`](https://github.com/TanStack/db/commit/968602e4ffc597eaa559219daf22d6ef6321162a)]:
  - @tanstack/db@0.1.8

## 0.1.7

### Patch Changes

- Updated dependencies [[`48d0889`](https://github.com/TanStack/db/commit/48d088996a3f18df026aa7d2d1e7f27d1151345b), [`aecbcc3`](https://github.com/TanStack/db/commit/aecbcc32012561f1645df0bdf89a6c259058d888), [`a937f4c`](https://github.com/TanStack/db/commit/a937f4c7a5f4fc20c255e86692c5e2e80d5ebbec), [`3d60fad`](https://github.com/TanStack/db/commit/3d60fadbb9e8a1b62a9bcde947e282d653a2a270), [`79c95a3`](https://github.com/TanStack/db/commit/79c95a36f60087ffc3f9a02b76975c8bdf40acc7)]:
  - @tanstack/db@0.1.7

## 0.1.6

### Patch Changes

- Updated dependencies [[`ad33e9e`](https://github.com/TanStack/db/commit/ad33e9e535ca6197c2e00e2dbb59bf8e8f9bb51e)]:
  - @tanstack/db@0.1.6

## 0.1.5

### Patch Changes

- ensure that useLiveQuery returns a stable ref when there are no changes ([#388](https://github.com/TanStack/db/pull/388))

- Updated dependencies [[`9a5a20c`](https://github.com/TanStack/db/commit/9a5a20c21fbf8286ab90e1db6d6f3315f8344a4e)]:
  - @tanstack/db@0.1.5

## 0.1.4

### Patch Changes

- Ensure that the ready status is correctly returned from a live query ([#390](https://github.com/TanStack/db/pull/390))

- Updated dependencies [[`c90b4d8`](https://github.com/TanStack/db/commit/c90b4d85822f94f7fe72286d5c7ee07b087d0e20), [`6c1c19c`](https://github.com/TanStack/db/commit/6c1c19cedbc1d9d98396948e8e43fa0515bb8919), [`69a6d2d`](https://github.com/TanStack/db/commit/69a6d2d94c7a5510568c8b652356c62bd2b3cc76), [`6250a92`](https://github.com/TanStack/db/commit/6250a92c8045ef2fd69c107a94e05179471681d7), [`68538b4`](https://github.com/TanStack/db/commit/68538b4c446abeb992e24964f811c8900749f141)]:
  - @tanstack/db@0.1.4

## 0.1.3

### Patch Changes

- Updated dependencies [[`0cb7699`](https://github.com/TanStack/db/commit/0cb76999e5d6df5916694a5afeb31b928eab68e4)]:
  - @tanstack/db@0.1.3

## 0.1.2

### Patch Changes

- Updated dependencies [[`bb5d50e`](https://github.com/TanStack/db/commit/bb5d50e255d9114ef32b8f52eef6b15399255327), [`97b595e`](https://github.com/TanStack/db/commit/97b595e9617b1abb05c14489e3d608b314da08e8)]:
  - @tanstack/db@0.1.2

## 0.1.1

### Patch Changes

- Updated dependencies [[`bc2f204`](https://github.com/TanStack/db/commit/bc2f204b8cb8a4870ade00757d10f846524e2090), [`bda3f24`](https://github.com/TanStack/db/commit/bda3f24cc41504f60be0c5e071698b7735f75e28)]:
  - @tanstack/db@0.1.1

## 0.1.0

### Minor Changes

- 0.1 release - first beta 🎉 ([#332](https://github.com/TanStack/db/pull/332))

### Patch Changes

- We have moved development of the differential dataflow implementation from @electric-sql/d2mini to a new @tanstack/db-ivm package inside the tanstack db monorepo to make development simpler. ([#330](https://github.com/TanStack/db/pull/330))

- Updated dependencies [[`7d2f4be`](https://github.com/TanStack/db/commit/7d2f4be95c43aad29fb61e80e5a04c58c859322b), [`f0eda36`](https://github.com/TanStack/db/commit/f0eda36cb36350399bc8835686a6c4b6ad297e45)]:
  - @tanstack/db@0.1.0

## 0.0.33

### Patch Changes

- Updated dependencies [[`6e8d7f6`](https://github.com/TanStack/db/commit/6e8d7f660050118e050d575913733e469e3daa8c)]:
  - @tanstack/db@0.0.33

## 0.0.32

### Patch Changes

- Updated dependencies [[`e04bd12`](https://github.com/TanStack/db/commit/e04bd1252f612d4638104368d17cb644cc85295b)]:
  - @tanstack/db@0.0.32

## 0.0.31

### Patch Changes

- Updated dependencies [[`3e9a36d`](https://github.com/TanStack/db/commit/3e9a36d2600c4f700ca7bc4f720c189a5a29387a)]:
  - @tanstack/db@0.0.31

## 0.0.30

### Patch Changes

- Updated dependencies [[`6bdde55`](https://github.com/TanStack/db/commit/6bdde554f36f54c0c4f4dacb74bef5da45811855)]:
  - @tanstack/db@0.0.30

## 0.0.29

### Patch Changes

- Updated dependencies [[`ced0657`](https://github.com/TanStack/db/commit/ced0657e72646e35343dfea8389d96e213710cdf), [`dcfef51`](https://github.com/TanStack/db/commit/dcfef51d4d94c756bf77e40e7015e47b7982c09a), [`360b0df`](https://github.com/TanStack/db/commit/360b0dfa411ba9f8a93f6b737aa1df8fb37dd036), [`608be0c`](https://github.com/TanStack/db/commit/608be0c14dc5ae9577deebf436557a1eace46733), [`5260ee3`](https://github.com/TanStack/db/commit/5260ee3098d12eccc58a5cf903ea479908681402)]:
  - @tanstack/db@0.0.29

## 0.0.28

### Patch Changes

- Updated dependencies [[`bb85522`](https://github.com/TanStack/db/commit/bb8552210a97dd05d3ca6fdd080a3fd25c1023a6), [`e9e8e5e`](https://github.com/TanStack/db/commit/e9e8e5e20c23fb7f98865d6b8aab05ad5322e5f7)]:
  - @tanstack/db@0.0.28

## 0.0.27

### Patch Changes

- Updated dependencies [[`bec8620`](https://github.com/TanStack/db/commit/bec862004deef5fdd560f70107ebd59f7c27656e)]:
  - @tanstack/db@0.0.27

## 0.0.26

### Patch Changes

- Add initial release of TrailBase collection for TanStack DB. TrailBase is a blazingly fast, open-source alternative to Firebase built on Rust, SQLite, and V8. It provides type-safe REST and realtime APIs with sub-millisecond latencies, integrated authentication, and flexible access control - all in a single executable. This collection type enables seamless integration with TrailBase backends for high-performance real-time applications. ([#228](https://github.com/TanStack/db/pull/228))

- Updated dependencies [[`09c6995`](https://github.com/TanStack/db/commit/09c6995ea9c8e6979d077ca63cbdd6215054ae78)]:
  - @tanstack/db@0.0.26

## 0.0.25

### Patch Changes

- Updated dependencies [[`1758eda`](https://github.com/TanStack/db/commit/1758edab9608383d9d1470156021ee632f043e51), [`20f810e`](https://github.com/TanStack/db/commit/20f810e13a7d802bf56da6f0df89b34312ebb2fd)]:
  - @tanstack/db@0.0.25

## 0.0.24

### Patch Changes

- Updated dependencies [[`11215d9`](https://github.com/TanStack/db/commit/11215d9544d02e9dc6258c661ba4b5e439e479ed), [`fe42591`](https://github.com/TanStack/db/commit/fe42591bd7ea9955d67ecec4471b44cb7808e74b), [`665efe6`](https://github.com/TanStack/db/commit/665efe660c1aed68139326a2a33904968622a882)]:
  - @tanstack/db@0.0.24

## 0.0.23

### Patch Changes

- Updated dependencies [[`056609e`](https://github.com/TanStack/db/commit/056609ed2926e12df5ee08be5fad0a6333e787f3)]:
  - @tanstack/db@0.0.23

## 0.0.22

### Patch Changes

- Updated dependencies [[`aeee9a1`](https://github.com/TanStack/db/commit/aeee9a13411527bd0ebfc0a0c06989bdb904b650)]:
  - @tanstack/db@0.0.22

## 0.0.21

### Patch Changes

- Updated dependencies [[`8e23322`](https://github.com/TanStack/db/commit/8e233229b25eabed07cdaf12948ba913786bf4f9)]:
  - @tanstack/db@0.0.21

## 0.0.20

### Patch Changes

- Updated dependencies [[`f13c11e`](https://github.com/TanStack/db/commit/f13c11ed0ab27cd88b03d789b0cd953e86bd1333)]:
  - @tanstack/db@0.0.20

## 0.0.19

### Patch Changes

- Updated dependencies [[`9f0b0c2`](https://github.com/TanStack/db/commit/9f0b0c28ede99273eb5914be28aff55b91c50778)]:
  - @tanstack/db@0.0.19

## 0.0.18

### Patch Changes

- Improve jsdocs ([#243](https://github.com/TanStack/db/pull/243))

- Updated dependencies [[`266bd29`](https://github.com/TanStack/db/commit/266bd29514c6c0fa9e903986ca11c5e22f4d2361)]:
  - @tanstack/db@0.0.18

## 0.0.17

### Patch Changes

- Updated dependencies [[`7e63d76`](https://github.com/TanStack/db/commit/7e63d7671f9df9f9fc81240c3818789d4ed0d464)]:
  - @tanstack/db@0.0.17

## 0.0.16

### Patch Changes

- add support for composable queries ([#232](https://github.com/TanStack/db/pull/232))

- Updated dependencies [[`e478d53`](https://github.com/TanStack/db/commit/e478d5353cc8fc64e3a29dda1f86fba863cf6ce8)]:
  - @tanstack/db@0.0.16

## 0.0.15

### Patch Changes

- Updated dependencies [[`f5cf44b`](https://github.com/TanStack/db/commit/f5cf44b1b181afef89a80cf7b8678337a3d4a065), [`f5cf44b`](https://github.com/TanStack/db/commit/f5cf44b1b181afef89a80cf7b8678337a3d4a065)]:
  - @tanstack/db@0.0.15

## 0.0.14

### Patch Changes

- Updated dependencies [[`74c140d`](https://github.com/TanStack/db/commit/74c140d8744f1f7bd3f9cb940c75719574afc78f)]:
  - @tanstack/db@0.0.14

## 0.0.13

### Patch Changes

- feat: implement Collection Lifecycle Management ([#198](https://github.com/TanStack/db/pull/198))

  Adds automatic lifecycle management for collections to optimize resource usage.

  **New Features:**
  - Added `startSync` option (defaults to `false`, set to `true` to start syncing immediately)
  - Automatic garbage collection after `gcTime` (default 5 minutes) of inactivity
  - Collection status tracking: "idle" | "loading" | "ready" | "error" | "cleaned-up"
  - Manual `preload()` and `cleanup()` methods for lifecycle control

  **Usage:**

  ```typescript
  const collection = createCollection({
    startSync: false, // Enable lazy loading
    gcTime: 300000, // Cleanup timeout (default: 5 minutes)
  })

  console.log(collection.status) // Current state
  await collection.preload() // Ensure ready
  await collection.cleanup() // Manual cleanup
  ```

- Add createOptimisticAction helper that replaces useOptimisticMutation ([#210](https://github.com/TanStack/db/pull/210))

  An example of converting a `useOptimisticMutation` hook to `createOptimisticAction`. Now all optimistic & server mutation logic are consolidated.

  ```diff
  -import { useOptimisticMutation } from '@tanstack/react-db'
  +import { createOptimisticAction } from '@tanstack/react-db'
  +
  +// Create the `addTodo` action, passing in your `mutationFn` and `onMutate`.
  +const addTodo = createOptimisticAction<string>({
  +  onMutate: (text) => {
  +    // Instantly applies the local optimistic state.
  +    todoCollection.insert({
  +      id: uuid(),
  +      text,
  +      completed: false
  +    })
  +  },
  +  mutationFn: async (text) => {
  +    // Persist the todo to your backend
  +    const response = await fetch('/api/todos', {
  +      method: 'POST',
  +      body: JSON.stringify({ text, completed: false }),
  +    })
  +    return response.json()
  +  }
  +})

   const Todo = () => {
  -  // Create the `addTodo` mutator, passing in your `mutationFn`.
  -  const addTodo = useOptimisticMutation({ mutationFn })
  -
     const handleClick = () => {
  -    // Triggers the mutationFn
  -    addTodo.mutate(() =>
  -      // Instantly applies the local optimistic state.
  -      todoCollection.insert({
  -        id: uuid(),
  -        text: '🔥 Make app faster',
  -        completed: false
  -      })
  -    )
  +    // Triggers the onMutate and then the mutationFn
  +    addTodo('🔥 Make app faster')
     }

     return <Button onClick={ handleClick } />
   }
  ```

- Updated dependencies [[`945868e`](https://github.com/TanStack/db/commit/945868e95944543ccf5d778409548679a952e249), [`0f8a008`](https://github.com/TanStack/db/commit/0f8a008be8b368f231c8518ad1adfcac08132da2), [`57b5f5d`](https://github.com/TanStack/db/commit/57b5f5de6297326a57ef205a400428af0697b48b)]:
  - @tanstack/db@0.0.13

## 0.0.12

### Patch Changes

- Updated dependencies [[`f6abe9b`](https://github.com/TanStack/db/commit/f6abe9b94b890487fe960bd72a89e4a75de89d46)]:
  - @tanstack/db@0.0.12

## 0.0.11

### Patch Changes

- Export `ElectricCollectionUtils` & allow passing generic to `createTransaction` ([#179](https://github.com/TanStack/db/pull/179))

- Updated dependencies [[`66ed58b`](https://github.com/TanStack/db/commit/66ed58b66553683ff0a5241de8cde83954d18847), [`c5489ff`](https://github.com/TanStack/db/commit/c5489ff276db07a0a4b65876790ccd7f11a6f99d)]:
  - @tanstack/db@0.0.11

## 0.0.10

### Patch Changes

- Updated dependencies [[`38d4505`](https://github.com/TanStack/db/commit/38d45051b065b619b95849f78422e9ace8750361)]:
  - @tanstack/db@0.0.10

## 0.0.9

### Patch Changes

- Updated dependencies [[`2ae0b09`](https://github.com/TanStack/db/commit/2ae0b09cc52152b0044818b538e11e8ca10d0f80)]:
  - @tanstack/db@0.0.9

## 0.0.8

### Patch Changes

- A large refactor of the core `Collection` with: ([#155](https://github.com/TanStack/db/pull/155))
  - a change to not use Store internally and emit fine grade changes with `subscribeChanges` and `subscribeKeyChanges` methods.
  - changes to the `Collection` api to be more `Map` like for reads, with `get`, `has`, `size`, `entries`, `keys`, and `values`.
  - renames `config.getId` to `config.getKey` for consistency with the `Map` like api.

- Updated dependencies [[`5c538cf`](https://github.com/TanStack/db/commit/5c538cf03573512a8d1bbde96962a9f7ca014708), [`9553366`](https://github.com/TanStack/db/commit/955336604a286d7992f9506cb1c76ecf150d0432), [`b4602a0`](https://github.com/TanStack/db/commit/b4602a071cb6866bb1338e30d5802220b0d1fc49), [`02adc81`](https://github.com/TanStack/db/commit/02adc813177cbb44ab6245cc9821142e9cf97876), [`06d8ecc`](https://github.com/TanStack/db/commit/06d8eccc5aaabc194c31ea89c9b4191e2aa68180), [`c50cd51`](https://github.com/TanStack/db/commit/c50cd51ac8030b391cd9d84e8cd8b8fb57cb8ca5)]:
  - @tanstack/db@0.0.8

## 0.0.7

### Patch Changes

- Expose utilities on collection instances ([#161](https://github.com/TanStack/db/pull/161))

  Implemented a utility exposure pattern for TanStack DB collections that allows utility functions to be passed as part of collection options and exposes them under a `.utils` namespace, with full TypeScript typing.
  - Refactored `createCollection` in packages/db/src/collection.ts to accept options with utilities directly
  - Added `utils` property to CollectionImpl
  - Added TypeScript types for utility functions and utility records
  - Changed Collection from a class to a type, updating all usages to use createCollection() instead
  - Updated Electric/Query implementations
  - Utilities are now ergonomically accessible under `.utils`
  - Full TypeScript typing is preserved for both collection data and utilities
  - API is clean and straightforward - users can call `createCollection(optionsCreator(config))` directly
  - Zero-boilerplate TypeScript pattern that infers utility types automatically

- Updated dependencies [[`8b43ad3`](https://github.com/TanStack/db/commit/8b43ad305b277560aed660c31cf1409d22ed1e47)]:
  - @tanstack/db@0.0.7

## 0.0.6

### Patch Changes

- Updated dependencies [[`856be72`](https://github.com/TanStack/db/commit/856be725a6299374a3a97c88b50bd5d7bb94b783), [`0455e27`](https://github.com/TanStack/db/commit/0455e27f50d69b1e1887b841dc2f262f4de4c55d), [`80fdac7`](https://github.com/TanStack/db/commit/80fdac76389ea741f5743bc788df375f63fb767b)]:
  - @tanstack/db@0.0.6

## 0.0.5

### Patch Changes

- Collections must have a getId function & use an id for update/delete operators ([#134](https://github.com/TanStack/db/pull/134))

- the `keyBy` query operator has been removed, keying withing the query pipeline is now automatic ([#144](https://github.com/TanStack/db/pull/144))

- Updated dependencies [[`1fbb844`](https://github.com/TanStack/db/commit/1fbb8447d8425d37cb9ab4f078ffab999b28b06c), [`338efc2`](https://github.com/TanStack/db/commit/338efc229c3794da5ac373b8b26143e379433407), [`ee5d026`](https://github.com/TanStack/db/commit/ee5d026715962dd0232fcaca513a8fac9189dce2), [`e7b036c`](https://github.com/TanStack/db/commit/e7b036ce6ebd17c94cc944d6d96ca2c645921c3e), [`e4feb0c`](https://github.com/TanStack/db/commit/e4feb0c214835675b47f0aa18a72d004a423df03)]:
  - @tanstack/db@0.0.5

## 0.0.4

### Patch Changes

- Updated dependencies [[`8ce449e`](https://github.com/TanStack/db/commit/8ce449ed6d070e9e591d1b74b0db5fed7a3fc92f)]:
  - @tanstack/db@0.0.4

## 0.0.3

### Patch Changes

- Updated dependencies [[`b29420b`](https://github.com/TanStack/db/commit/b29420bcdae30dfeffeef63a8753b83306a54e5a)]:
  - @tanstack/db@0.0.3

## 0.0.2

### Patch Changes

- Fixed an issue with injecting the optimistic state removal into the reactive live query. ([#78](https://github.com/TanStack/db/pull/78))

- Updated dependencies [[`4c82edb`](https://github.com/TanStack/db/commit/4c82edb9547f26c9de44f5bf43d4385c38920672)]:
  - @tanstack/db@0.0.2

## 0.0.3

### Patch Changes

- Make transactions first class & move ownership of mutationFn from collections to transactions ([#53](https://github.com/TanStack/db/pull/53))

- Updated dependencies [[`b42479c`](https://github.com/TanStack/db/commit/b42479cf95f9a820b36e01684b13a9179973f3d8)]:
  - @tanstack/db@0.0.3

## 0.0.2

### Patch Changes

- make mutationFn optional for read-only collections ([#12](https://github.com/TanStack/db/pull/12))

- Updated dependencies [[`9bb6e89`](https://github.com/TanStack/db/commit/9bb6e8909cebdcd7c03091bfc12dd37f5ab2e1ea), [`8eb7e9b`](https://github.com/TanStack/db/commit/8eb7e9b1d1f569c5c064e0f440257589486b73cf)]:
  - @tanstack/db@0.0.2

## 0.0.1

### Patch Changes

- feat: Initial release ([#2](https://github.com/TanStack/db/pull/2))

- Updated dependencies [[`2d2dd77`](https://github.com/TanStack/db/commit/2d2dd7743f715ffefaeee8e8d11173b751c7043b)]:
  - @tanstack/db@0.0.1


## Links discovered
- [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0)
- [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435)
- [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)
- [#886](https://github.com/TanStack/db/pull/886)
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd)
- [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)
- [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)
- [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60)
- [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)
- [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)
- [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)
- [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)
- [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938)
- [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe)
- [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116)
- [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)
- [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9)
- [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)
- [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)
- [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)
- [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45)
- [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a)
- [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)
- [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)
- [#697](https://github.com/TanStack/db/pull/697)
- [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9)
- [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)
- [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)
- [#704](https://github.com/TanStack/db/pull/704)
- [TanStack Pacer](https://github.com/TanStack/pacer)
- [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110)
- [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b)
- [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)
- [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)
- [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)
- [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)
- [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477)
- [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)
- [#684](https://github.com/TanStack/db/pull/684)
- [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)
- [#669](https://github.com/TanStack/db/pull/669)
- [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a)
- [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)
- [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47)
- [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13)
- [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)
- [#658](https://github.com/TanStack/db/pull/658)
- [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450)
- [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)
- [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)
- [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113)
- [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)
- [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)
- [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888)
- [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd)
- [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627)
- [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c)
- [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)
- [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)
- [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a)
- [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534)
- [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b)
- [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)
- [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)
- [#564](https://github.com/TanStack/db/pull/564)
- [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f)
- [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [#535](https://github.com/TanStack/db/pull/535)
- [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)
- [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)
- [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc)
- [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)
- [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5)
- [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)
- [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256)
- [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)
- [[`b162556`](https://github.com/TanStack/db/commit/b1625565df44b0824501297f7ef14ae1cd450b49)
- [[`33515c6`](https://github.com/TanStack/db/commit/33515c69befc557add2cf828354ee378100f3977)
- [[`620ebea`](https://github.com/TanStack/db/commit/620ebea96eb3fbeec66701b949de9920c4084c17)
- [[`08303e6`](https://github.com/TanStack/db/commit/08303e645974db97e10b2aca0031abcbce027dd6)
- [`bafeaa1`](https://github.com/TanStack/db/commit/bafeaa1e9f161ac2200ce86537e442b2aa8e2a5b)
- [`1814f8c`](https://github.com/TanStack/db/commit/1814f8cc3c0e831c82f8053b86fbbbd737e4f34b)
- [`31acdf2`](https://github.com/TanStack/db/commit/31acdf2a96411da327f93f0d30fa78d884422969)
- [`e41ed7e`](https://github.com/TanStack/db/commit/e41ed7e1ff1d94dd3ce0c48b6321f66b8ea044fd)
- [`51954d8`](https://github.com/TanStack/db/commit/51954d8c5d64291d136159bce293e0ad00a19f88)
- [[`cc4c34a`](https://github.com/TanStack/db/commit/cc4c34a6b40c81c83aa10c8d00dfc0a3d33c56db)
- [#485](https://github.com/TanStack/db/pull/485)
- [[`b869f68`](https://github.com/TanStack/db/commit/b869f68f0109b3126509f202a38855cee38b4276)
- [[`eb8fd18`](https://github.com/TanStack/db/commit/eb8fd18c50ee03b72cb06e4d7ef25f214367950b)
- [`e59a355`](https://github.com/TanStack/db/commit/e59a3551e75bac9dd166e14c911d9491e3a67b9a)
- [`074aab0`](https://github.com/TanStack/db/commit/074aab0477a7c55e9e0f19a705b96ed2619e2afb)

--- packages/rxdb-db-collection/CHANGELOG.md ---
# @tanstack/rxdb-db-collection

## 0.1.44

### Patch Changes

- Updated dependencies [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0), [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435), [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)]:
  - @tanstack/db@0.5.12

## 0.1.43

### Patch Changes

- Updated dependencies [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b), [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)]:
  - @tanstack/db@0.5.11

## 0.1.42

### Patch Changes

- Updated dependencies [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd), [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)]:
  - @tanstack/db@0.5.10

## 0.1.41

### Patch Changes

- Updated dependencies [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)]:
  - @tanstack/db@0.5.9

## 0.1.40

### Patch Changes

- Updated dependencies [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60), [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)]:
  - @tanstack/db@0.5.8

## 0.1.39

### Patch Changes

- Updated dependencies [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)]:
  - @tanstack/db@0.5.7

## 0.1.38

### Patch Changes

- Updated dependencies [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)]:
  - @tanstack/db@0.5.6

## 0.1.37

### Patch Changes

- Updated dependencies [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)]:
  - @tanstack/db@0.5.5

## 0.1.36

### Patch Changes

- Updated dependencies [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938), [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe), [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116), [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)]:
  - @tanstack/db@0.5.4

## 0.1.35

### Patch Changes

- Updated dependencies [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9), [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)]:
  - @tanstack/db@0.5.3

## 0.1.34

### Patch Changes

- Updated dependencies [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)]:
  - @tanstack/db@0.5.2

## 0.1.33

### Patch Changes

- Updated dependencies [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)]:
  - @tanstack/db@0.5.1

## 0.1.32

### Patch Changes

- Updated dependencies [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d), [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34), [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb), [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9), [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)]:
  - @tanstack/db@0.5.0

## 0.1.31

### Patch Changes

- Updated dependencies [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45), [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a), [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)]:
  - @tanstack/db@0.4.20

## 0.1.30

### Patch Changes

- Updated dependencies [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)]:
  - @tanstack/db@0.4.19

## 0.1.29

### Patch Changes

- Updated dependencies [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9), [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)]:
  - @tanstack/db@0.4.18

## 0.1.28

### Patch Changes

- Updated dependencies [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)]:
  - @tanstack/db@0.4.17

## 0.1.27

### Patch Changes

- Updated dependencies [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110), [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b), [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)]:
  - @tanstack/db@0.4.16

## 0.1.26

### Patch Changes

- Updated dependencies [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)]:
  - @tanstack/db@0.4.15

## 0.1.25

### Patch Changes

- Updated dependencies [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)]:
  - @tanstack/db@0.4.14

## 0.1.24

### Patch Changes

- Updated dependencies [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)]:
  - @tanstack/db@0.4.13

## 0.1.23

### Patch Changes

- Updated dependencies [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477), [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)]:
  - @tanstack/db@0.4.12

## 0.1.22

### Patch Changes

- Updated dependencies [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)]:
  - @tanstack/db@0.4.11

## 0.1.21

### Patch Changes

- Updated dependencies [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a), [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)]:
  - @tanstack/db@0.4.10

## 0.1.20

### Patch Changes

- Addressed the majority of "any" type usage in the rxdb-db-collection adapter as well as fixed querying for documents where \_deleted is false, which fixes issues when using localStorage or other persistent storage mechanisms. ([#667](https://github.com/TanStack/db/pull/667))

- Updated dependencies [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47), [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13), [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)]:
  - @tanstack/db@0.4.9

## 0.1.19

### Patch Changes

- Updated dependencies [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450), [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)]:
  - @tanstack/db@0.4.8

## 0.1.18

### Patch Changes

- Updated dependencies [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)]:
  - @tanstack/db@0.4.7

## 0.1.17

### Patch Changes

- Updated dependencies [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113), [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)]:
  - @tanstack/db@0.4.6

## 0.1.16

### Patch Changes

- Updated dependencies [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)]:
  - @tanstack/db@0.4.5

## 0.1.15

### Patch Changes

- Updated dependencies [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888), [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd), [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627), [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c), [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)]:
  - @tanstack/db@0.4.4

## 0.1.14

### Patch Changes

- Updated dependencies [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)]:
  - @tanstack/db@0.4.3

## 0.1.13

### Patch Changes

- Updated dependencies [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a), [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534), [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b), [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)]:
  - @tanstack/db@0.4.2

## 0.1.12

### Patch Changes

- Updated dependencies [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)]:
  - @tanstack/db@0.4.1

## 0.1.11

### Patch Changes

- Refactor the main Collection class into smaller classes to make it easier to maintain. ([#560](https://github.com/TanStack/db/pull/560))

- Updated dependencies [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58), [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f), [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)]:
  - @tanstack/db@0.4.0

## 0.1.10

### Patch Changes

- Updated dependencies [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)]:
  - @tanstack/db@0.3.2

## 0.1.9

### Patch Changes

- Updated dependencies [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)]:
  - @tanstack/db@0.3.1

## 0.1.8

### Patch Changes

- Updated dependencies [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc), [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)]:
  - @tanstack/db@0.3.0

## 0.1.7

### Patch Changes

- Updated dependencies [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5), [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)]:
  - @tanstack/db@0.2.5

## 0.1.6

### Patch Changes

- Updated dependencies [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256), [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)]:
  - @tanstack/db@0.2.4

## 0.1.5

### Patch Changes

- Initial release ([#533](https://github.com/TanStack/db/pull/533))

## 0.0.0

- Initial Release


## Links discovered
- [[`b3b1940`](https://github.com/TanStack/db/commit/b3b194000d8efcc2c6cc45a663029dadc26f13f0)
- [`09da081`](https://github.com/TanStack/db/commit/09da081b420fc915d7f0dc566c6cdbbc78582435)
- [`86ad40c`](https://github.com/TanStack/db/commit/86ad40c6bc37b2f5d4ad24d06f72168ca4b96161)
- [[`c4b9399`](https://github.com/TanStack/db/commit/c4b93997432743d974749683059bf68a082d3e5b)
- [`a1a484e`](https://github.com/TanStack/db/commit/a1a484ec4d2331d702ab9c4b7e5b02622c76b3dd)
- [[`1d19d22`](https://github.com/TanStack/db/commit/1d19d2219cbbaef6483845df1c3b078077e4e3bd)
- [`b3e4e80`](https://github.com/TanStack/db/commit/b3e4e80c4b73d96c15391ac25efb518c7ae7ccbb)
- [[`5f474f1`](https://github.com/TanStack/db/commit/5f474f1eabd57e144ba05b0f33d848f7efc8fb07)
- [[`954c8fe`](https://github.com/TanStack/db/commit/954c8fed5ed92a348ac8b6d8333bc69c955f4f60)
- [`51c73aa`](https://github.com/TanStack/db/commit/51c73aaa2b27b27966edb98fb6664beb44eac1ac)
- [[`295cb45`](https://github.com/TanStack/db/commit/295cb45797572b232650eddd3d62ffa937fa2fd7)
- [[`c8a2c16`](https://github.com/TanStack/db/commit/c8a2c16aa528427d5ddd55cda4ee59a5cb369b5f)
- [[`077fc1a`](https://github.com/TanStack/db/commit/077fc1a418ca090d7533115888c09f3f609e36b2)
- [[`acb3e4f`](https://github.com/TanStack/db/commit/acb3e4f1441e6872ca577e74d92ae2d77deb5938)
- [`464805d`](https://github.com/TanStack/db/commit/464805d96bad6d0fd741e48fbfc98e90dc58bebe)
- [`2c2e4db`](https://github.com/TanStack/db/commit/2c2e4dbd781d278347d73373f66d3c51c6388116)
- [`15c772f`](https://github.com/TanStack/db/commit/15c772f5e42e49000a2d775fd8e4cfda3418243f)
- [[`846a830`](https://github.com/TanStack/db/commit/846a8309a243197245f4400a5d53cef5cec6d5d9)
- [`8e26dcf`](https://github.com/TanStack/db/commit/8e26dcfde600e4a18cd51fbe524560d60ab98d70)
- [[`99a3716`](https://github.com/TanStack/db/commit/99a371630b9f4632db86c43357c64701ecb53b0e)
- [[`a83a818`](https://github.com/TanStack/db/commit/a83a8189514d22ca2fcdf34b9cb97206d3c03c38)
- [[`243a35a`](https://github.com/TanStack/db/commit/243a35a632ee0aca20c3ee12ee2ac2929d8be11d)
- [`f9d11fc`](https://github.com/TanStack/db/commit/f9d11fc3d7297c61feb3c6876cb2f436edbb5b34)
- [`7aedf12`](https://github.com/TanStack/db/commit/7aedf12996a67ef64010bca0d78d51c919dd384f)
- [`28f81b5`](https://github.com/TanStack/db/commit/28f81b5165d0a9566f99c2b6cf0ad09533e1a2cb)
- [`f6ac7ea`](https://github.com/TanStack/db/commit/f6ac7eac50ae1334ddb173786a68c9fc732848f9)
- [`01093a7`](https://github.com/TanStack/db/commit/01093a762cf2f5f308edec7f466d1c3dabb5ea9f)
- [[`6c55e16`](https://github.com/TanStack/db/commit/6c55e16a2545b479b1d47f548b6846d362573d45)
- [`7805afb`](https://github.com/TanStack/db/commit/7805afb7286b680168b336e77dd4de7dd1b6f06a)
- [`1367756`](https://github.com/TanStack/db/commit/1367756d0a68447405c5f5c1a3cca30ab0558d74)
- [[`75470a8`](https://github.com/TanStack/db/commit/75470a8297f316b4817601b2ea92cb9b21cc7829)
- [[`f416231`](https://github.com/TanStack/db/commit/f41623180c862b58b4fa6415383dfdb034f84ee9)
- [`b1b8299`](https://github.com/TanStack/db/commit/b1b82994cb9765225129b5a19be06e9369e3158d)
- [[`49bcaa5`](https://github.com/TanStack/db/commit/49bcaa5557ba8d647c947811ed6e0c2450159d84)
- [[`979a66f`](https://github.com/TanStack/db/commit/979a66f2f6eff0ffe44dfde7c67feea933ee6110)
- [`f8a979b`](https://github.com/TanStack/db/commit/f8a979ba3aa90ac7e85f7a065fc050bda6589b4b)
- [`cb25623`](https://github.com/TanStack/db/commit/cb256234c9cd8df7771808b147e5afc2be56f51f)
- [[`6738247`](https://github.com/TanStack/db/commit/673824791bcfae04acf42fc35e5d6d8755adceb2)
- [[`970616b`](https://github.com/TanStack/db/commit/970616b6db723d1716eecd5076417de5d6e9a884)
- [[`3c9526c`](https://github.com/TanStack/db/commit/3c9526cd1fd80032ddddff32cf4a23dfa8376888)
- [[`8b29841`](https://github.com/TanStack/db/commit/8b298417964340bbac5ad08a831766f8f1497477)
- [`8187c6d`](https://github.com/TanStack/db/commit/8187c6d69c4b498e306ac2eb5fc7115e4f8193a5)
- [[`5566b26`](https://github.com/TanStack/db/commit/5566b26100abdae9b4a041f048aeda1dd726e904)
- [[`63aa8ef`](https://github.com/TanStack/db/commit/63aa8ef8b09960ce0f93e068d41b37fb0503a21a)
- [`b0687ab`](https://github.com/TanStack/db/commit/b0687ab4c1476362d7a25e3c1704ab0fb0385455)
- [#667](https://github.com/TanStack/db/pull/667)
- [[`e52be92`](https://github.com/TanStack/db/commit/e52be92ce16b09a095b4b9baf7ac2cf708146f47)
- [`4a7c44a`](https://github.com/TanStack/db/commit/4a7c44a723223ade4e226745eadffead671fff13)
- [`ee61bb6`](https://github.com/TanStack/db/commit/ee61bb61f76ca510f113e96baa090940719aac40)
- [[`d9ae7b7`](https://github.com/TanStack/db/commit/d9ae7b76b8ab30fd55fe835531974eee333dd450)
- [`44555b7`](https://github.com/TanStack/db/commit/44555b733a1a4d38d8126bf8da51d4b44f898298)
- [[`6692aad`](https://github.com/TanStack/db/commit/6692aad4267e127b71ce595529080d6fc0aa2066)
- [[`dd6cdf7`](https://github.com/TanStack/db/commit/dd6cdf7ea62d91bfb12ea8d25bdd25549259c113)
- [`c30a20b`](https://github.com/TanStack/db/commit/c30a20b1df39b34f18d0aa7c7b901a27fb963f36)
- [[`7556fb6`](https://github.com/TanStack/db/commit/7556fb6f888b5bdc830fe6448eb3368efeb61988)
- [[`56b870b`](https://github.com/TanStack/db/commit/56b870b3e63f8010b6eeebea87893b10c75a5888)
- [`f623990`](https://github.com/TanStack/db/commit/f62399062e4db61426ddfbbbe324c48cab2513dd)
- [`5f43d5f`](https://github.com/TanStack/db/commit/5f43d5f7f47614be8e71856ceb0f91733d9be627)
- [`05776f5`](https://github.com/TanStack/db/commit/05776f52a8ce4fe41b34fc8cace2046afc42835c)
- [`d27d32a`](https://github.com/TanStack/db/commit/d27d32aceb7f8fcabc07dcf1b55a84a605d2f23f)
- [[`32f2212`](https://github.com/TanStack/db/commit/32f221278e2a684f3f4e1e2ace1ca98f5ecc858a)
- [[`51c6bc5`](https://github.com/TanStack/db/commit/51c6bc58244ed6a3ac853e7e6af7775b33d6b65a)
- [`248e2c6`](https://github.com/TanStack/db/commit/248e2c6db8e9df8cf2cb225100e4ba9cb67cd534)
- [`ce7e2b2`](https://github.com/TanStack/db/commit/ce7e2b209ed882baa29ec86f89f1b527d6580e0b)
- [`1b832ff`](https://github.com/TanStack/db/commit/1b832ff9ec236e7dbe9256803e2ba12b4c9b9a30)
- [[`8cd0876`](https://github.com/TanStack/db/commit/8cd0876b50bc7c1a614365318d5e74c2f32a0f80)
- [#560](https://github.com/TanStack/db/pull/560)
- [[`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [`ac6250a`](https://github.com/TanStack/db/commit/ac6250a879e95718e8d911732c10fb3388569f0f)
- [`2f87216`](https://github.com/TanStack/db/commit/2f8721630e06331ca8bb2f962fbb283341103a58)
- [[`cacfca2`](https://github.com/TanStack/db/commit/cacfca2d1b430c34a05202128fd3affa4bff54d6)
- [[`5f51f35`](https://github.com/TanStack/db/commit/5f51f35d2c9543766a00cc5eea1374c62798b34e)
- [[`c557a14`](https://github.com/TanStack/db/commit/c557a1488650ea9081b671a4ac278d55c59ac9cc)
- [`b5c87f7`](https://github.com/TanStack/db/commit/b5c87f71dbb534e4f1c660cf010e2cb6c0446ec5)
- [[`b03894d`](https://github.com/TanStack/db/commit/b03894db05e063629a3660e03b31a80a48558dd5)
- [`3968087`](https://github.com/TanStack/db/commit/39680877fdc1993733933d2def13217bd18fa254)
- [[`92febbf`](https://github.com/TanStack/db/commit/92febbf1feaa1d46f8cc4d7a4ea0d44cd5f85256)
- [`b487430`](https://github.com/TanStack/db/commit/b4874308813f95232f3361de539cec104ed55170)
- [#533](https://github.com/TanStack/db/pull/533)

--- AGENTS.md ---
# Agent Coding Guidelines for TanStack DB

This guide provides principles and patterns for AI agents contributing to the TanStack DB codebase. These guidelines are derived from PR review patterns and reflect the quality standards expected in this project.

## Table of Contents

1. [Type Safety](#type-safety)
2. [Code Organization](#code-organization)
3. [Algorithm Efficiency](#algorithm-efficiency)
4. [Semantic Correctness](#semantic-correctness)
5. [Abstraction Design](#abstraction-design)
6. [Code Clarity](#code-clarity)
7. [Testing Requirements](#testing-requirements)
8. [Function Design](#function-design)
9. [Modern JavaScript Patterns](#modern-javascript-patterns)
10. [Edge Cases and Corner Cases](#edge-cases-and-corner-cases)

## Type Safety

### Avoid `any` Types

**❌ Bad:**

```typescript
function processData(data: any) {
  return data.value
}

const result: any = someOperation()
```

**✅ Good:**

```typescript
function processData(data: unknown) {
  if (isDataObject(data)) {
    return data.value
  }
  throw new Error('Invalid data')
}

const result: TQueryData = someOperation()
```

**Key Principles:**

- Use `unknown` instead of `any` when the type is truly unknown
- Provide proper type annotations for return values
- Use type guards to narrow `unknown` types safely
- If you find yourself using `any`, question whether there's a better type

## Code Organization

### Extract Common Logic

**❌ Bad:**

```typescript
// Duplicated logic in multiple places
function processA() {
  const key = typeof value === 'number' ? `__number__${value}` : String(value)
  // ...
}

function processB() {
  const key = typeof value === 'number' ? `__number__${value}` : String(value)
  // ...
}
```

**✅ Good:**

```typescript
function serializeKey(value: string | number): string {
  return typeof value === 'number' ? `__number__${value}` : String(value)
}

function processA() {
  const key = serializeKey(value)
  // ...
}

function processB() {
  const key = serializeKey(value)
  // ...
}
```

### Organize Utilities

**Key Principles:**

- Extract serialization/deserialization logic into utility files
- When you see identical or near-identical code blocks, extract to a helper function
- Prefer small, focused utility functions over large inline implementations
- Move reusable logic into utility modules (e.g., `utils/`, `helpers/`)

### Function Size and Complexity

**❌ Bad:**

```typescript
function syncData() {
  // 200+ lines of logic handling multiple concerns
  // - snapshot phase
  // - buffering
  // - sync state management
  // - error handling
  // all inline...
}
```

**✅ Good:**

```typescript
function syncData() {
  handleSnapshotPhase()
  manageBuffering()
  updateSyncState()
  handleErrors()
}

function handleSnapshotPhase() {
  // Focused logic for snapshot phase
}
```

**Key Principle:** If a function is massive, extract logical sections into separate functions. This improves readability and maintainability.

## Algorithm Efficiency

### Be Mindful of Time Complexity

**❌ Bad: O(n²) Queue Processing:**

```typescript
// Processes elements in queue, but elements may need multiple passes
while (queue.length > 0) {
  const job = queue.shift()
  if (hasUnmetDependencies(job)) {
    queue.push(job) // Re-queue, causing O(n²) behavior
  } else {
    processJob(job)
  }
}
```

**✅ Good: Dependency-Aware Processing:**

```typescript
// Use a data structure that respects dependencies
// Process only jobs with no unmet dependencies
// Consider topological sort for DAG-like structures
const readyJobs = jobs.filter((job) => !hasUnmetDependencies(job))
readyJobs.forEach(processJob)
```

### Use Appropriate Data Structures

**❌ Bad:**

```typescript
// O(n) lookup for each check
const items = ['foo', 'bar', 'baz' /* hundreds more */]
if (items.includes(searchValue)) {
  // ...
}
```

**✅ Good:**

```typescript
// O(1) lookup
const items = new Set(['foo', 'bar', 'baz' /* hundreds more */])
if (items.has(searchValue)) {
  // ...
}
```

**Key Principles:**

- For membership checks on large collections, use `Set` instead of `Array.includes()`
- Be aware of nested loops and their complexity implications
- Consider the worst-case scenario, especially for operations that could process many items
- Use appropriate data structures (Set for lookups, Map for key-value, etc.)

## Semantic Correctness

### Ensure Logic Matches Intent

**❌ Bad:**

```typescript
// Intending to check if subset limit is more restrictive than superset
function isLimitSubset(
  subset: number | undefined,
  superset: number | undefined,
) {
  return subset === undefined || superset === undefined || subset <= superset
}

// Problem: If subset has no limit but superset does, returns true (incorrect)
```

**✅ Good:**

```typescript
function isLimitSubset(
  subset: number | undefined,
  superset: number | undefined,
) {
  // Subset with no limit cannot be a subset of one with a limit
  return superset === undefined || (subset !== undefined && subset <= superset)
}
```

### Validate Intersections and Unions

When merging predicates or combining queries, ensure the semantics are correct:

**Example Problem:**

```sql
-- Query 1: WHERE age >= 18 LIMIT 1
-- Query 2: WHERE age >= 20 LIMIT 3
-- Naive intersection: WHERE age >= 20 LIMIT 1
-- Problem: This may not return the actual intersection of results
```

**Key Principle:** Think carefully about what operations like intersection, union, and subset mean for your specific use case. Consider edge cases with limits, ordering, and predicates.

## Abstraction Design

### Avoid Leaky Abstractions

**❌ Bad:**

```typescript
class Collection {
  getViewKey(key: TKey): string {
    // Caller needs to know internal representation
    return `${this._state.viewKeyPrefix}${key}`
  }
}

// Usage exposes internals
const viewKey = collection.getViewKey(key)
if (viewKey.startsWith(PREFIX)) {
  /* ... */
}
```

**✅ Good:**

```typescript
class Collection {
  getViewKey(key: TKey): string {
    // Delegate to state manager, hiding implementation
    return this._state.getViewKey(key)
  }
}

class CollectionStateManager {
  getViewKey(key: TKey): string {
    return `${this.viewKeyPrefix}${key}`
  }
}
```

**Key Principles:**

- Encapsulate implementation details within the responsible class
- Don't expose internal data structures or representations
- Use delegation to maintain clean boundaries between components
- Keep internal properties private when possible

### Proper Encapsulation

**Key Principle:** If you need to access a property or method from outside a class, add a public method that delegates to the internal implementation rather than exposing the internal property directly.

## Code Clarity

### Prefer Positive Predicates

**❌ Bad:**

```typescript
if (!refs.some((ref) => ref.path[0] === outerAlias)) {
  // treat as safe
}
```

**✅ Good:**

```typescript
if (refs.every((ref) => ref.path[0] !== outerAlias)) {
  // treat as safe
}
```

**Key Principle:** Positive conditions (every, all) are generally easier to understand than negated conditions (not some).

### Simplify Complex Conditions

**❌ Bad:**

```typescript
const isLoadingNow = this.pendingLoadSubsetPromises.size > 0
if (isLoadingNow && !isLoadingNow) {
  // Confusing logic
}
```

**✅ Good:**

```typescript
const wasLoading = this.pendingLoadSubsetPromises.size > 0
this.pendingLoadSubsetPromises.add(promise)
const isLoadingNow = this.pendingLoadSubsetPromises.size === 1

if (isLoadingNow) {
  // Started loading
}
```

### Use Descriptive Names

**❌ Bad:**

```typescript
const viewKeysMap = new Map() // Type in name is redundant
const dependencyBuilders = [] // Sounds like functions that build
```

**✅ Good:**

```typescript
const viewKeys = new Map() // Data structure not in name
const dependentBuilders = [] // Accurately describes dependents
```

**Key Principles:**

- Avoid Hungarian notation (encoding type in variable name)
- Use names that describe the role or purpose, not the data structure
- Choose names that make the code read like prose
- Prefer `dependentBuilders` over `dependencyBuilders` when referring to things that depend on something

## Testing Requirements

### Always Add Tests for Bugs

**Key Principle:** If you're fixing a bug, add a unit test that reproduces the bug before fixing it. This ensures:

- The bug is actually fixed
- The bug doesn't regress in the future
- The fix is validated

**Example:**

```typescript
// Found a bug with fetchSnapshot resolving after up-to-date message
// Should add a test:
test('ignores snapshot that resolves after up-to-date message', async () => {
  // Reproduce the corner case
  // Verify it's handled correctly
})
```

### Test Corner Cases

Common corner cases to consider:

- Empty arrays or sets
- Single-element collections
- `undefined` vs `null` values
- Operations on already-resolved promises
- Race conditions between async operations
- Limit/offset edge cases (0, 1, very large numbers)
- IN predicates with 0 or 1 elements

## Function Design

### Prefer Explicit Parameters Over Closures

**❌ Bad:**

```typescript
function outer() {
  const config = getConfig()
  const state = getState()

  const updateFn = () => {
    // Closes over config and state
    applyUpdate(config, state)
  }

  scheduler.schedule(updateFn)
}
```

**✅ Good:**

```typescript
function updateEntry(entry: Entry, config: Config, state: State) {
  applyUpdate(entry, config, state)
}

function outer() {
  const config = getConfig()
  const state = getState()

  scheduler.schedule({
    config,
    state,
    update: updateEntry,
  })
}
```

**Key Principles:**

- Functions that take dependencies as arguments are easier to test
- Explicit parameters make data flow clearer
- Closures can hide dependencies and make code harder to follow
- Use closures when they genuinely simplify the code, but be intentional

### Return Type Precision

**❌ Bad:**

```typescript
function serializeKey(key: string | number): unknown {
  return String(key)
}
```

**✅ Good:**

```typescript
function serializeKey(key: string | number): string {
  return String(key)
}
```

**Key Principle:** Always provide the most precise return type. Avoid `unknown` or `any` return types unless truly necessary.

## Modern JavaScript Patterns

### Use Modern Operators

**❌ Bad:**

```typescript
if (firstError === undefined) {
  firstError = error
}

const value = cached !== null && cached !== undefined ? cached : defaultValue

if (obj[key] === undefined) {
  obj[key] = value
}
```

**✅ Good:**

```typescript
firstError ??= error

const value = cached ?? defaultValue

obj[key] ??= value
```

### Use Spread Operator

**❌ Bad:**

```typescript
const combined = []
for (const item of currentItems) {
  combined.push(item)
}
for (const item of newItems) {
  combined.push(item)
}
```

**✅ Good:**

```typescript
const combined = [...currentItems, ...newItems]
```

### Simplify Array Operations

**❌ Bad:**

```typescript
const filtered = []
for (const item of items) {
  if (item.value > 0) {
    filtered.push(item)
  }
}
```

**✅ Good:**

```typescript
const filtered = items.filter((item) => item.value > 0)
```

## Edge Cases and Corner Cases

### Common Patterns to Consider

1. **Key Encoding**: When converting keys to strings, ensure no collisions

   ```typescript
   // ❌ Bad: numeric 1 and string "__number__1" collide
   const key = typeof val === 'number' ? `__number__${val}` : String(val)

   // ✅ Good: proper encoding with type prefix
   const key = `${typeof val}_${String(val)}`
   ```

2. **Subset/Superset Logic**: Consider all cases

   ```typescript
   // Consider: IN with 0, 1, or many elements
   // Consider: EQ vs IN predicates
   // Consider: Range predicates (>=, <=) vs equality
   ```

3. **Limit and Offset**: Handle undefined, 0, and edge values

   ```typescript
   // What happens when limit is 0?
   // What happens when offset exceeds data length?
   // What happens when limit is undefined?
   ```

4. **Optional vs Required**: Be explicit about optionality

   ```typescript
   // ❌ Why is this optional?
   interface Config {
     collection?: Collection
   }

   // ✅ Document or make required if always needed
   interface Config {
     collection: Collection // Always required for query collections
   }
   ```

5. **Race Conditions**: Async operations may resolve in unexpected order
   ```typescript
   // Request snapshot before receiving up-to-date
   // But snapshot resolves after up-to-date arrives
   // Should ignore the stale snapshot
   ```

## Package Versioning

### Understand Semantic Versioning

**Common Mistake:**

```json
{
  "dependencies": {
    "package": "^0.0.0"
  }
}
```

**Problem:** `^0.0.0` restricts to exactly `0.0.0`, not "latest 0.0.x" as you might expect.

From [npm semver docs](https://github.com/npm/node-semver):

> Caret Ranges allow changes that do not modify the left-most non-zero element. For versions `0.0.X`, this means no updates.

**Solutions:**

- Use `*` for any version
- Use `latest` for the latest version
- Use a proper range like `^0.1.0` if that's what you mean

## Documentation and Comments

### Keep Useful Comments

**Good Comment:**

```typescript
// Returning false signals that callers should schedule another pass
return allDone
```

**Good Comment:**

```typescript
// This step is necessary because the query function has captured
// the old subscription instance in its closure
```

### Remove Outdated Comments

**Key Principle:** When refactoring code, update or remove comments that reference old function names or outdated logic.

## General Principles

1. **Question Optionality**: If a property is optional, understand why. Often it should be required.

2. **Consider Performance**: Before implementing, think about time complexity, especially for operations that might process many items.

3. **Validate Semantics**: Ensure that your implementation actually does what you think it does. Consider edge cases.

4. **Avoid Premature Complexity**: Don't add ternaries, special cases, or checks for things that can't happen.

5. **Test First for Bugs**: Reproduce bugs in tests before fixing them.

6. **Be Consistent**: Follow naming conventions and patterns used elsewhere in the codebase.

7. **Simplify**: Modern JavaScript provides many concise operators and methods. Use them.

8. **Encapsulate**: Hide implementation details. Use delegation and proper abstraction boundaries.

9. **Type Precisely**: Use the most specific type possible. Avoid `any`.

10. **Extract When Duplicating**: If you're writing the same logic twice, extract it.

## When in Doubt

If you're unsure about an implementation decision:

1. Look for similar patterns in the existing codebase
2. Consider the worst-case scenario for performance
3. Think about edge cases and corner cases
4. Ask: "Does this abstraction leak implementation details?"
5. Ask: "Would this be easy to test?"
6. Ask: "Is this as simple as it could be?"

Remember: Simple, well-typed, well-tested code with clear abstractions is the goal. We raise the standard of code quality—not through complexity, but through clarity and correctness.


## Links discovered
- [npm semver docs](https://github.com/npm/node-semver)

--- README.md ---
<div align="center">
  <img src="./media/header_db.png" >
</div>

<br />

<div align="center">
	<a href="https://npmjs.com/package/@tanstack/db" target="\_parent">
	  <img alt="" src="https://img.shields.io/npm/dm/@tanstack/db.svg" alt="npm downloads" />
	</a>
	<a href="https://github.com/TanStack/db" target="\_parent">
	  <img alt="" src="https://img.shields.io/github/stars/TanStack/db.svg?style=social&label=Star" alt="GitHub stars" />
	</a>
	<a href="https://bundlejs.com/?q=%40tanstack%2Fdb&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=" target="\_parent">
	  <img alt="" src="https://deno.bundlejs.com/?q=@tanstack/db&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" alt="Bundle size" />
	</a>
</div>

<div align="center">
	<a href="#status">
    <img src="https://img.shields.io/badge/status-beta-yellow" alt="Status - BETA">
  </a>
	<a href="https://bestofjs.org/projects/tanstack-db">
		<img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Fdb%26since=daily" alt="Best of JS"/>
	</a>
	<a href="https://twitter.com/tan_stack">
		<img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/>
	</a>
</div>

<div align="center">
		
###  [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
</div>

# TanStack DB

> Tanstack DB is currently in BETA. See [the release post](https://tanstack.com/blog/tanstack-db-0.1-the-embedded-client-database-for-tanstack-query) for more details.

The reactive client store for your API.

TanStack DB solves the problems of building fast, modern apps, helping you:

- Avoid endpoint sprawl and network waterfalls by loading data into normalized collections
- Optimise client performance with sub-millisecond live queries and real-time reactivity
- Take the network off the interaction path with instant optimistic writes

Data loading is optimized. Interactions feel instantaneous. Your backend stays simple and your app stays blazing fast. No matter how much data you load.

<a href="https://tanstack.com/db" style="font-weight:bold" >Read the docs →</a>
<br />

## Get Involved

- We welcome issues and pull requests!
- Participate in [GitHub discussions](https://github.com/TanStack/db/discussions)
- Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ)
- See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions

## Partners

<table align="center">
<tr>
<td>
<a href="https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS" >
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/coderabbit-dark-CMcuvjEy.svg" height="40" />
  <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" />
  <img src="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" alt="CodeRabbit" />
</picture>
</a>
</td>
<td>
<a href="https://www.cloudflare.com?utm_source=tanstack">
<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/cloudflare-white-DQDB7UaL.svg" height="60" />
  <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" />
  <img src="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" alt="Cloudflare" />
</picture>
</a>
</td>
</tr>
<tr>
<td>
<a href="https://electric-sql.com">
<picture>
	<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/electric-dark-Bfu2Vl2j.svg" height="60">
	<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/electric-light-C-5MDda4.svg" height="60">
	<img src="https://raw.githubusercontent.com/electric-sql/meta/main/identity/ElectricSQL-logo.with-background.sm.png" height="60" alt="ElectricSQL logo"/>
</picture>
</a>
</td>
<td>
<a href="https://www.prisma.io?utm_source=tanstack&via=tanstack">
<picture>
	<source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/prisma-dark-DwgDxLwn.svg" height="60">
	<source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/prisma-light-Cloa3Onm.svg" height="60">
	<img src="https://tanstack.com/assets/prisma-dark-DwgDxLwn.svg" height="60" alt="Prisma"/>
</picture>
</a>
</td>
</tr>
</table>

<div align="center">
<img src="./media/partner_logo.svg" alt="DB & you?" height="65">
<p>
We're looking for TanStack DB Partners to join our mission! Partner with us to push the boundaries of TanStack DB and build amazing things together.
</p>
<a href="mailto:partners@tanstack.com?subject=TanStack DB Partnership"><b>LET'S CHAT</b></a>
</div>

## Explore the TanStack Ecosystem

- <a href="https://github.com/tanstack/config"><b>TanStack Config</b></a> – Tooling for JS/TS packages
- <a href="https://github.com/tanstack/devtools"><b>TanStack DevTools</b></a> – Unified devtools panel
- <a href="https://github.com/tanstack/form"><b>TanStack Form</b></a> – Type‑safe form state
- <a href="https://github.com/tanstack/pacer"><b>TanStack Pacer</b></a> – Debouncing, throttling, batching <br/>
- <a href="https://github.com/tanstack/query"><b>TanStack Query</b></a> – Async state & caching
- <a href="https://github.com/tanstack/ranger"><b>TanStack Ranger</b></a> – Range & slider primitives
- <a href="https://github.com/tanstack/router"><b>TanStack Router</b></a> – Type‑safe routing, caching & URL state
- <a href="https://github.com/tanstack/router"><b>TanStack Start</b></a> – Full‑stack SSR & streaming
- <a href="https://github.com/tanstack/store"><b>TanStack Store</b></a> – Reactive data store
- <a href="https://github.com/tanstack/table"><b>TanStack Table</b></a> – Headless datagrids
- <a href="https://github.com/tanstack/virtual"><b>TanStack Virtual</b></a> – Virtualized rendering

… and more at <a href="https://tanstack.com"><b>TanStack.com »</b></a>
v>

<!-- Use the force, Luke -->


## Links discovered
- [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
- [the release post](https://tanstack.com/blog/tanstack-db-0.1-the-embedded-client-database-for-tanstack-query)
- [GitHub discussions](https://github.com/TanStack/db/discussions)
- [Discord](https://discord.com/invite/WrRKjPJ)
- [CONTRIBUTING.md](https://github.com/tanstack/db/blob/main/CONTRIBUTING.md)
- [<img alt="" src="https://img.shields.io/npm/dm/@tanstack/db.svg" alt="npm downloads" />](https://npmjs.com/package/@tanstack/db)
- [<img alt="" src="https://img.shields.io/github/stars/TanStack/db.svg?style=social&label=Star" alt="GitHub stars" />](https://github.com/TanStack/db)
- [<img alt="" src="https://deno.bundlejs.com/?q=@tanstack/db&config={%22esbuild%22:{%22external%22:[%22react%22,%22react-dom%22]}}&badge=detailed" alt="Bundle size" />](https://bundlejs.com/?q=%40tanstack%2Fdb&config=%7B%22esbuild%22%3A%7B%22external%22%3A%5B%22react%22%2C%22react-dom%22%5D%7D%7D&badge=)
- [<img alt="Best of JS" src="https://img.shields.io/endpoint?url=https://bestofjs-serverless.now.sh/api/project-badge?fullName=TanStack%2Fdb%26since=daily" alt="Best of JS"/>](https://bestofjs.org/projects/tanstack-db)
- [<img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/>](https://twitter.com/tan_stack)
- [Read the docs →](https://tanstack.com/db)
- [<picture> <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/coderabbit-dark-CMcuvjEy.svg" height="40" /> <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" /> <img src="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" alt="CodeRabbit" /> </picture>](https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS)
- [<picture> <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/cloudflare-white-DQDB7UaL.svg" height="60" /> <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" /> <img src="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" alt="Cloudflare" /> </picture>](https://www.cloudflare.com?utm_source=tanstack)
- [<picture> <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/electric-dark-Bfu2Vl2j.svg" height="60"> <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/electric-light-C-5MDda4.svg" height="60"> <img src="https://raw.githubusercontent.com/electric-sql/meta/main/identity/ElectricSQL-logo.with-background.sm.png" height="60" alt="ElectricSQL logo"/> </picture>](https://electric-sql.com)
- [<picture> <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/prisma-dark-DwgDxLwn.svg" height="60"> <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/prisma-light-Cloa3Onm.svg" height="60"> <img src="https://tanstack.com/assets/prisma-dark-DwgDxLwn.svg" height="60" alt="Prisma"/> </picture>](https://www.prisma.io?utm_source=tanstack&via=tanstack)
- [<b>TanStack Config</b>](https://github.com/tanstack/config)
- [<b>TanStack DevTools</b>](https://github.com/tanstack/devtools)
- [<b>TanStack Form</b>](https://github.com/tanstack/form)
- [<b>TanStack Pacer</b>](https://github.com/tanstack/pacer)
- [<b>TanStack Query</b>](https://github.com/tanstack/query)
- [<b>TanStack Ranger</b>](https://github.com/tanstack/ranger)
- [<b>TanStack Router</b>](https://github.com/tanstack/router)
- [<b>TanStack Start</b>](https://github.com/tanstack/router)
- [<b>TanStack Store</b>](https://github.com/tanstack/store)
- [<b>TanStack Table</b>](https://github.com/tanstack/table)
- [<b>TanStack Virtual</b>](https://github.com/tanstack/virtual)
- [<b>TanStack.com »</b>](https://tanstack.com)

--- eslint.config.js ---
import { tanstackConfig } from '@tanstack/eslint-config'

export default [
  ...tanstackConfig,
  {
    ignores: [
      `**/dist/**`,
      `**/.output/**`,
      `**/.nitro/**`,
      `**/traildepot/**`,
      `examples/angular/**`,
    ],
  },
  {
    settings: {
      // import-x/* settings required for import/no-cycle.
      'import-x/resolver': { typescript: true },
      'import-x/extensions': ['.ts', '.tsx', '.js', '.jsx', '.cjs', '.mjs'],
    },
    rules: {
      'pnpm/enforce-catalog': `off`,
      'pnpm/json-enforce-catalog': `off`,
    },
  },
  {
    files: [`**/*.ts`, `**/*.tsx`],
    rules: {
      '@typescript-eslint/no-unused-vars': [
        `error`,
        { argsIgnorePattern: `^_`, varsIgnorePattern: `^_` },
      ],
      '@typescript-eslint/naming-convention': [
        `error`,
        {
          selector: `typeParameter`,
          format: [`PascalCase`],
          leadingUnderscore: `allow`,
        },
      ],
      'import/no-cycle': `error`,
    },
  },
]


--- prettier.config.js ---
// @ts-check

/** @type {import('prettier').Config} */
const config = {
  semi: false,
  singleQuote: true,
  trailingComma: 'all',
}

export default config


--- scripts/verify-links.ts ---
import { existsSync, readFileSync, statSync } from 'node:fs'
import { extname, resolve } from 'node:path'
import { glob } from 'tinyglobby'
// @ts-ignore Could not find a declaration file for module 'markdown-link-extractor'.
import markdownLinkExtractor from 'markdown-link-extractor'

const errors: Array<{
  file: string
  link: string
  resolvedPath: string
  reason: string
}> = []

function isRelativeLink(link: string) {
  return (
    !link.startsWith('/') &&
    !link.startsWith('http://') &&
    !link.startsWith('https://') &&
    !link.startsWith('//') &&
    !link.startsWith('#') &&
    !link.startsWith('mailto:')
  )
}

/** Remove any trailing .md */
function stripExtension(p: string): string {
  return p.replace(`${extname(p)}`, '')
}

function relativeLinkExists(link: string, file: string): boolean {
  // Remove hash if present
  const linkWithoutHash = link.split('#')[0]
  // If the link is empty after removing hash, it's not a file
  if (!linkWithoutHash) return false

  // Strip the file/link extensions
  const filePath = stripExtension(file)
  const linkPath = stripExtension(linkWithoutHash)

  // Resolve the path relative to the markdown file's directory
  // Nav up a level to simulate how links are resolved on the web
  let absPath = resolve(filePath, '..', linkPath)

  // Ensure the resolved path is within /docs
  const docsRoot = resolve('docs')
  if (!absPath.startsWith(docsRoot)) {
    errors.push({
      link,
      file,
      resolvedPath: absPath,
      reason: 'Path outside /docs',
    })
    return false
  }

  // Check if this is an example path
  const isExample = absPath.includes('/examples/')

  let exists = false

  if (isExample) {
    // Transform /docs/framework/{framework}/examples/ to /examples/{framework}/
    absPath = absPath.replace(
      /\/docs\/framework\/([^/]+)\/examples\//,
      '/examples/$1/',
    )
    // For examples, we want to check if the directory exists
    exists = existsSync(absPath) && statSync(absPath).isDirectory()
  } else {
    // For non-examples, we want to check if the .md file exists
    if (!absPath.endsWith('.md')) {
      absPath = `${absPath}.md`
    }
    exists = existsSync(absPath)
  }

  if (!exists) {
    errors.push({
      link,
      file,
      resolvedPath: absPath,
      reason: 'Not found',
    })
  }
  return exists
}

async function verifyMarkdownLinks() {
  // Find all markdown files in docs directory
  const markdownFiles = await glob('docs/**/*.md', {
    ignore: ['**/node_modules/**'],
  })

  console.log(`Found ${markdownFiles.length} markdown files\n`)

  // Process each file
  for (const file of markdownFiles) {
    const content = readFileSync(file, 'utf-8')
    const links: Array<string> = markdownLinkExtractor(content)

    const relativeLinks = links.filter((link: string) => {
      return isRelativeLink(link)
    })

    if (relativeLinks.length > 0) {
      relativeLinks.forEach((link) => {
        relativeLinkExists(link, file)
      })
    }
  }

  if (errors.length > 0) {
    console.log(`\n❌ Found ${errors.length} broken links:`)
    errors.forEach((err) => {
      console.log(
        `${err.file}\n  link:      ${err.link}\n  resolved:  ${err.resolvedPath}\n  why:       ${err.reason}\n`,
      )
    })
    process.exit(1)
  } else {
    console.log('\n✅ No broken links found!')
  }
}

verifyMarkdownLinks().catch(console.error)


--- .github/pull_request_template.md ---
## 🎯 Changes

<!-- What changes are made in this PR? Describe the change and its motivation. -->

## ✅ Checklist

- [ ] I have followed the steps in the [Contributing guide](https://github.com/TanStack/db/blob/main/CONTRIBUTING.md).
- [ ] I have tested this code locally with `pnpm test:pr`.

## 🚀 Release Impact

- [ ] This change affects published code, and I have generated a [changeset](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).
- [ ] This change is docs/CI/dev-only (no release).


## Links discovered
- [Contributing guide](https://github.com/TanStack/db/blob/main/CONTRIBUTING.md)
- [changeset](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md)

--- .github/ISSUE_TEMPLATE/bug_report.md ---
---
name: 🐛 Bug Report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---

- [ ] I've validated the bug against the latest version of DB packages

**Describe the bug**
A clear and concise description of what the bug is.

**To Reproduce**
Steps to reproduce the behavior:

1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**
A clear and concise description of what you expected to happen.

**Screenshots**
If applicable, add screenshots to help explain your problem.

**Desktop (please complete the following information):**

- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]

**Smartphone (please complete the following information):**

- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]

**Additional context**
Add any other context about the problem here.


--- packages/angular-db/README.md ---
# @tanstack/angular-db

Angular hooks for TanStack DB. See [TanStack/db](https://github.com/TanStack/db) for more details.

Installation

    npm install @tanstack/angular-db @tanstack/db

Usage

Basic Setup

First, create a collection:

    import { createCollection, localOnlyCollectionOptions } from "@tanstack/db"

    interface Todo {
      id: number
      text: string
      completed: boolean
      projectID: number
      created_at: Date
    }

    export const todosCollection = createCollection(
      localOnlyCollectionOptions<Todo>({
        getKey: (todo: Todo) => todo.id,
        initialData: [
          {
            id: 1,
            text: "Learn Angular",
            completed: false,
            projectID: 1,
            created_at: new Date(),
          },
        ],
      })
    )

Using injectLiveQuery in Components

Direct Collection Usage

The simplest way to use injectLiveQuery is to pass a collection directly:

    import { Component } from "@angular/core"
    import { injectLiveQuery } from "@tanstack/angular-db"
    import { todosCollection } from "./collections/todos-collection"

    @Component({
      selector: "app-all-todos",
      template: `
        @if (allTodos.isReady()) {
          <div>Total todos: {{ allTodos.data().length }}</div>
          @for (todo of allTodos.data(); track todo.id) {
            <div>{{ todo.text }}</div>
          }
        } @else {
          <div>Loading todos...</div>
        }
      `,
    })
    export class AllTodosComponent {
      // Direct collection usage - gets all items
      allTodos = injectLiveQuery(todosCollection)
    }

Static Query Functions

You can create filtered queries using a query function. Note: The query function is evaluated once and is not reactive to signal changes:

    import { Component } from "@angular/core"
    import { injectLiveQuery } from "@tanstack/angular-db"
    import { eq } from "@tanstack/db"
    import { todosCollection } from "./collections/todos-collection"

    @Component({
      selector: "app-todos",
      template: `
        @if (todoQuery.isReady()) {
          @for (todo of todoQuery.data(); track todo.id) {
            <div class="todo-item">
              {{ todo.text }}
              <button (click)="toggleTodo(todo.id)">
                {{ todo.completed ? "Undo" : "Complete" }}
              </button>
            </div>
          }
        } @else {
          <div>Loading todos...</div>
        }
      `,
    })
    export class TodosComponent {
      // Static query - filters for incomplete todos
      // This will not react to signal changes within the function
      todoQuery = injectLiveQuery((q) =>
        q
          .from({ todo: todosCollection })
          .where(({ todo }) => eq(todo.completed, false))
      )

      toggleTodo(id: number) {
        todosCollection.utils.begin()
        todosCollection.utils.write({
          type: 'update',
          key: id,
          value: { completed: true }
        })
        todosCollection.utils.commit()
      }
    }

Reactive Queries with Parameters

For queries that need to react to component state changes, use the reactive parameters overload:

    import { Component, signal } from "@angular/core"
    import { injectLiveQuery } from "@tanstack/angular-db"
    import { eq } from "@tanstack/db"
    import { todosCollection } from "./collections/todos-collection"

    @Component({
      selector: "app-project-todos",
      template: `
        <select (change)="selectedProjectId.set(+$any($event).target.value)">
          <option [value]="1">Project 1</option>
          <option [value]="2">Project 2</option>
          <option [value]="3">Project 3</option>
        </select>

        @if (todoQuery.isReady()) {
          <div>Todos for project {{ selectedProjectId() }}:</div>
          @for (todo of todoQuery.data(); track todo.id) {
            <div class="todo-item">
              {{ todo.text }}
            </div>
          }
        } @else {
          <div>Loading todos...</div>
        }
      `,
    })
    export class ProjectTodosComponent {
      selectedProjectId = signal(1)

      // Reactive query - automatically recreates when selectedProjectId changes
      todoQuery = injectLiveQuery({
        params: () => ({ projectID: this.selectedProjectId() }),
        query: ({ params, q }) =>
          q
            .from({ todo: todosCollection })
            .where(({ todo }) => eq(todo.completed, false))
            .where(({ todo }) => eq(todo.projectID, params.projectID)),
      })
    }

Advanced Configuration

You can also pass a full configuration object:

    import { Component } from "@angular/core"
    import { injectLiveQuery } from "@tanstack/angular-db"
    import { eq } from "@tanstack/db"
    import { todosCollection } from "./collections/todos-collection"

    @Component({
      selector: "app-configured-todos",
      template: `
        @if (todoQuery.isReady()) {
          @for (todo of todoQuery.data(); track todo.id) {
            <div>{{ todo.text }}</div>
          }
        }
      `,
    })
    export class ConfiguredTodosComponent {
      todoQuery = injectLiveQuery({
        query: (q) =>
          q
            .from({ todo: todosCollection })
            .where(({ todo }) => eq(todo.completed, false))
            .select(({ todo }) => ({
              id: todo.id,
              text: todo.text,
            })),
        startSync: true,
        gcTime: 5000,
      })
    }

Important Notes

Reactivity Behavior

- Direct collection: Automatically reactive to collection changes
- Static query function: Query is built once and is not reactive to signals read within the function
- Reactive parameters: Query rebuilds when any signal read in params() changes
- Collection configuration: Static, not reactive to external signals

Lifecycle Management

- injectLiveQuery automatically handles subscription cleanup when the component is destroyed
- Each call to injectLiveQuery creates a new collection instance (no caching/reuse)
- Collections are started immediately and will sync according to their configuration

Template Usage

Use Angular's new control flow syntax for best performance:

    @if (query.isReady()) {
      @for (item of query.data(); track item.id) {
        <div>{{ item.text }}</div>
      }
    } @else if (query.isError()) {
      <div>Error loading data</div>
    } @else {
      <div>Loading...</div>
    }

API

injectLiveQuery()

Angular injection function for TanStack DB live queries. Must be called within an injection context (e.g., component constructor, inject(), or field initializer).

Overloads

    // Direct collection - reactive to collection changes
    function injectLiveQuery<TResult, TKey, TUtils>(
      collection: Collection<TResult, TKey, TUtils>
    ): LiveQueryResult<TResult>

    // Static query function - NOT reactive to signals within function
    function injectLiveQuery<TContext>(
      queryFn: (q: InitialQueryBuilder) => QueryBuilder<TContext>
    ): LiveQueryResult<TContext>

    // Reactive query with parameters - recreates when params() signals change
    function injectLiveQuery<TContext, TParams>(options: {
      params: () => TParams
      query: (args: {
        params: TParams
        q: InitialQueryBuilder
      }) => QueryBuilder<TContext>
    }): LiveQueryResult<TContext>

    // Collection configuration - static configuration
    function injectLiveQuery<TContext>(
      config: LiveQueryCollectionConfig<TContext>
    ): LiveQueryResult<TContext>

Returns

An object with Angular signals:

- data: Signal<Array<T>> - Array of query results, automatically updates
- state: Signal<Map<Key, T>> - Map of results by key, automatically updates
- collection: Signal<Collection> - The underlying collection instance
- status: Signal<CollectionStatus> - Current status ('idle' | 'loading' | 'ready' | 'error' | 'cleaned-up')
- isLoading: Signal<boolean> - true when status is 'loading'
- isReady: Signal<boolean> - true when status is 'ready'
- isIdle: Signal<boolean> - true when status is 'idle'
- isError: Signal<boolean> - true when status is 'error'
- isCleanedUp: Signal<boolean> - true when status is 'cleaned-up'

Parameters

- collection - Existing collection to observe directly
- queryFn - Function that builds a static query using the query builder
- options.params - Reactive function that returns parameters; triggers query rebuild when accessed signals change
- options.query - Function that builds a query using parameters and query builder
- config - Configuration object for creating a live query collection

Requirements

- Angular 16+ (requires signals support)
- Must be called within an Angular injection context
- Automatically handles cleanup when the injector is destroyed


## Links discovered
- [TanStack/db](https://github.com/TanStack/db)

--- packages/db-collection-e2e/README.md ---
# @tanstack/db-collection-e2e

Shared end-to-end test suite for TanStack DB collections with query-driven sync and on-demand loading.

## Overview

This package provides a comprehensive e2e test suite that can be reused across different collection implementations (Electric, Query, etc.). It tests:

- Predicate push-down and filtering
- Pagination, ordering, and window management
- Multi-collection joins with mixed syncModes
- Deduplication of concurrent loadSubset calls
- String collation configurations
- Mutations with on-demand mode
- Live updates (for sync-enabled collections)

## Architecture

### Package Structure

```
db-collection-e2e/
├── docker/                   # Docker Compose for test infrastructure
│   ├── docker-compose.yml    # Postgres + Electric
│   └── postgres.conf         # Optimized for fast tests
├── src/
│   ├── types.ts              # TypeScript interfaces
│   ├── fixtures/             # Test data and schemas
│   │   ├── seed-data.ts      # Generate ~100 records per table
│   │   └── test-schema.ts    # SQL schema definitions
│   ├── suites/               # Test suite modules
│   │   ├── predicates.test.ts
│   │   ├── pagination.test.ts
│   │   ├── joins.test.ts
│   │   ├── deduplication.test.ts
│   │   ├── collation.test.ts
│   │   ├── mutations.test.ts
│   │   ├── live-updates.test.ts
│   │   └── regressions.test.ts
│   └── utils/                # Helper functions
│       ├── helpers.ts        # Common utilities
│       └── assertions.ts     # Custom assertions
└── support/                  # Vitest setup
    ├── global-setup.ts       # Health checks, DB init
    └── test-context.ts       # Vitest fixtures
```

## Getting Started

### Prerequisites

- Docker and Docker Compose
- Node.js 20+
- pnpm 10+

### Installation

From the repository root:

```bash
pnpm install
```

### Running Tests Locally

1. **Start Docker services:**

```bash
cd packages/db-collection-e2e/docker
docker compose up -d
```

2. **Run tests:**

```bash
cd packages/db-collection-e2e
pnpm test
```

3. **Stop Docker services:**

```bash
cd packages/db-collection-e2e/docker
docker compose down
```

## Test Data Schema

The test suite uses three related tables:

### Users Table (~100 records)

```typescript
interface User {
  id: string // UUID
  name: string // For collation testing
  email: string | null
  age: number
  isActive: boolean
  createdAt: Date
  metadata: object | null // JSON field
  deletedAt: Date | null // Soft delete
}
```

### Posts Table (~100 records)

```typescript
interface Post {
  id: string
  userId: string // FK to User
  title: string
  content: string | null
  viewCount: number
  publishedAt: Date | null
  deletedAt: Date | null
}
```

### Comments Table (~100 records)

```typescript
interface Comment {
  id: string
  postId: string // FK to Post
  userId: string // FK to User
  text: string
  createdAt: Date
  deletedAt: Date | null
}
```

### Data Distributions

Seed data includes:

- Mix of null/non-null values
- Various string cases (uppercase, lowercase, special chars)
- Date ranges (past, present, future)
- Numeric ranges (negative, zero, positive)
- Some soft-deleted records (~10%)

## Integrating with Your Collection

### 1. Create Setup File

Create `e2e/setup.ts` in your collection package. See real examples:

- Electric: `packages/electric-db-collection/e2e/setup.ts`
- Query: `packages/query-db-collection/e2e/setup.ts`

Example structure:

```typescript
import { createCollection } from '@tanstack/db'
import { yourCollectionOptions } from '../src'
import type {
  E2ETestConfig,
  User,
  Post,
  Comment,
} from '../../db-collection-e2e/src/types'

export async function createYourE2EConfig(options: {
  schema: string
  usersTable: string
  postsTable: string
  commentsTable: string
}): Promise<E2ETestConfig> {
  // Create collections for both syncModes (eager and on-demand)
  const eagerUsers = createCollection(
    yourCollectionOptions({
      id: `your-e2e-users-eager-${Date.now()}`,
      syncMode: 'eager',
      getKey: (item: User) => item.id,
      startSync: false,
    }),
  )

  const onDemandUsers = createCollection(
    yourCollectionOptions({
      id: `your-e2e-users-ondemand-${Date.now()}`,
      syncMode: 'on-demand',
      getKey: (item: User) => item.id,
      startSync: false,
    }),
  )

  // ... create posts and comments collections similarly

  return {
    collections: {
      eager: { users: eagerUsers, posts: eagerPosts, comments: eagerComments },
      onDemand: {
        users: onDemandUsers,
        posts: onDemandPosts,
        comments: onDemandComments,
      },
    },
    setup: async () => {
      // Optional setup hook
    },
    teardown: async () => {
      await Promise.all([
        eagerUsers.cleanup(),
        eagerPosts.cleanup(),
        eagerComments.cleanup(),
        onDemandUsers.cleanup(),
        onDemandPosts.cleanup(),
        onDemandComments.cleanup(),
      ])
    },
  }
}
```

### 2. Create E2E Test File

Create `e2e/your-collection.e2e.test.ts`:

```typescript
import { describe, it, expect } from 'vitest'
import { createCollection } from '@tanstack/db'
import { yourCollectionOptions } from '../src'

describe('Your Collection E2E', () => {
  it('should create collection', async () => {
    const collection = createCollection(
      yourCollectionOptions({
        id: 'test-collection',
        getKey: (item: any) => item.id,
        startSync: false,
      }),
    )

    expect(collection).toBeDefined()
    expect(collection._sync.loadSubset).toBeDefined()

    await collection.cleanup()
  })
})
```

### 3. Update Vitest Config

Update your `vite.config.ts` to include e2e tests:

```typescript
const config = defineConfig({
  test: {
    include: ['tests/**/*.test.ts', 'e2e/**/*.e2e.test.ts'],
    // Remove dir: './tests' if present
  },
})
```

### 4. Run Tests

```bash
cd packages/your-collection
pnpm test
```

The e2e tests will run alongside your regular tests.

## Test Suites

All test suites are implemented in `src/suites/*.suite.ts` files and exported as factory functions.

### Predicates Suite (`predicates.suite.ts`)

Tests basic where clause functionality with ~20 test scenarios:

**Example Test:**

```typescript
it('should filter with eq() on number field', async () => {
  const query = createLiveQueryCollection((q) =>
    q.from({ user: usersCollection }).where(({ user }) => eq(user.age, 25)),
  )
  await query.preload()

  const results = Array.from(query.state.values())
  assertAllItemsMatch(query, (u) => u.age === 25)
})
```

**Covers:**

- `eq()`, `gt()`, `gte()`, `lt()`, `lte()` with all data types
- `inArray()` with arrays
- `isNull()`, `not(isNull())` for null checks
- Complex boolean logic with `and()`, `or()`, `not()`
- Predicate pushdown verification

### Pagination Suite (`pagination.suite.ts`)

Tests ordering and pagination with ~15 test scenarios:

**Example Test:**

```typescript
it('should sort ascending by single field', async () => {
  const query = createLiveQueryCollection((q) =>
    q.from({ user: usersCollection }).orderBy(({ user }) => user.age, 'asc'),
  )
  await query.preload()

  const results = Array.from(query.state.values())
  assertSorted(results, 'age', 'asc')
})
```

**Covers:**

- Basic `orderBy` (asc/desc) on various field types
- Multiple `orderBy` fields
- `limit` and `offset` for pagination
- Edge cases (limit=0, offset beyond dataset)
- Performance verification (only requested page loaded)

### Joins Suite (`joins.suite.ts`)

Tests multi-collection joins with ~12 test scenarios:

**Example Test:**

```typescript
it('should join Users and Posts', async () => {
  const query = createLiveQueryCollection((q) =>
    q
      .from({ user: usersCollection })
      .join({ post: postsCollection }, ({ user, post }) =>
        eq(user.id, post.userId),
      )
      .select(({ user, post }) => ({
        id: post.id,
        userName: user.name,
        postTitle: post.title,
      })),
  )
  await query.preload()

  expect(query.size).toBeGreaterThan(0)
})
```

**Covers:**

- Two-collection joins (Users + Posts)
- Three-collection joins (Users + Posts + Comments)
- Mixed syncModes (eager + on-demand)
- Predicates on joined collections
- Left joins and ordering on joined results
- Pagination on joined results

### Deduplication Suite

Tests concurrent loadSubset calls:

- Identical predicates called simultaneously
- Overlapping predicates (subset relationships)
- Queries during active loading
- Deduplication callback verification

### Collation Suite

Tests string collation:

- Default collation behavior
- Custom `defaultStringCollation`
- Query-level collation override
- Case-sensitive vs case-insensitive

### Mutations Suite

Tests data mutations:

- Insert, update, delete operations
- Soft delete pattern
- Concurrent mutations
- Reactive query updates

### Live Updates Suite (Optional)

Tests reactive updates (for sync-enabled collections):

- Backend data changes
- Updates during loadSubset
- Multiple watchers
- Subscription lifecycle

### Regression Suite

Tests for known bugs:

- Initial state sent multiple times (#7214245)
- Race conditions in multi-join
- Missing data in change tracking
- LoadSubset naming changes (#9874949)

## Configuration

### Environment Variables

- `ELECTRIC_URL` - Electric server URL (default: `http://localhost:3000`)
- `POSTGRES_HOST` - Postgres host (default: `localhost`)
- `POSTGRES_PORT` - Postgres port (default: `54321`)
- `POSTGRES_USER` - Postgres user (default: `postgres`)
- `POSTGRES_PASSWORD` - Postgres password (default: `password`)
- `POSTGRES_DB` - Postgres database (default: `e2e_test`)

### Docker Configuration

The Docker Compose setup uses:

- Postgres 16 Alpine with tmpfs for speed
- Electric canary image
- Health checks with 10s timeout
- Optimized postgres.conf for testing

## Troubleshooting

### Docker services not starting

```bash
# Check service status
docker compose ps

# View logs
docker compose logs

# Restart services
docker compose restart
```

### Tests timing out

- Increase `timeout` in `vite.config.ts`
- Check Docker resource limits
- Verify network connectivity

### Database connection errors

- Ensure Docker services are healthy
- Check environment variables
- Verify ports are not in use

### Test isolation issues

Tests use unique table names per test to prevent collisions:

```
"users_taskId_random"
```

If you see data from other tests, check that cleanup is working properly.

## Performance

Target execution time: **< 5 minutes** for entire suite

Optimizations:

- tmpfs for Postgres data directory
- Serial execution (`fileParallelism: false`)
- Minimal test data (~300 records total)
- Optimized Postgres configuration
- Health checks with fast intervals

## Contributing

When adding new test suites:

1. Create new file in `src/suites/`
2. Export test factory function
3. Add to main exports in `src/index.ts`
4. Update README with test suite description
5. Ensure execution time stays < 5 minutes

## License

MIT

## Related

- [RFC #676](https://github.com/TanStack/db/discussions/676) - Query-driven sync RFC
- [PR #763](https://github.com/TanStack/db/pull/763) - Implementation PR
- [TanStack DB Documentation](https://tanstack.com/db)


## Links discovered
- [RFC #676](https://github.com/TanStack/db/discussions/676)
- [PR #763](https://github.com/TanStack/db/pull/763)
- [TanStack DB Documentation](https://tanstack.com/db)

--- packages/db-ivm/README.md ---
# IVM implementation for TanStack DB based on Differential Dataflow

This is an implementation of differential dataflow used by TanStack DB, forked from [@electric-sql/d2ts](https://github.com/electric-sql/d2ts), but simplified and without the complexities of multi-dimensional versioning.

It is used internally by the TanStack DB with the live queries compiled to a D2 graph. This library doesn't depend on the TanStack DB and so could be used in other projects.

The API is almost identical to D2TS, but without the need to specify a version when sending data, or to send a frontier to mark the end of a version.

### Basic Usage

Here's a simple example that demonstrates the core concepts:

```typescript
import { D2, map, filter, debug, MultiSet } from '@tanstack/db-ivm'

// Create a new D2 graph
const graph = new D2()

// Create an input stream
// We can specify the type of the input stream, here we are using number.
const input = graph.newInput<number>()

// Build a simple pipeline that:
// 1. Takes numbers as input
// 2. Adds 5 to each number
// 3. Filters to keep only even numbers
// Pipelines can have multiple inputs and outputs.
const output = input.pipe(
  map((x) => x + 5),
  filter((x) => x % 2 === 0),
  debug('output'),
)

// Finalize the pipeline, after this point we can no longer add operators or
// inputs
graph.finalize()

// Send some data
// Data is sent as a MultiSet, which is a map of values to their multiplicity
// Here we are sending 3 numbers (1-3), each with a multiplicity of 1
// The key thing to understand is that the MultiSet represents a *change* to
// the data, not the data itself. "Inserts" and "Deletes" are represented as
// an element with a multiplicity of 1 or -1 respectively.
input.sendData(
  new MultiSet([
    [1, 1],
    [2, 1],
    [3, 1],
  ]),
)

// Process the data
graph.run()

// Output will show:
// 6 (from 1 + 5)
// 8 (from 3 + 5)
```


## Links discovered
- [@electric-sql/d2ts](https://github.com/electric-sql/d2ts)

--- packages/db/README.md ---
# @tanstack/db

**The reactive client store for your API**

TanStack DB solves the problems of building fast, modern apps. It extends TanStack Query with collections, live queries and optimistic mutations that keep your UI reactive, consistent and blazing fast 🔥

<p>
  <a href="https://x.com/intent/post?text=TanStack%20DB&url=https://tanstack.com/db">
    <img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack" /></a>
  <a href="#status">
    <img src="https://img.shields.io/badge/status-alpha-orange" alt="Status - Alpha"></a>
  <a href="https://npmjs.com/package/@tanstack/db">
    <img alt="" src="https://img.shields.io/npm/dm/@tanstack/db.svg" /></a>
  <a href="https://discord.gg/yjUNbvbraC">
    <img alt="" src="https://img.shields.io/badge/Discord-TanStack-%235865F2" /></a>
  <a href="https://github.com/tanstack/db/discussions">
    <img alt="Join the discussion on Github" src="https://img.shields.io/badge/Discussions-Chat%20now!-green" /></a>
  <a href="https://x.com/tan_stack">
    <img alt="" src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social&label=Follow @TanStack" /></a>
</p>

## 💥 Visit the [TanStack/db](https://github.com/TanStack/db) repo for docs and details!

- 🚀 **Avoid endpoint sprawl**<br />
  Load data into normalized collections instead of building custom endpoints for every view
- 🔥 **Blazing fast queries**<br />
  Sub-millisecond live queries with joins & aggregates—your app stays fast no matter how much data you load
- ⚡ **Instant interactions**<br />
  Take the network off the interaction path with optimistic writes that feel instantaneous
- 🎯 **Fine-grained reactivity**<br />
  Minimize component re-rendering with precise updates

---

### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)

Enjoy this library? Try the entire [TanStack](https://tanstack.com), including [TanStack Query](https://tanstack.com/query), [TanStack Store](https://tanstack.com/store), etc.


## Links discovered
- [TanStack/db](https://github.com/TanStack/db)
- [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
- [TanStack](https://tanstack.com)
- [TanStack Query](https://tanstack.com/query)
- [TanStack Store](https://tanstack.com/store)
- [<img alt="#TanStack" src="https://img.shields.io/twitter/url?color=%2308a0e9&label=%23TanStack&style=social&url=https%3A%2F%2Ftwitter.com%2Fintent%2Ftweet%3Fbutton_hashtag%3DTanStack" />](https://x.com/intent/post?text=TanStack%20DB&url=https://tanstack.com/db)
- [<img alt="" src="https://img.shields.io/npm/dm/@tanstack/db.svg" />](https://npmjs.com/package/@tanstack/db)
- [<img alt="" src="https://img.shields.io/badge/Discord-TanStack-%235865F2" />](https://discord.gg/yjUNbvbraC)
- [<img alt="Join the discussion on Github" src="https://img.shields.io/badge/Discussions-Chat%20now!-green" />](https://github.com/tanstack/db/discussions)
- [<img alt="" src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social&label=Follow @TanStack" />](https://x.com/tan_stack)

--- packages/offline-transactions/README.md ---
# @tanstack/offline-transactions

Offline-first transaction capabilities for TanStack DB that provides durable persistence of mutations with automatic retry when connectivity is restored.

## Features

- **Outbox Pattern**: Persist mutations before dispatch for zero data loss
- **Automatic Retry**: Exponential backoff with jitter for failed transactions
- **Multi-tab Coordination**: Leader election ensures safe storage access
- **FIFO Sequential Processing**: Transactions execute one at a time in creation order
- **Flexible Storage**: IndexedDB with localStorage fallback
- **Type Safe**: Full TypeScript support with TanStack DB integration

## Installation

```bash
npm install @tanstack/offline-transactions
```

## Quick Start

```typescript
import { startOfflineExecutor } from '@tanstack/offline-transactions'

// Setup offline executor
const offline = startOfflineExecutor({
  collections: { todos: todoCollection },
  mutationFns: {
    syncTodos: async ({ transaction, idempotencyKey }) => {
      await api.saveBatch(transaction.mutations, { idempotencyKey })
    },
  },
  onLeadershipChange: (isLeader) => {
    if (!isLeader) {
      console.warn('Running in online-only mode (another tab is the leader)')
    }
  },
})

// Create offline transactions
const offlineTx = offline.createOfflineTransaction({
  mutationFnName: 'syncTodos',
  autoCommit: false,
})

offlineTx.mutate(() => {
  todoCollection.insert({
    id: crypto.randomUUID(),
    text: 'Buy milk',
    completed: false,
  })
})

// Execute with automatic offline support
await offlineTx.commit()
```

## Core Concepts

### Outbox-First Persistence

Mutations are persisted to a durable outbox before being applied, ensuring zero data loss during offline periods:

1. Mutation is persisted to IndexedDB/localStorage
2. Optimistic update is applied locally
3. When online, mutation is sent to server
4. On success, mutation is removed from outbox

### Multi-tab Coordination

Only one tab acts as the "leader" to safely manage the outbox:

- **Leader tab**: Full offline support with outbox persistence
- **Non-leader tabs**: Online-only mode for safety
- **Leadership transfer**: Automatic failover when leader tab closes

### FIFO Sequential Processing

Transactions are processed one at a time in the order they were created:

- **Sequential execution**: All transactions execute in FIFO order
- **Dependency safety**: Avoids conflicts between transactions that may reference each other
- **Predictable behavior**: Transactions complete in the exact order they were created

## API Reference

### startOfflineExecutor(config)

Creates and starts an offline executor instance.

```typescript
interface OfflineConfig {
  collections: Record<string, Collection>
  mutationFns: Record<string, MutationFn>
  storage?: StorageAdapter
  maxConcurrency?: number
  jitter?: boolean
  beforeRetry?: (transactions: OfflineTransaction[]) => OfflineTransaction[]
  onUnknownMutationFn?: (name: string, tx: OfflineTransaction) => void
  onLeadershipChange?: (isLeader: boolean) => void
}
```

### OfflineExecutor

#### Properties

- `isOfflineEnabled: boolean` - Whether this tab can persist offline transactions

#### Methods

- `createOfflineTransaction(options)` - Create a manual offline transaction
- `waitForTransactionCompletion(id)` - Wait for a specific transaction to complete
- `removeFromOutbox(id)` - Manually remove transaction from outbox
- `peekOutbox()` - View all pending transactions
- `notifyOnline()` - Manually trigger retry execution
- `dispose()` - Clean up resources

### Error Handling

Use `NonRetriableError` for permanent failures:

```typescript
import { NonRetriableError } from '@tanstack/offline-transactions'

const mutationFn = async ({ transaction }) => {
  try {
    await api.save(transaction.mutations)
  } catch (error) {
    if (error.status === 422) {
      throw new NonRetriableError('Invalid data - will not retry')
    }
    throw error // Will retry with backoff
  }
}
```

## Advanced Usage

### Custom Storage Adapter

```typescript
import {
  IndexedDBAdapter,
  LocalStorageAdapter,
} from '@tanstack/offline-transactions'

const executor = startOfflineExecutor({
  // Use custom storage
  storage: new IndexedDBAdapter('my-app', 'transactions'),
  // ... other config
})
```

### Custom Retry Policy

```typescript
const executor = startOfflineExecutor({
  maxConcurrency: 5,
  jitter: true,
  beforeRetry: (transactions) => {
    // Filter out old transactions
    const cutoff = Date.now() - 24 * 60 * 60 * 1000 // 24 hours
    return transactions.filter((tx) => tx.createdAt.getTime() > cutoff)
  },
  // ... other config
})
```

### Manual Transaction Control

```typescript
const tx = executor.createOfflineTransaction({
  mutationFnName: 'syncData',
  autoCommit: false,
})

tx.mutate(() => {
  collection.insert({ id: '1', text: 'Item 1' })
  collection.insert({ id: '2', text: 'Item 2' })
})

// Commit when ready
await tx.commit()
```

## Migration from TanStack DB

This package uses explicit offline transactions to provide offline capabilities:

```typescript
// Before: Standard TanStack DB (online only)
todoCollection.insert({ id: '1', text: 'Buy milk' })

// After: Explicit offline transactions
const offline = startOfflineExecutor({
  collections: { todos: todoCollection },
  mutationFns: {
    syncTodos: async ({ transaction }) => {
      await api.sync(transaction.mutations)
    },
  },
})

const tx = offline.createOfflineTransaction({ mutationFnName: 'syncTodos' })
tx.mutate(() => todoCollection.insert({ id: '1', text: 'Buy milk' }))
await tx.commit() // Works offline!
```

## Browser Support

- **IndexedDB**: Modern browsers (primary storage)
- **localStorage**: Fallback for limited environments
- **Web Locks API**: Chrome 69+, Firefox 96+ (preferred leader election)
- **BroadcastChannel**: All modern browsers (fallback leader election)

## License

MIT


--- packages/react-db/README.md ---
# @tanstack/react-db

React hooks for TanStack DB. See [TanStack/db](https://github.com/TanStack/db) for more details.


## Links discovered
- [TanStack/db](https://github.com/TanStack/db)

--- packages/solid-db/README.md ---
# @tanstack/solid-db

Solidjs hooks for TanStack DB. See [TanStack/db](https://github.com/TanStack/db) for more details.


## Links discovered
- [TanStack/db](https://github.com/TanStack/db)

--- packages/svelte-db/README.md ---
# @tanstack/svelte-db

Svelte helpers for TanStack DB. See [TanStack/db](https://github.com/TanStack/db) for more details.


## Links discovered
- [TanStack/db](https://github.com/TanStack/db)

--- packages/vue-db/README.md ---
# @tanstack/vue-db

Vue composables for TanStack DB. See [TanStack/db](https://github.com/TanStack/db) for more details.


## Links discovered
- [TanStack/db](https://github.com/TanStack/db)

--- packages/svelte-db/svelte.config.js ---
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'

const config = {
  preprocess: vitePreprocess(),
}

export default config
