Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/all-meals-follow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/db": patch
---

Add optional compareOptions to collection configuration.
39 changes: 39 additions & 0 deletions .changeset/expression-helpers-queryfn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
---
"@tanstack/db": patch
"@tanstack/query-db-collection": patch
---

Add expression helper utilities for parsing LoadSubsetOptions in queryFn.

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.
5 changes: 5 additions & 0 deletions .changeset/legal-cooks-sink.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/db-ivm": patch
---

Fix bug with setWindow on ordered queries that have no limit.
5 changes: 5 additions & 0 deletions .changeset/light-phones-flash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/db": patch
---

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.
5 changes: 5 additions & 0 deletions .changeset/open-cups-lose.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/db": patch
---

Add support for orderBy and limit in currentStateAsChanges function
5 changes: 5 additions & 0 deletions .changeset/silent-trains-tell.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/query-db-collection": patch
---

Handle pushed-down predicates
5 changes: 5 additions & 0 deletions .changeset/tender-carpets-cheat.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/electric-db-collection": patch
---

Handle predicates that are pushed down.
5 changes: 5 additions & 0 deletions .changeset/two-lamps-wave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@tanstack/db": patch
---

Adds an onDeduplicate callback on the DeduplicatedLoadSubset class which is called when a loadSubset call is deduplicated
77 changes: 77 additions & 0 deletions .github/workflows/e2e-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
name: E2E Tests

on:
push:
branches: [main]
pull_request:

jobs:
e2e-tests:
name: Run E2E Tests
runs-on: ubuntu-latest
timeout-minutes: 10

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 10.19.0

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: "20"
cache: "pnpm"

- name: Install dependencies
run: pnpm install --frozen-lockfile

- name: Start Docker services
run: |
cd packages/db-collection-e2e/docker
docker compose up -d
echo "Waiting for services to be healthy..."
timeout 60 bash -c 'until docker compose ps | grep -q "healthy"; do sleep 2; done'

- name: Build packages
run: |
pnpm --filter @tanstack/db-ivm build
pnpm --filter @tanstack/db build
pnpm --filter @tanstack/electric-db-collection build
pnpm --filter @tanstack/query-db-collection build

- name: Run Electric E2E tests
run: |
cd packages/electric-db-collection
pnpm test:e2e
env:
ELECTRIC_URL: http://localhost:3000
POSTGRES_HOST: localhost
POSTGRES_PORT: 54321
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: e2e_test

- name: Run Query E2E tests
run: |
cd packages/query-db-collection
pnpm test:e2e
env:
ELECTRIC_URL: http://localhost:3000

- name: Stop Docker services
if: always()
run: |
cd packages/db-collection-e2e/docker
docker compose down -v

- name: Upload test results
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-results
path: packages/db-collection-e2e/junit/
retention-days: 7
Loading
Loading