Skip to content

Add initial TrailBase integration and tests. #228

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 3 commits into
base: main
Choose a base branch
from

Conversation

ignatz
Copy link
Contributor

@ignatz ignatz commented Jul 4, 2025

I've also started working on an example, as you suggested, but wanted to send out an RFC early.

Don't hold back. Let me know if this is going roughly the expected direction. If so, also let me know how you'd like to handle a potential example, e.g. should it be part of the same PR, should it be a full replica of the todo example?

Thanks!

Copy link

changeset-bot bot commented Jul 4, 2025

⚠️ No Changeset found

Latest commit: 59bcb8d

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
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.

Looking good!

BTW, thinking about this PR made me realize we really should have collection types be in their own packages so e.g. if you want to do a major release you can #235

We'll be migrating the other packages in the next day or two so you can just move this PR to create a new package.

@ignatz
Copy link
Contributor Author

ignatz commented Jul 7, 2025

BTW, thinking about this PR made me realize we really should have collection types be in their own packages so e.g. if you want to do a major release you can #235

Sounds good. I was thinking the same, let alone when adding the backend-specific dependency.

We'll be migrating the other packages in the next day or two so you can just move this PR to create a new package.

If I understood correctly, we'll table this review until the split has happened for me to rebase? Sounds good, just ping this PR and I'll get the train rolling.

Did you think about the example, should we handle it in a follow-up?

Thanks!

@KyleAMathews
Copy link
Collaborator

The refactor is merged so you can now move your code to a trailbase-db-collection package #252

@ignatz
Copy link
Contributor Author

ignatz commented Jul 14, 2025

Awesome! Moved to separate package.

@KyleAMathews
Copy link
Collaborator

Great! I also refactored the example so you can easily add a trail base version. Could you look at doing that? The docker backend perhaps could have a trail base setup too?

@ignatz
Copy link
Contributor Author

ignatz commented Jul 14, 2025

Great! I also refactored the example so you can easily add a trail base version. Could you look at doing that? The docker backend perhaps could have a trail base setup too?

Sure can do. Quick questions:

  • Would you like me to add to the existing example?
  • If so, just add to the existing docker-compose or have a separate compose setup?
  • Would you like to make it part of this initial PR?

@KyleAMathews
Copy link
Collaborator

Yeah same example. It's meant to be an omnibus example so easily see every collection type. And yes, one command to start all of them. And yes in this pr as that'll make it easier to test.

@ignatz
Copy link
Contributor Author

ignatz commented Jul 14, 2025

I added TrailBase to the example. I tried to fumble my way through...

  • Additions and deletions work, however update both for the config and todo fail due to zod validation. I have differnt data types. I already made created_at and updated_at strings, which worked for insertions but not for updates 🤷‍♀️

@KyleAMathews
Copy link
Collaborator

hmm interesting — you're using the zod schemas from drizzle it looks like? So you should use zod schemas consistent with the trailblaze schema? I suppose you can't have Date types w/ sqlite?

@ignatz
Copy link
Contributor Author

ignatz commented Jul 15, 2025

hmm interesting — you're using the zod schemas from drizzle it looks like?

That my understanding, at first I tried to make mine compatible because I didn't necessarily want to change the downstream code.

So you should use zod schemas consistent with the trailblaze schema?

I guess so.

I suppose you can't have Date types w/ sqlite?

SQLite has a DATETIME type, which internally is just an INT64. That said, for type-safety reasons TrailBase requires STRICT mode (see migrations), which doesn't allow DATETIME. W/o STRICT, types are merely affinities and SQLite let's you stick any value into any column :)

@KyleAMathews
Copy link
Collaborator

Ok — yeah the other collections serialize & deserialize to/from Date objects — I imagine most people might want that for Trailblaze? Perhaps you could add a parser & serialize config option to the Trailblaze collection?

@ignatz
Copy link
Contributor Author

ignatz commented Jul 15, 2025

Ok — yeah the other collections serialize & deserialize to/from Date objects — I imagine most people might want that for Trailblaze? Perhaps you could add a parser & serialize config option to the Trailblaze collection?

That's an interesting proposal. I would certainly love not to to diverge the downstream code of the example. Could you elaborate a bit how this could look like, is there any precedent for me to look at? Thanks

EDIT: Would this just be two functions:

parser: (record: Record) -> TItem,
serialize: (item: TItem) -. Record,

? If so, yeah, yeah I'll do that. It will certainly be a good starting point.

@ignatz
Copy link
Contributor Author

ignatz commented Jul 15, 2025

Ok, I found

timestamptz: (date: string) => new Date(date),
, which is probably what you meant. I'm not sure the same approach would work for me, since my base type is just INTEGER as opposed to PG TIMESTAMPZ.

Anyway, it works now 🎉 . Do you think this is a workable starting point?

@KyleAMathews
Copy link
Collaborator

Nice!

Yeah, parsing/serializing the whole row works — perhaps doing it per column would be better though as for big tables, it'd be tedious to have to pass through all the untouched stuff. Electric has a parser by pg type as you found.

@KyleAMathews
Copy link
Collaborator

I tested it briefly — update works if I refresh the page after adding a todo. But not if I add it and then try to check it off. Changing the color of the background doesn't work either.

Screenshot 2025-07-15 at 7 05 22 PM

@ignatz
Copy link
Contributor Author

ignatz commented Jul 16, 2025

perhaps doing it per column would be better though as for big tables, it'd be tedious to have to pass through all the untouched stuff.

I like that, I'm just not sure my TS foo is strong enough. I'm aware that it can render Doom, but how would I define/infer a type Parse as follows:

type TItem = { 
 id: string;
 created: Date;
}
type TRecord = {
 id: string;
 created: number;
}

type Parse = {
 id?: (id: string) => string;
 created: (id: number) => Date;
}

function parse(parse: Parse, record: Partial<TRecord> | Record) : Partial<TItem> | TItem;

Instead I rewrote the serialize/parse implementations to only explicit set the relevant fields. Do you think this could be a workable starting point?

{
  parse: (record: Todo): SelectTodo => ({
    ...record,
    created_at: new Date(record.created_at * 1000),
    updated_at: new Date(record.updated_at * 1000),
  }),
}

I tested it briefly — update works if I refresh the page after adding a todo. But not if I add it and then try to check it off. Changing the color of the background doesn't work either.

My bad. Fixed

TrailBase-TanstackDB.mp4

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