Skip to content

DRAFT live query docs #242

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

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft

DRAFT live query docs #242

wants to merge 3 commits into from

Conversation

samwillis
Copy link
Collaborator

No description provided.

Copy link

changeset-bot bot commented Jul 8, 2025

⚠️ No Changeset found

Latest commit: ee13a10

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

Copy link

pkg-pr-new bot commented Jul 8, 2025

@tanstack/db-example-react-todo

npm i https://pkg.pr.new/@tanstack/db@242
npm i https://pkg.pr.new/@tanstack/db-collections@242
npm i https://pkg.pr.new/@tanstack/react-db@242
npm i https://pkg.pr.new/@tanstack/vue-db@242

commit: ee13a10

Copy link
Contributor

github-actions bot commented Jul 8, 2025

Size Change: 0 B

Total Size: 30.3 kB

ℹ️ View Unchanged
Filename Size
./packages/db/dist/esm/collection.js 7.89 kB
./packages/db/dist/esm/deferred.js 230 B
./packages/db/dist/esm/errors.js 150 B
./packages/db/dist/esm/index.js 528 B
./packages/db/dist/esm/optimistic-action.js 294 B
./packages/db/dist/esm/proxy.js 3.75 kB
./packages/db/dist/esm/query/builder/functions.js 531 B
./packages/db/dist/esm/query/builder/index.js 3.4 kB
./packages/db/dist/esm/query/builder/ref-proxy.js 842 B
./packages/db/dist/esm/query/compiler/evaluators.js 1.34 kB
./packages/db/dist/esm/query/compiler/group-by.js 2.09 kB
./packages/db/dist/esm/query/compiler/index.js 1.42 kB
./packages/db/dist/esm/query/compiler/joins.js 1.15 kB
./packages/db/dist/esm/query/compiler/order-by.js 933 B
./packages/db/dist/esm/query/compiler/select.js 657 B
./packages/db/dist/esm/query/ir.js 318 B
./packages/db/dist/esm/query/live-query-collection.js 2.06 kB
./packages/db/dist/esm/SortedMap.js 1.24 kB
./packages/db/dist/esm/transactions.js 1.51 kB

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

Copy link
Contributor

github-actions bot commented Jul 8, 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

Copy link
Collaborator

@KyleAMathews KyleAMathews left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Love it!


### Convenience Function

For simpler cases, you can use `createLiveQueryCollection` as a shortcut:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we want this? We explicitly went down the two function calls as a way of being explicit about how collections work & I'd rather keep things consistent — people can certainly add their own convenience functions if they'd like

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking here is that this could be the exception to the rule. Users will be very regularly be creating liveQueryCollections outside of components, in loaders and other places, and if we don't provide this wrapper they will after a while get frustrated and make it themselves. The intention is that it exposes the same api as the useLiveQuery, you just use the callback to build your query, so moving between the two doesn't require any different structures in your code.

This is a strong opinion (I would expect it from the lib), but but weakly held - if you felt equally strongly that we should remove it then let's do that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I don't feel that strongly against it 👍 so let's keep it

id: user.id,
name: user.name,
})),
getKey: (user) => user.id, // Optional: uses stream key if not provided
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there an actual use case for explicitly defining the key? We should probably then say what it is or if not, just disallow it altogether.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, with joins. We generate a composite key for the join using the key from each side, but often there would only need to be one side of the key.

For example if you join an aggregate query bringing in stats for "issues" - comment counts, velocity, ect. - you are joining the PK on the same PK. Issue 1 would end up with a key of [1,1], 2 with [2,2] ect.

In that cases using getKey: (issue) => issue.id would ensure that the resulting collection used the same PK as the original collection.

There is also a similar thing with groupBy, it generates a json string as the key, but often there is a better natural key that could have been used.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I do remember you saying this. Then yeah, adding the above as context in the docs would be great


## Basic Queries

The foundation of every query is the `from` method, which specifies the source collection or subquery. You can alias the source using object syntax.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can probably remove this section

}))
```

### Query Builder Pattern
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd expect this to show something new from the previous ones e.g. an if (filter === 'foo') { /* add a where clause */ }

)
```

### Using Functions
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could be combined with the section above

const allPosts = createLiveQueryCollection((q) =>
q
.from({ user: usersCollection })
.join(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I kinda liked .rightJoin more — that seems clearer than a lonely third argument

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, I meant to add this but it got forgotten in the mix. @thruflo was keen on a simple join() for a left join, and we then discussed having leftJoin, rightJoin, innerJoin ect. that wrapped it and set that final param.

How does that sound?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

)
```

### Conditional Query Building
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant?

const activeUsers = createLiveQueryCollection(buildUserQuery({ activeOnly: true, limit: 10 }))
```

### Caching Intermediate Results
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redundant?

}))
```

You can also create callbacks that take the whole row and pass them directly to `where`:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔥

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