Skip to content

React Native Shopping List demo app#1357

Open
kevin-dp wants to merge 189 commits intokevin/includesfrom
examples/shopping-list
Open

React Native Shopping List demo app#1357
kevin-dp wants to merge 189 commits intokevin/includesfrom
examples/shopping-list

Conversation

@kevin-dp
Copy link
Contributor

Summary

  • Adds a React Native Shopping List demo app (examples/react-native/shopping-list/) showcasing three TanStack DB features:
    • Includes with aggregates — parent query uses nested count() subqueries to compute per-list item counts; ListCard subcomponents subscribe to child collections via useLiveQuery() for reactive updates
    • Offline transactions — mutations (add/delete lists, add/toggle/delete items) are applied optimistically and queued for sync via startOfflineExecutor from @tanstack/offline-transactions/react-native
    • SQLite persistence — collections use persistedCollectionOptions with createReactNativeSQLitePersistence (op-sqlite) so data survives app restarts
  • Express backend (server/index.ts) with in-memory storage and seed data for polling-based sync
  • Metro config handles pnpm monorepo symlinks, singleton React resolution, and package exports for subpath imports

Test plan

  • Start server: cd examples/react-native/shopping-list && npx tsx server/index.ts
  • Start Metro: npx expo start --dev-client --clear
  • Run on Android: npx expo run:android
  • Verify lists display with correct item counts (includes + aggregates)
  • Add/delete lists and items (offline transactions)
  • Kill and restart app — verify data persists (SQLite persistence)
  • Stop server — verify mutations queue and sync when server restarts

🤖 Generated with Claude Code

cursoragent and others added 30 commits February 10, 2026 09:28
autofix-ci bot and others added 23 commits March 10, 2026 10:34
…ion key collision

When multiple parents share the same correlation key but have different
parent-referenced filter values, child collections were incorrectly shared.
Fix by keying child collections by (correlationKey, parentFilterValues)
composite, and using composite child keys in the D2 stream to prevent
collisions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ss-window sync

Add ElectronCollectionCoordinator using BroadcastChannel + Web Locks for
leader election and cross-window coordination in Electron renderer windows.
Wire coordinator into renderer persistence via setAdapter(), add
getStreamPosition to the IPC protocol, and export from package index.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reproduces the bug where grouped ordering for limit uses the raw
correlation key instead of the composite routing key, causing parents
that share a correlation key but differ on parent-referenced filters
to have their children merged before the limit is applied.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The includesGroupKeyFn for orderBy + limit/offset was grouping by raw
correlationKey, causing parents sharing a correlation key but differing
on parent-referenced filters to have their children merged before the
limit was applied. Use the same composite key as the routing layer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…at both levels

When both the child and grandchild includes use parent-referencing
filters, the grandchild collection comes back empty because the
nested routing index uses a different key than the nested buffer.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…fer keys

The nested routing index was keyed by raw correlationKey while nested
buffers use computeRoutingKey(correlationKey, parentContext). This
mismatch caused drainNestedBuffers lookups to fail, leaving grandchild
collections empty when parent-referencing filters exist at both levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…filters

Verifies that composite routing keys work at arbitrary nesting depth,
not just the first two levels.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…llection

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ld cleanup

Two fixes for when multiple parents share the same correlation key:

1. Add reduce operator on parentKeyStream to clamp multiplicities to 1,
   preventing the inner join from producing duplicate child entries that
   cause incorrect deletions when one parent is removed.

2. In Phase 5, only delete child registry entry when the last parent
   referencing it is removed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These routing properties leak into user-visible results when the child
query uses a spread select (e.g. { ...i }).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brings in toArray() for includes subqueries, used by the shopping list
demo to materialize child item arrays for reactive count display.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Brings in support for aggregates (e.g. count) in includes subqueries,
enabling per-parent aggregate computation in the shopping list demo.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: b318908

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

