Triplit roles for those who wear many hats
TLDR
We release a slew of improvements for roles, the console and error messages across the Triplit stack.
Better support for clients with multiple roles
When building your permissions system in Triplit, we've seen developers often want or need to assign multiple roles to a single client. While this was possible before, the treatment of multiple roles was not well defined. This week we've improved that. Clients with multiple roles will have those permissions "or'd" together. If the roles have competing permission filters for a single collection, the client will need to just pass one of the filters to view a given entity.
For example, with the following roles:
import { type Roles } from '@triplit/client';
export const roles: Roles = {
admin: {
match: {
admin: true,
},
},
user: {
match: {
sub: '$userId',
},
},
};
And permissions for a collection:
import { S as Schema } from '@triplit/client';
export const schema = {
posts: {
schema: S.Schema({
id: S.Id(),
authorId: S.String(),
text: S.String(),
}),
permissions: {
admin: {
read: { filter: [true] },
insert: { filter: [true] },
update: { filter: [true] },
delete: { filter: [true] },
},
user: {
read: { filter: [['authorId', '=', '$role.userId']] },
insert: { filter: [['authorId', '=', '$role.userId']] },
update: { filter: [['authorId', '=', '$role.userId']] },
delete: { filter: [['authorId', '=', '$role.userId']] },
},
},
},
};
A client that has both the admin
and user
roles will be able to read, insert, update, and delete any post, as the eventual permission filter for that client will be a combination of the admin
and user
filters: or([[true], ['authorId', '=', '$role.userId']])
.
Console improvements
We've added two new features to the Triplit console:
Role preview for tokens
When adding a new token to the console, you can now see the roles that the token will have access to, allowing you a chance to change or debug the token or the roles before saving.
Pagination control
Due to popular demand, we've added pagination controls to the console. You can choose whether to load 25, 50, or 100 items at a time, and then grow the list as needed at that increment.
Angular pagination hooks
Triplit has subscriptions for subscribing to data in a paginated way. It's great for reducing the amount of data you need to load at once but also allows you to load more data as needed. These methods (client.subscribeWithExpand
and client.subscribeWithPagination
) have been available in vanilla JavaScript and in React, but we've added some easy to use bindings for Angular as well. Read the docs on createPaginatedQuery
and createInfiniteQuery
to learn more.
We've also made improvements to the existing createQuery
hook that prevent it from running the subscribe side-effect multiple times when subscribing to the same results$
observable in multiple places.
Sync improvements
- The sync engine will now properly backfill results as data changes for subscribed queries that have a limit. E.g. a query with limit 10, loads the initial 10, then two entities from that result are deleted, the sync engine will now attempt to find two items to fill the gap.
- Fixed a bug where in some cases subscriptions on a query with limit and no defined order would not properly backfill results
Error messaging improvements
We've made a handful of improvements to our error messaging across the client, server and CLI:
- The HTTPClient prints better error messages
- Running seeds for a server with
npx triplit seed run [seedfile.ts]
will now throw full errors with stack traces - Syncing queries with
includes
andexists
clauses will no longer crash a schemaless server and have more helpful error messages