Skip to content

Conversation

@BrianGrug
Copy link

@BrianGrug BrianGrug commented Nov 21, 2025

🎯 Changes

βœ… Checklist

  • I have followed the steps in the Contributing guide.
    (Doesn't exist)
  • I have tested this code locally with pnpm test:pr.
    (Doesn't exist)

πŸš€ Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

This PR allows the Firestore collection package tests to pass. There are some things to note:

  1. Aborts throw a warning instead of error. This is because there are many times Firestore may abort (e.g a subscription being canceled, firestore shutting down, etc).
  2. getAll was not implemented, so I have replaced it with toArray

kevin-dp and others added 30 commits September 1, 2025 17:04
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Sam Willis <sam.willis@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Kyle Mathews <mathews.kyle@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
…ction. (TanStack#389)

Co-authored-by: Kyle Mathews <mathews.kyle@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…es in live query collections (TanStack#521)

Co-authored-by: Ali Sabil <ali.sabil@kopera.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
KyleAMathews and others added 20 commits November 17, 2025 10:34
Add changesets for two merged PRs that were missing them:
- Pacer package upgrade (0592852)
- Query collection loadSubset dedupe removal (47255e5)

πŸ€– Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* test: add regression tests for issue TanStack#397 (update/delete targeting)

Adds comprehensive test coverage for issue TanStack#397 which reported that
update() and delete() operations on localStorage collections were
targeting the wrong items.

Investigation findings:
- Bug was fixed by PR TanStack#760 (Nov 5, 2025) which changed from using
  config.getKey() to mutation.key for consistency
- All tests pass, unable to reproduce the reported issue
- Likely that recent commenter is using an outdated package version

Test Coverage Added:
- Test for updating correct item with multiple items present
- Test for deleting correct item with multiple items present
- Both tests verify collection state AND localStorage persistence

Also includes detailed investigation report (INVESTIGATION_397.md)
documenting the analysis, timeline, and recommendations.

Related: TanStack#397, TanStack#760

* fix: resolve localStorage numeric ID key type mismatch (issue TanStack#397)

Fixes TanStack#397 - Update and delete operations on localStorage collections
now work correctly with numeric IDs.

## Root Cause

When using numeric IDs with localStorage collections, a type mismatch
occurred between numeric keys (e.g., 1, 2, 3) and string keys from
localStorage (e.g., "1", "2", "3").

The issue manifested when:
1. Data was loaded from localStorage (keys become strings via JSON.parse)
2. User performed update/delete with numeric ID
3. JavaScript Map lookup failed: Map.has(1) !== Map.has("1")

## The Fix

Convert all mutation.key values to strings before using with lastKnownData
Map, ensuring consistency with localStorage's string-only keys.

Changed in packages/db/src/local-storage.ts:
- Line 419 (wrappedOnInsert): const key = String(mutation.key)
- Line 455 (wrappedOnUpdate): const key = String(mutation.key)
- Line 486 (wrappedOnDelete): const key = String(mutation.key)
- Line 554 (acceptMutations): const key = String(mutation.key)

## Test Coverage

Added 6 comprehensive test cases in packages/db/tests/local-storage.test.ts:

Bug TanStack#397 test suite (lines 1618-1985):
- String ID tests (baseline/regression)
- Numeric ID tests (direct operations)
- Numeric ID tests after loading from storage (critical case)

All 43 tests pass βœ…

## Impact

- βœ… Fully backward compatible (string IDs unchanged)
- βœ… Numeric IDs now work correctly
- βœ… No breaking changes to API

## Documentation

- BUG_FIX_397.md: Detailed technical explanation
- INVESTIGATION_397.md: Complete investigation report

Closes TanStack#397

* chore: add changeset for numeric ID localStorage fix

- Remove investigation documentation files
- Add changeset for patch release

* test: add test for numeric/string ID collision behavior

Documents that numeric ID 1 and string ID "1" will collide in
localStorage due to JSON's string-only object keys. Last write wins.

This is expected behavior and a fundamental localStorage limitation.

* refactor: use __number__ prefix for numeric keys instead of String()

Improves fix for issue TanStack#397 to prevent collision between numeric and
string IDs (e.g., numeric 1 vs string "1").

Approach:
- Numeric keys: prefixed with "__number__" β†’ __number__1
- String keys: kept as-is β†’ "1", "first"

Benefits:
- βœ… Fixes numeric ID bug (original issue TanStack#397)
- βœ… Prevents numeric/string ID collision
- βœ… Maintains backward compatibility for string IDs
- βœ… All 44 tests passing

Related: TanStack#397

* chore: update changeset to focus on original bug

Reworded to emphasize the actual bug (numeric IDs not working)
rather than collision prevention as the main issue.

* test: rename test suite to remove issue number reference

Changed 'Bug TanStack#397: update/delete targeting wrong item' to
'numeric and string ID handling' to be more descriptive and
issue-agnostic.

* fix: implement proper type-safe encoding for localStorage keys

- Replace __number__ prefix with type-safe n: and s: encoding scheme
- Extract encoding/decoding logic into helper functions (encodeStorageKey, decodeStorageKey)
- Prevents all possible collisions between numeric and string keys
- Add test case for collision prevention between numeric 1 and string 'n:1'
- Update all tests to use new encoding format

Co-authored-by: Kevin <kevin-dp@users.noreply.github.com>

* test: update localStorage tests for type-safe encoding

Update all localStorage collection tests to match the new type-safe
key encoding format that prevents collisions between numeric and
string IDs.

Changes:
- Update test assertions to use encoded keys ("s:1" for string "1")
- Update test data setup to use encoded keys in storage
- Fix verifyConsistency helper to decode storage keys properly
- All 17 failing tests now correctly expect the encoded format

Co-authored-by: Kevin <kevin-dp@users.noreply.github.com>

* fix: update acceptMutations tests to use encoded storage keys

Tests were expecting unencoded keys (e.g., 'tx-1') but the new type-safe
encoding stores string keys with the 's:' prefix (e.g., 's:tx-1').

Updated 6 test cases to access parsed storage with correct encoded keys.

Co-authored-by: Kevin <kevin-dp@users.noreply.github.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com>
Co-authored-by: Kevin <kevin-dp@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* Unit test to reproduce problem with operators not being passed to loadSubset

* Do not filter non-indexable operators in convertToBasicExpression

* Changeset

* Unit tests in query collection to check that where clause is passed through to the query function's context

* Revert changes to lockfile

* Remove isConvertibleToCollectionFilter function

* Rename convertToBasicExpression to normalizeExpressionPaths and convertOrderByToBasicExpression to normalizeOrderByPaths
* Add type test reproducing the problem

* Fix type problem

* Changeset
* docs: edit broken link for collection interface

* docs: fix broken link to collection options creator guide
Fix docs sidebar Collection link capitalization

The sidebar was linking to reference/interfaces/collection (lowercase) but
the actual interface documentation is at reference/interfaces/Collection
(uppercase). This was causing a broken link in the docs.

Co-authored-by: Claude <noreply@anthropic.com>
…ction (TanStack#800)

* feat: automatically append predicates to static queryKey in on-demand mode

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 static queryKeys in on-demand mode would cause
all live queries with different predicates to share the same cache entry,
defeating the purpose of predicate push-down.

Changes:
- Added serialization utilities for LoadSubsetOptions (serializeLoadSubsetOptions,
  serializeExpression, serializeValue)
- Modified createQueryFromOpts to automatically append serialized predicates
  when queryKey is static and syncMode is 'on-demand'
- Function-based queryKeys continue to work as before
- Eager mode with static queryKeys unchanged (no automatic serialization)

Tests:
- Added comprehensive test suite for static queryKey with on-demand mode
- Tests verify different predicates create separate cache entries
- Tests verify identical predicates reuse the same cache entry
- Tests verify eager mode behavior unchanged
- All existing tests pass

* chore: add changeset for static queryKey on-demand mode fix

* chore: update changeset to patch instead of minor

* chore: format changeset with prettier

* refactor: address PR review feedback

Addresses Kevin's review comments:

1. Move serialization functions to dedicated utility file
   - Created src/serialization.ts with serializeLoadSubsetOptions,
     serializeExpression, and serializeValue functions
   - Keeps query.ts focused on query logic

2. Fix return type and use undefined instead of null
   - Changed serializeLoadSubsetOptions return type from `unknown` to
     `string | undefined`
   - Returns undefined instead of null for empty options
   - Updated usage to conditionally append only when serialized result
     is not undefined

3. Add missing CompareOptions properties to orderBy serialization
   - Now includes stringSort, locale, and localeOptions properties
   - Properly handles the StringCollationConfig union type with
     conditional serialization for locale-specific options

All runtime tests pass (65/65 in query.test.ts).

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
…Stack#857)

* Type tests reproducing the problem with the current type of the meta property

* Augment tanstack query-core module to provide precise type for meta property

* Fix linting

* Changeset

* Fix failing unit test after rebase
* docs: add framework overview pages for Vue, Solid, Svelte, and Angular

Replace placeholder content with complete framework-specific documentation
for all non-React adapters. Each overview includes:

- Installation instructions
- Basic usage with useLiveQuery (or injectLiveQuery for Angular)
- Dependency arrays/reactive parameters documentation
- Framework-specific code examples and best practices

These pages follow the same structure as the React overview but are
tailored to each framework's conventions and only document the
useLiveQuery hook (the only hook currently available for these frameworks).

* docs: fix reactivity patterns in Solid and Vue framework overviews

Correct the documentation based on actual source code and test verification:

**Solid changes:**
- Remove incorrect dependency array pattern
- Document automatic fine-grained reactivity tracking
- Show correct signal usage inside query functions
- Add examples of good vs bad patterns
- Explain that Solid tracks signals automatically without deps

**Vue changes:**
- Fix dependency array to pass refs directly, not wrapped in functions
- Show correct pattern: [minAge] instead of [() => minAge]
- Add toRef pattern for props
- Clarify getter functions are only needed for non-ref values
- Add example of using pre-created collections with reactive refs

Both frameworks now match their actual implementations as verified
against packages/*-db/src/*.ts source files and test files.

* docs: fix Angular and Svelte framework overview issues

Address critical issues identified in external code review:

**Angular fixes:**
- Replace invalid destructuring syntax ({ data } = injectLiveQuery)
  with correct field assignment (query = injectLiveQuery)
- Update all templates to call signals with () as per Angular API
- Add separate examples for Angular 16+ (@input) vs 17+ (input.required)
- Add note explaining all return values are Angular signals
- Ensure all examples use query.data() and query.isLoading()

**Svelte fixes:**
- Remove incorrect $ prefix from all examples (not Svelte stores)
- Change to const query = useLiveQuery() pattern
- Update all templates to use query.data and query.isLoading directly
- Add note explaining Svelte 5 runes return reactive values via getters
- Ensure consistency: query.data (no call), query.isLoading (no call)

These changes align documentation with actual adapter implementations
and fix syntax errors that would cause compile failures.

* docs: address second-round reviewer feedback on Angular and Solid

Apply precision improvements from external code review:

**Angular:**
- Soften parameter-change behavior wording to avoid over-promising
  timing guarantees (changed from "isLoading becomes true" to
  "status()/isLoading() reflect the new query's lifecycle")
- Add template syntax version note explaining @if/@for requires
  Angular 17+ (v16 users should use *ngIf/*ngFor)

**Solid:**
- Fix contradictory intro sentence that claimed "all return values
  should be called as functions" while the note correctly stated
  "data is a plain array"
- Now states clearly: "data is a plain array and status fields are
  accessors"

All changes align documentation with exact adapter behavior and
prevent user confusion about API contracts.

---------

Co-authored-by: Claude <noreply@anthropic.com>
…nStack#812)

* Enhance overview.md with blog post content and Query-Driven Sync

Updates the overview documentation to better reflect the content and
features from the two DB blog posts (0.1 and 0.5):

- Add compelling "Option C" narrative explaining the architecture
  problem TanStack DB solves (view-specific APIs vs load-everything)

- Document Query-Driven Sync feature from 0.5 release:
  - Three sync modes: eager, on-demand, progressive
  - How component queries automatically become API calls
  - Request optimization (collapsing, delta loading, join batching)

- Add concrete performance numbers: ~0.7ms updates for 100k items
  on M1 Pro, demonstrating truly instantaneous optimistic updates

- Expand sync engine benefits section:
  - Easy real-time updates without WebSocket plumbing
  - Automatic side-effects and cache invalidation
  - Efficient delta updates enabling "load everything once" pattern

These changes bridge the gap between the technical reference docs
and the compelling narrative from the blog posts, helping developers
understand both why TanStack DB exists and how to use it effectively.

* Add end-user benefit emphasis: apps stay fast regardless of data size

Highlights that apps can't get sluggish due to too much data, with
queries over 100k+ rows completing in under a millisecond. This makes
the end-user experience benefit clear early in the documentation.

* Refine introduction with clearer problem-solution framing

Rewrites the introduction to:
- Lead with the problems TanStack DB solves (endpoint sprawl,
  client performance, network on interaction path)
- Emphasize the end-user benefit upfront: interactions feel
  instantaneous, app stays fast regardless of data volume
- Present the "new way" as numbered benefits rather than
  "Option C" framing
- More action-oriented and benefit-focused language

This makes the value proposition clearer and more compelling
for developers evaluating TanStack DB.

* Update README.md to match new overview.md messaging

Aligns README with the refined overview.md framing:
- Changes "client-first" to "client" to match new terminology
- Adopts problem-solution framing (avoid endpoint sprawl,
  optimize client performance, take network off interaction path)
- Emphasizes end-user benefit: app stays fast regardless of data
- More action-oriented and benefit-focused language

Keeps README concise while maintaining consistency with docs.

* Update packages/db/README.md with new messaging

Aligns the core package README with the refined messaging:
- Updates tagline to "The reactive client store for your API"
- Adds "solves the problems of building fast, modern apps"
- Rewrites bullet points to focus on problem-solution framing:
  - Avoid endpoint sprawl (vs building custom endpoints)
  - Blazing fast queries (app stays fast regardless of data)
  - Instant interactions (network off interaction path)
  - Fine-grained reactivity (minimize re-rendering)

Makes the npm package description more benefit-oriented.

---------

Co-authored-by: Claude <noreply@anthropic.com>
docs: regenerate API documentation

Auto-generated by daily docs sync workflow

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
@changeset-bot
Copy link

changeset-bot bot commented Nov 21, 2025

πŸ¦‹ Changeset detected

Latest commit: 5589131

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@tanstack/query-db-collection Patch
@tanstack/db-collection-e2e Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@BrianGrug BrianGrug changed the title fixed(tests): Made Firestore tests pass Make Firestore tests pass Nov 21, 2025
@BrianGrug BrianGrug changed the title Make Firestore tests pass Finish Firestore integration Dec 2, 2025
@BrianGrug BrianGrug marked this pull request as draft December 2, 2025 21:04
@BrianGrug
Copy link
Author

Didn't mean to push the merge.. Going to reset and create a new PR, noticed a few other things (Schema, on-demand sync, etc) is missing

@BrianGrug BrianGrug closed this Dec 2, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.