This PR includes changesets to release 19 packages
Name Type
@tanstack/react-db Patch
@tanstack/db Patch
@tanstack/electric-db-collection Patch
@tanstack/angular-db Patch
@tanstack/db-sqlite-persisted-collection-core Patch
@tanstack/offline-transactions Patch
@tanstack/powersync-db-collection Patch
@tanstack/query-db-collection Patch
@tanstack/rxdb-db-collection Patch
@tanstack/solid-db Patch
@tanstack/svelte-db Patch
@tanstack/trailbase-db-collection Patch
@tanstack/vue-db Patch
shopping-list-react-native Patch
@tanstack/db-browser-wa-sqlite-persisted-collection Patch
@tanstack/db-cloudflare-do-sqlite-persisted-collection Patch
@tanstack/db-electron-sqlite-persisted-collection Patch
@tanstack/db-node-sqlite-persisted-collection Patch
@tanstack/db-react-native-sqlite-persisted-collection 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

@changeset-bot
Copy link

changeset-bot bot commented Mar 12, 2026

🦋 Changeset detected

Latest commit: 6d89a7a

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

This PR includes changesets to release 19 packages
Name Type
@tanstack/react-db Patch
@tanstack/db Patch
@tanstack/electric-db-collection Patch
@tanstack/angular-db Patch
@tanstack/db-sqlite-persisted-collection-core Patch
@tanstack/offline-transactions Patch
@tanstack/powersync-db-collection Patch
@tanstack/query-db-collection Patch
@tanstack/rxdb-db-collection Patch
@tanstack/solid-db Patch
@tanstack/svelte-db Patch
@tanstack/trailbase-db-collection Patch
@tanstack/vue-db Patch
shopping-list-react-native Patch
@tanstack/db-browser-wa-sqlite-persisted-collection Patch
@tanstack/db-cloudflare-do-sqlite-persisted-collection Patch
@tanstack/db-electron-sqlite-persisted-collection Patch
@tanstack/db-node-sqlite-persisted-collection Patch
@tanstack/db-react-native-sqlite-persisted-collection 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

@kevin-dp kevin-dp changed the base branch from kevin/includes-aggregates to kevin/includes-arbitrary-correlation March 12, 2026 08:48
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 12, 2026

More templates

@tanstack/angular-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/angular-db@1357

@tanstack/db

npm i https://pkg.pr.new/TanStack/db/@tanstack/db@1357

@tanstack/db-browser-wa-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-browser-wa-sqlite-persisted-collection@1357

@tanstack/db-cloudflare-do-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-cloudflare-do-sqlite-persisted-collection@1357

@tanstack/db-electron-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-electron-sqlite-persisted-collection@1357

@tanstack/db-ivm

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-ivm@1357

@tanstack/db-node-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-node-sqlite-persisted-collection@1357

@tanstack/db-react-native-sqlite-persisted-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-react-native-sqlite-persisted-collection@1357

@tanstack/db-sqlite-persisted-collection-core

npm i https://pkg.pr.new/TanStack/db/@tanstack/db-sqlite-persisted-collection-core@1357

@tanstack/electric-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/electric-db-collection@1357

@tanstack/offline-transactions

npm i https://pkg.pr.new/TanStack/db/@tanstack/offline-transactions@1357

@tanstack/powersync-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/powersync-db-collection@1357

@tanstack/query-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/query-db-collection@1357

@tanstack/react-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/react-db@1357

@tanstack/rxdb-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/rxdb-db-collection@1357

@tanstack/solid-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/solid-db@1357

@tanstack/svelte-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/svelte-db@1357

@tanstack/trailbase-db-collection

npm i https://pkg.pr.new/TanStack/db/@tanstack/trailbase-db-collection@1357

@tanstack/vue-db

npm i https://pkg.pr.new/TanStack/db/@tanstack/vue-db@1357

commit: 42ea541

@github-actions
Copy link
Contributor

Size Change: +3.17 kB (+3.28%)

Total Size: 99.8 kB

