Skip to content

Refactor Ref System with Nested Optional Properties #386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

samwillis
Copy link
Collaborator

🎯 Overview

This PR introduces a comprehensive refactor of the ref system to properly support nested structures and optionality, bringing the type system in line with JavaScript's optional chaining behavior.

✨ Key Improvements

  • 🔗 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, enabling proper optional chaining
  • 🔧 New Query Functions: Added isUndefined, isNotUndefined, isNull, isNotNull for proper null/undefined checks in queries
  • ⚙️ Improved JOIN Handling: Fixed optionality in JOIN operations and multiple GROUP BY clause support

🚨 Breaking Changes

IMPORTANT: Code that previously worked by ignoring optionality now requires proper optional chaining syntax.

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

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

🔧 Technical Changes

Type System Refactor

  • RefProxyForContext: Now handles optionality outside refs (RefProxy<T> | undefined)
  • PrecomputeRefStructure: Only wraps leaf values, leaving objects as plain TypeScript
  • Enhanced SelectValue: Support for nested projections and JavaScript literals
  • New Helper Types: Comprehensive null/undefined handling

Runtime Improvements

  • Compiler Functions: Implemented isNotUndefined, isUndefined, isNull, isNotNull
  • GROUP BY Fixes: Multiple .groupBy() calls now accumulate instead of replace
  • JOIN Optionality: Correct handling of optional tables in different join types

📊 Testing

  • 1,050 tests passing (60 test files)
  • 0 type errors
  • 0 linting errors
  • Enhanced type safety with comprehensive nested property coverage

🗂️ Files Changed

Core Type System

  • packages/db/src/query/builder/types.ts - Major refactor of ref types
  • packages/db/src/query/builder/index.ts - Enhanced query builder methods
  • packages/db/src/query/builder/functions.ts - New null/undefined functions

Compiler & Runtime

  • packages/db/src/query/compiler/evaluators.ts - Added missing function implementations
  • packages/db/src/query/compiler/group-by.ts - Fixed multiple GROUP BY validation

Tests & Documentation

  • Updated 100+ test files to use proper optional chaining syntax
  • Fixed linting issues from improved type inference
  • Added comprehensive changeset documentation

🚀 Migration Guide

For existing codebases: Add ?. when accessing potentially undefined nested properties. The TypeScript compiler will guide you to the correct syntax.

🎉 Benefits

  • Eliminates runtime errors from accessing undefined nested properties
  • Better IDE experience with cleaner type displays and proper IntelliSense
  • JavaScript alignment - type system now mirrors optional chaining behavior
  • Improved SQL compliance with better validation and null handling

This enhancement significantly improves developer experience while maintaining the robustness and performance of the existing query system.

KyleAMathews and others added 16 commits August 7, 2025 11:02
Added comprehensive test coverage for querying nested objects across WHERE, SELECT,
GROUP BY, and ORDER BY operations. Fixed query builder syntax issues by removing
JavaScript expressions, null coalescing operators, and unnecessary optional chaining.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@samwillis samwillis requested a review from kevin-dp August 7, 2025 15:16
Copy link

changeset-bot bot commented Aug 7, 2025

🦋 Changeset detected

Latest commit: cfb0b9e

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

This PR includes changesets to release 8 packages
Name Type
@tanstack/db Patch
@tanstack/electric-db-collection Patch
@tanstack/query-db-collection Patch
@tanstack/react-db Patch
@tanstack/solid-db Patch
@tanstack/svelte-db Patch
@tanstack/trailbase-db-collection Patch
@tanstack/vue-db 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

Copy link

pkg-pr-new bot commented Aug 7, 2025

More templates

@tanstack/db

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

@tanstack/db-ivm

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

@tanstack/electric-db-collection

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

@tanstack/query-db-collection

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

@tanstack/react-db

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

@tanstack/solid-db

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

@tanstack/svelte-db

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

@tanstack/trailbase-db-collection

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

@tanstack/vue-db

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

commit: cfb0b9e

Copy link
Contributor

github-actions bot commented Aug 7, 2025

Size Change: +107 B (+0.18%)

Total Size: 58.6 kB

Filename Size Change
./packages/db/dist/esm/query/builder/functions.js 584 B +9 B (+1.57%)
./packages/db/dist/esm/query/builder/index.js 3.83 kB +35 B (+0.92%)
./packages/db/dist/esm/query/compiler/evaluators.js 1.54 kB +63 B (+4.27%)
ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/change-events.js 1.13 kB
./packages/db/dist/esm/collection.js 9.85 kB
./packages/db/dist/esm/deferred.js 230 B
./packages/db/dist/esm/errors.js 2.98 kB
./packages/db/dist/esm/index.js 1.51 kB
./packages/db/dist/esm/indexes/auto-index.js 689 B
./packages/db/dist/esm/indexes/base-index.js 605 B
./packages/db/dist/esm/indexes/btree-index.js 1.47 kB
./packages/db/dist/esm/indexes/lazy-index.js 1.25 kB
./packages/db/dist/esm/local-only.js 827 B
./packages/db/dist/esm/local-storage.js 2.03 kB
./packages/db/dist/esm/optimistic-action.js 294 B
./packages/db/dist/esm/proxy.js 4.19 kB
./packages/db/dist/esm/query/builder/ref-proxy.js 890 B
./packages/db/dist/esm/query/compiler/expressions.js 631 B
./packages/db/dist/esm/query/compiler/group-by.js 2.03 kB
./packages/db/dist/esm/query/compiler/index.js 1.74 kB
./packages/db/dist/esm/query/compiler/joins.js 1.56 kB
./packages/db/dist/esm/query/compiler/order-by.js 677 B
./packages/db/dist/esm/query/compiler/select.js 655 B
./packages/db/dist/esm/query/ir.js 318 B
./packages/db/dist/esm/query/live-query-collection.js 2.45 kB
./packages/db/dist/esm/query/optimizer.js 2.44 kB
./packages/db/dist/esm/SortedMap.js 1.24 kB
./packages/db/dist/esm/transactions.js 2.29 kB
./packages/db/dist/esm/utils.js 419 B
./packages/db/dist/esm/utils/btree.js 5.93 kB
./packages/db/dist/esm/utils/comparison.js 718 B
./packages/db/dist/esm/utils/index-optimization.js 1.62 kB

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

Copy link
Contributor

github-actions bot commented Aug 7, 2025

Size Change: 0 B

Total Size: 1.05 kB

ℹ️ View Unchanged
Filename Size
./packages/react-db/dist/esm/index.js 152 B
./packages/react-db/dist/esm/useLiveQuery.js 902 B

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

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