30:22Yeah, certainly.
30:23So in the very first instance, I
was just jSON serializing the content
30:29of the store and writing it to local
storage, or to session storage, or to
30:34file, because you can obviously run
TinyBase on a node server as well.
30:38And, that's great, and in 2022 that
seemed like the Basically, you know,
30:45when you're thinking about small stores
anyway that seems like a fine array of
30:49ways to do it, but Obviously people start
to push the boundaries of what you can
30:53store in those media and just serialize
JSON isn't necessarily the way to go
30:56So I think IndexedDB was probably the
next one that I tackled was not as easy.
31:00, just Just as a small side
note, IndexedDB is not the most
31:05enjoyable API to work with.
31:08Most notably, it lacks any form of
reactivity whatsoever that I know of.
31:12I think there were some proposals
that never went anywhere.
31:15But there's no observability.
31:17So it's kind of Crappy to have
to poll for changes, but , yeah,
31:22I do now have that as well.
31:24So you can either save your in
memory store to IndexedDB or load
31:29it or automatically save to it when
changes happen or automatically load
31:33from it with a polling mechanism.
31:35so that, that, that, that's there as
well and and then around the same
31:40time, in fact, it was Matt Wonlow
that I know it was on your show a
31:43little while back he was working on his
CR SQLite solution and I started to see
31:50that SQLite was starting to emerge.
31:53as as a browser opportunity.
31:57And so I figured, well, you know, there'll
be people who want to store it in the
32:00browser on, on a SQLite database as well.
32:03So I went down the path
of supporting that.
32:06So the tables that were in your
memory store in TinyBase can
32:10now be literally written out
to tables in a SQLite instance.
32:14Or read in, and again,
reactivity is not perfect.
32:19, some APIs are better than others,
but you know, do what I can to, to
32:23keep that as synchronized as possible.
32:26And that then opened the door
to support things like PowerSync
32:31and, uh Turso and ElectricSQL.
32:37, I also did.
32:38PartyKit along the way, which is
not a SQLite store, but it's a
32:42kind of a WebSocket based way of
storing data up in a durable object,
32:46and so it supported that also.
32:49So yeah, there was a period, probably
over the last year or so, that the
32:52version 4 series of TinyBase, if you like,
where each major release was me adding
32:56support for one of these new storage
technologies or synchronization platforms.
33:02The other two that are very worthy of
note are AutoMerge and YJS, so those
33:08are more classic CRDT technologies,
but you can store TinyBase into a
33:13Yjs document, or load it from a Yjs
document, or into an automerge document.
33:18And then, of course, you've
got the benefit of those two
33:20platforms synchronizing in
whatever way they want to.
33:23So, yeah, I guess you could say
I, am providing a lot of options.
33:28Maybe too many.
33:29I, Suspect that when you go to
the website and you see all these
33:31baffling options, you're like, Oh
yeah, but which do I actually choose?
33:34so what I'm hoping to do actually fairly
soon is write a guide for, you know,
33:38this is the kind of app I'm building.
33:39This is the kind of platform I should
use, or this is how I should synchronize.
33:43Do I do the synchronization myself or
do I rely on some third party to do it?
33:47And at the same time, obviously we've
seen companies like PowerSync and
33:51ElectricSQL, you know coming forward
with their, their solutions here.
33:54And so, yeah, if people are using
TinyBase and they want to Provide
33:58a a gateway to those systems,
then that's that option as well.
34:01So yeah, I have tried to
be as flexible as possible.
34:04One of the privileges, I guess, of
working on this as a hobby is that,
34:07you know, I can be open to working with
as many of these partners as possible,
34:12whether they're commercial startups
or just open source projects, right?
34:15I'm not in competition with anybody.
34:18And so if I'm providing a way for
developers to onboard onto these
34:21different things, then that's great.
34:22I definitely have a view that
the, the tide is rising up.
34:26I'm saying that on a boat but the local
tide is rising, local-first tide is
34:30rising, and I'm happy to see all boats
go with it even in the long term.
34:35, even if in the long term TinyBase
becomes not needed because, you
34:40know, all of these other platforms
have, have matured to the point where
34:43they're offering what I already do.
34:44But I think in the meantime, I'm hopefully
providing a nice, disambiguation
34:49layer or you know, something like
that to help people decide what their
34:53approach is going to be without having
to rewrite their app dramatically.
34:57So yeah, today you could store
your TinyBase data to local
35:00storage and tomorrow you could
then sync it to ElectricSQL.
35:03Why not, right?
35:04So in terms of the data that is persisted,
let's say to IndexedDB or OPFS, SQLite,
35:11or synced to one of the syncing providers,
how do you bring the data into memory?
35:18And do you typically, let's say
I have a, let's say I'm using
35:22Turso and have my SQLite database
somewhere, Is TinyBase automatically,
35:27hydrating all of that data from the
database into the in memory version?
35:32Or is there some sort of scoped
version where maybe the database is two
35:36gigabytes and you only can constrain
yourself to 200 megabytes in memory?
35:42how are you handling that?
35:43Right.
35:44So for all of the database based
persisters, I call them, there's a
35:48configuration where you say which
tables you want and, you know,
35:52whether you want to just load from
those tables or whether you also
35:55want to be able to save back to them.
35:57the worst thing I could think of would
be somebody with some large production
36:00database and they connect TinyBase to
it and the next thing you know, it's
36:03tried to load the entire database into
memory or it's tried to write No, back
36:08to the whole database, and then, you
know, that's the end of the world.
36:10So no, it's all very configurable
on a table by table basis.
36:15And the one thing I have not done,
but I'm pretty sure I need to
36:18do, is also provide some kind of
pagination or filtering on that view.
36:23because if you've got a database that
has, let's say you, you, you shard
36:27it on user or something, and you only
want to be able to see just the data
36:31from that user, which, you know, it's
gonna be a pretty common use case,
36:34then make sure that persistence is
not for the whole table, but just
36:38for the relevant rows, of that table.
36:41I think it's going to be
harder than I think it is.
36:43I suspect there are lots
of gotchas to doing that.
36:46, and so for now, there's my, my solution
or my suggestion will be that people
36:51doing this should probably have a per
user database, which is kind of an
36:56interesting approach that I know some
people have started taking anyway,
36:59for, for edge based, databases.
37:02Um, so that, you know, you're,
you're in no danger of, accidentally
37:06loading data from a different
user into someone's browser.
37:09But no, that's definitely
something I need to tackle.
37:12So it's scoped, to answer your question,
it's scoped to individual tables as
37:16to whether it's load or save or both.
37:18But I think over time we
need to add more pagination.
37:21So that you are just looking at,
you know, the top 10 records,
37:23100 records, or what have you.
37:25The reactivity gets really tricky
at that point because I'm sure you
37:29know, you know, SQLite's reactivity
out of the box is pretty weak.
37:32At best, you're going to
know that a table changed.
37:35And what are you going to do?
37:36Query the whole table to find out
which row it was that changed.
37:40And so knowing that it was row 47 out of
2 billion that was the one that changed.
37:45is not currently something that the
database platforms provide by default.
37:49Um, So, that's one thing where I
am really having to work around
37:54those limitations right now.
37:56, and I'm hoping, if I can't make it
clearer to you, I'm hoping that people
37:59working on SQLite are going to crack
this and provide, you know technologies
38:03that make it easier to synchronize
at a much more granular level, or get
38:06reactivity at a much more granular level,
so that TinyBase isn't having to poll
38:10everything in a way that doesn't scale.
38:13Yeah, I mean, I, I think, Ideally
for SQLite, the most principled and
38:21foundational approach would be to
rebuild SQLite from the ground up to
38:27be incremental and to be reactive.
38:29And I think actually a former coworker
of yours, who is um, Julian, who
38:35has also created, like HipHopVM
at, at Facebook and, and HackLang.
38:40he's actually trying to, to do that with
a new startup called, Skip that is a
38:45very ambitious, or even audacious goal to
build the whole new database from scratch
38:50to be reactive, from the ground up.
38:53Which I think is very, very interesting,
but short of that, I think you, you're
38:57left by imposing, reactivity, primitives
on top of SQLite and the best you can
39:04do there is to do the minimal amount
of work, you need at a given situation.
39:09So instead of pulling the entire table
that, you know, okay, row 47 has changed.
39:16And that requires quite a bit of like
a reactivity system on top of it.
39:20And so luckily with, a signal like
system, that is a, it's a pretty
39:25good, primitive to put on top of
it, to implement that reactivity.
39:30But, yeah, it's not as efficient
as you, if you'd build it
39:33from the, from the ground up.
39:35That being said, SQLite is so fast that
you get a lot of performance benefits out
39:40of the box and you can get away with it.
39:42Yeah, that's true.
39:43you know, certainly on the client.
39:44Um, yeah, I, I, without, you know,
sharing too much, internal stuff,
39:49there was a big push, at Facebook.
39:51I'm thinking six, seven years ago, you
know, to think about reactivity for
39:56the entire Facebook stack, because this
concept of, you know, taking the ideas
40:00of React that were out on facebook.
40:02com and bringing them all the way back
through the web servers, which are
40:06HHVM, all the way through to the data
stores that were being used at the
40:10company, you know, like it's a utopian
vision, but like, if you can make
40:14that push based all the way through.
40:16That's spectacular.
40:17and you know, Julian and I were
probably in many of the same, uh
40:22discussion groups and, you know,
internal Facebook groups where a lot of
40:25these ideas were being bounced around.
40:27And, and so yeah, when he left and
went off and did, Skip and you know,
40:31I guess maybe some of this informed my
thinking about TinyBase too, you know,
40:36that dream is still very much alive.
40:40and yeah, it's coming from, ironically,
it's like it's coming from React.
40:44That idea is coming from React.
40:45It's just like, well, okay, can we bring
that idea a little bit further back,
40:48and then a little bit further back,
and then a little bit further back?
40:51Oh, like, and then we
end up on the database.
40:53Like, why can't we get the database to be,
you know, telling us about these changes?
40:57And, yeah, I guess that
would be the vision.
41:00Unfortunately, I haven't checked in
recently, but I think SkipDB wasn't
41:04Wasn't at a level where I could start
working with it, when I last looked.
41:08Um, so yeah.
41:10I think it's not yet fully production
ready, but as far as I know,
41:13they're just still working on it.
41:15So in terms of the query layer
for TinyBase, you have, not
41:21implemented SQL as a query language
on top of your own data store.
41:25Um, so yeah.
41:25But you've provided, given that
JavaScript or TypeScript is the
41:29primary way how you interact with
it, you've just embedded a DSL, as a
41:34query language directly into TinyBase.
41:36So would you mind briefly describing
that and, how that describes a user
41:40experience or the developer experience?
41:42Right, right.
41:43So the, the journey here for me was
that first I knew there were going
41:47to be some very simple query like
primitives that I wanted to have.
41:51So one is, like a metric, which
is some kind of, you know, number
41:57derived from the content in a table.
41:59And I knew that that was going to be the
first thing I wanted to have if I was
42:02building this hypothetical GitHub app.
42:04I was going to want to have a number
in the top that said number of repos,
42:07and I was going to want to have a
number that said number of commits.
42:10And so I actually baked in.
42:12a kind of a metrics oriented DSL where you
can define a metric which is, you know,
42:19basic aggregates, counts, averages, sums,
those sorts of things, which by default
42:24is normally just counting the rows in a
table, but that is then a reactive entity.
42:29So again, you can say, I just want
this span in the top right hand
42:33corner of the window to just always
show whatever that metric was,
42:36and then you can forget about it.
42:38And if that table is updated, You
know that number's going to change,
42:40TinyBase will take care of it.
42:42another thing that I knew I
was going to need to do was
42:44relationships between tables.
42:45So I built a very specific thing for
just one local table, one remote foreign
42:51table, and then like keys between them.
42:53So the value of one column in one table
is used as the identifier for another.
42:57And so, yeah, you want to see the issues
just for this repo, or you want to see
43:01the repos just for this user, then you'll
be able to do those kinds of things.
43:04So those are, were actually baked in
pretty early to TinyBase, just because
43:07they seemed Very important, but I, I
guess I knew eventually people were
43:13going to want to push that on and start
doing things like arbitrary queries.
43:20And I toyed with the idea of, you
know, supporting SQL in some form.
43:26And I should say, I love SQL.
43:28I have been writing SQL most of
my professional career, which
43:30you know, goes back a fair way.
43:33And my most recent role at Facebook
was, you know, the data analytics
43:37team in the data infrastructure org.
43:40So you know, we were working
with SQL all the time.
43:43Perhaps despite that, or because of
that, I kind of got nervous about doing
43:47an arbitrary SQL parser, evaluator,
executor, and then being able to make
43:53the results reactive, which was like,
that's the, that's That's the non deniable
43:58requirement, like, it has to be, reactive.
44:01So, I didn't really have a lot of
choice, but, oh, and by the way, you
44:06know, a full SQL parser with all the
dialects you'd want is, like, it's
44:09gonna quadruple the size of TinyBase.
44:12It's just, it's code based.
44:13So, no longer tiny.
44:15Yes.
44:15So, I wanted to come at it from
a slightly different direction.
44:19I know I'm not the only person to have
thought of doing more like a DSL approach
44:22to this, but I, I wanted to see whether
I could capture as much of the, the
44:26valuable parts of SQL without turning
it into a place where people could build
44:31stupid cartesian joins and kill their app.
44:34so I wanted to make it kind
of a little bit on rails.
44:37And yeah, it was the idea of TinyQL was
born, which is kind of a stupid name.
44:41But it's, as you said, a DSL
that allows you to, you know,
44:45select, where, group, limit.
44:48, actually, no, I don't
have a limit in there.
44:50I limit a later part in the pipeline.
44:53But, yeah, basically allows
you to join tables together.
44:56and then where them, there's havings and
groups and those kinds of things too,
45:02which like really is what 98 percent
of people want to do with SQL anyway.
45:07And haven't really come across too
many queries that I can't express
45:11with these five or six quote keywords.
45:14Yeah, the cool thing about
SQL is you can do anything.
45:17The awful thing about SQL
is you can do anything.
45:19And, I have worked with enough people
who thought they knew what SQL did and
45:24didn't quite know what it did to, you
know, see the trouble you can get into.
45:27So I really, yeah, wanted to make it a
little bit more constrained than that.
45:31And it's, it's been,
it was a real journey.
45:33That was a very tricky, for me, anyway.
45:35, that was a very tricky thing to
build, especially making sure
45:38that all the results are reactive.
45:39Because, by the way, you know,
any of those tables could change.
45:43Any of the rows in those
tables could change.
45:44In fact, you don't want to react
to the changes of the results if
45:47some of the irrelevant rows change.
45:49You only want to know if it was
the relevant rows that changed.
45:51So you have to set up listeners on
all the things that were relevant and
45:54not the things that were irrelevant.
45:56so that ended up being a little
harder than I thought, but yeah,
45:59pretty proud with how it turned out.
46:00And as a result, and I would urge
people to go check this out, You can
46:04build kind of interesting analytics
apps, right, with this, in the browser.
46:09So if you go to the TinyBase.
46:11org demos, you'll see there's a demo.
46:14I think it's called car
analytics or something like that.
46:17And it takes a data set of car
data, different models, different
46:20makes, miles per gallon, years.
46:23So there's a bunch of numerical measures
and there's a bunch of dimensions.
46:27And in the browser, it loads
all the data in pretty quick.
46:30It's not that much data, but you
know, loads it in pretty quickly.
46:32And then you can do groups,
sorts, filters, across all
46:35of this data in the browser.
46:37And it's like, it's completely instant.
46:39It's like, great, love it.
46:41and look, this is not going to be
great for querying the Facebook data
46:44warehouse, however many hundreds of
petabytes that is these days, but
46:49it is going to be fine if you've got
10 or 100, 000 rows in your browser.
46:53And Don't be scared, people.
46:55Like, getting a hundred thousand rows
of data into a browser is not hard.
46:58The browser is perfectly
capable of doing that.
47:00You know, most even phones
are very happy to run that kind
47:04of sized data in, in memory.
47:06so yeah, for a lot of even analytics
use cases, you can do, you could, you
47:09could build interactive dashboards
with this kind of technology and
47:13have a sort of constrained set of
queries all running off TinyBase.
47:17And it's super feasible, and it's been.
47:20It's been fun to build that.
47:22Whether or not people are using
it in the wild, I don't know.
47:24I should say, I don't put any
instrumentation into this product.
47:27So who knows what people are using
it for, or how they're using it.
47:31But I hope that those people who use
it do, do find the value of being
47:34able to run queries, without, shooting
themselves in the foot with SQL.
47:37Did you follow any sort of prior
art in regards to how you built
47:41that reactive query system?
47:43So, as I was working on a similar
part as, the work on Rffle, there,
47:48there was, some prior art in
regards to Adapton and mini Adapton.
47:53And so this was, some inspiration,
that we followed for the reactivity
47:57system and we've like over time learned
that, it's very similar to how now like
48:04signals is all the rage these days.
48:06It's like very similar
in terms of the ideas.
48:09So did you follow some,
some similar paths?
48:12No.
48:13And I wish I had.
48:14I think it's one of my weaknesses.
48:16One of my weaknesses is
that I look at a problem.
48:18You know, it's like the
famous Hacker News thing.
48:19It's like, I could have
built that in a weekend.
48:22I, I look at a reactive query system.
48:23I think, yeah, I'm sure
I could build that.
48:25And then like two months later, I
was like, I wish I'd read a bit more.
48:30I am not good at prior art and
reading scientific papers or even
48:35just, you know, looking at other
projects to see how they're done.
48:37I think, you know, I know what
the result should be and I'm
48:39going to try to build it myself.
48:40And then I get into trouble.
48:42Fortunately, I worked
my way out of trouble.
48:44If it makes you feel any better,
even with knowledge of the prior art,
48:48it still took easily more than two
months just to get anything working.
48:53So,
48:55Okay, that's just, that's just my,
my weakness that fortunately I
48:59was able to work around this time.
49:00But yeah, I think the other thing is
that I obviously knew in intense detail
49:06how the reactivity of the underlying
tables, rows, and cells were right.
49:11And so I knew how I was gonna have to
cascade the listener trees into all
49:16the relevant parts of the database.
49:18And, That was, yeah, that was just
something I had to figure out for myself.
49:23The other thing I alluded to
earlier is that TinyBase is
49:27just draped with test cases.
49:29Like, I am exhaustive, overly exhaustive.
49:32I'm completely OCD when
it comes to test cases.
49:35It's not quite TDD.
49:37I don't always do the tests first,
but, you know, I do eventually try
49:41to make it look like I did TDD.
49:42So I built every possible query I can
think of, and I build all these demo
49:46apps, and I build all these sample,
you know, fragments of code, and
49:50they all get tested exhaustively, and
so I figure out, well, once, once,
49:55once those work, I'm probably there.
49:57So that, that was my
benchmark, and I got there.
49:59It's probably, I'm sure it's
still possible to break it,
50:02but, you know, I think, I think
I'm about where it needs to be.