Filename Size Change
./packages/db/dist/esm/collection/events.js 434 B +46 B (+11.86%) ⚠️
./packages/db/dist/esm/collection/index.js 3.56 kB +236 B (+7.1%) 🔍
./packages/db/dist/esm/collection/indexes.js 2.35 kB +1.25 kB (+113.57%) 🆘
./packages/db/dist/esm/index.js 2.78 kB +74 B (+2.74%)
./packages/db/dist/esm/indexes/lazy-index.js 1.24 kB +135 B (+12.24%) ⚠️
./packages/db/dist/esm/query/builder/index.js 5.15 kB +496 B (+10.66%) ⚠️
./packages/db/dist/esm/query/compiler/evaluators.js 1.62 kB +189 B (+13.23%) ⚠️
./packages/db/dist/esm/query/compiler/index.js 3.29 kB +572 B (+21.06%) 🚨
./packages/db/dist/esm/query/ir.js 784 B +27 B (+3.57%)
./packages/db/dist/esm/query/live/collection-config-builder.js 8.05 kB +144 B (+1.82%)
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/collection/change-events.js 1.39 kB
./packages/db/dist/esm/collection/changes.js 1.22 kB
./packages/db/dist/esm/collection/lifecycle.js 1.75 kB
./packages/db/dist/esm/collection/mutations.js 2.34 kB
./packages/db/dist/esm/collection/state.js 3.49 kB
./packages/db/dist/esm/collection/subscription.js 3.71 kB
./packages/db/dist/esm/collection/sync.js 2.41 kB
./packages/db/dist/esm/deferred.js 207 B
./packages/db/dist/esm/errors.js 4.7 kB
./packages/db/dist/esm/event-emitter.js 748 B
./packages/db/dist/esm/indexes/auto-index.js 742 B
./packages/db/dist/esm/indexes/base-index.js 766 B
./packages/db/dist/esm/indexes/btree-index.js 2.17 kB
./packages/db/dist/esm/indexes/reverse-index.js 538 B
./packages/db/dist/esm/local-only.js 808 B
./packages/db/dist/esm/local-storage.js 2.1 kB
./packages/db/dist/esm/optimistic-action.js 359 B
./packages/db/dist/esm/paced-mutations.js 496 B
./packages/db/dist/esm/proxy.js 3.75 kB
./packages/db/dist/esm/query/builder/functions.js 792 B
./packages/db/dist/esm/query/builder/ref-proxy.js 1.05 kB
./packages/db/dist/esm/query/compiler/expressions.js 430 B
./packages/db/dist/esm/query/compiler/group-by.js 2.35 kB
./packages/db/dist/esm/query/compiler/joins.js 2.11 kB
./packages/db/dist/esm/query/compiler/order-by.js 1.5 kB
./packages/db/dist/esm/query/compiler/select.js 1.11 kB
./packages/db/dist/esm/query/expression-helpers.js 1.43 kB
./packages/db/dist/esm/query/live-query-collection.js 360 B
./packages/db/dist/esm/query/live/collection-registry.js 264 B
./packages/db/dist/esm/query/live/collection-subscriber.js 2.42 kB
./packages/db/dist/esm/query/live/internal.js 145 B
./packages/db/dist/esm/query/optimizer.js 2.62 kB
./packages/db/dist/esm/query/predicate-utils.js 2.97 kB
./packages/db/dist/esm/query/subset-dedupe.js 921 B
./packages/db/dist/esm/scheduler.js 1.3 kB
./packages/db/dist/esm/SortedMap.js 1.3 kB
./packages/db/dist/esm/strategies/debounceStrategy.js 247 B
./packages/db/dist/esm/strategies/queueStrategy.js 428 B
./packages/db/dist/esm/strategies/throttleStrategy.js 246 B
./packages/db/dist/esm/transactions.js 2.9 kB
./packages/db/dist/esm/utils.js 924 B
./packages/db/dist/esm/utils/browser-polyfills.js 304 B
./packages/db/dist/esm/utils/btree.js 5.61 kB
./packages/db/dist/esm/utils/comparison.js 952 B
./packages/db/dist/esm/utils/cursor.js 457 B
./packages/db/dist/esm/utils/index-optimization.js 1.51 kB
./packages/db/dist/esm/utils/type-guards.js 157 B

compressed-size-action::db-package-size

@github-actions
Copy link
Contributor

Size Change: 0 B

Total Size: 3.7 kB

ℹ️ View Unchanged
Filename Size
./packages/react-db/dist/esm/index.js 225 B
./packages/react-db/dist/esm/useLiveInfiniteQuery.js 1.17 kB
./packages/react-db/dist/esm/useLiveQuery.js 1.34 kB
./packages/react-db/dist/esm/useLiveSuspenseQuery.js 559 B
./packages/react-db/dist/esm/usePacedMutations.js 401 B

compressed-size-action::react-db-package-size

Base automatically changed from kevin/includes-arbitrary-correlation to kevin/includes March 12, 2026 13:27
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.

2 participants