ZettelKasten part 4
The danger of the rabbithole
This is a followup to a previous article, ZettelKasten Part 3
In the previous article, we set up Grakn and created a basic API. In this article, we'll upgrade to the Grakn alpha and write our own client.
Just Kidding
That was originally what I wrote because I literally started going down that path. That led to lots of delays. When working on personal projects it's easy to get to a point where you want everything to be perfect, but as I said previously the point of this series is to build it fast. Although I might prefer a nicer client for Grakn, I'll leave that to later as a refactor.
In case you're wondering what I wanted, I wanted to turn something like:
const writeTransaction = await session.transaction().write();
await writeTransaction.query(graql);
await writeTransaction.commit();
await session.close();
await client.close();
Into something like this:
const session = await client.session('zettelkasten');
await session.transaction().write().query(graql).commit().close();
await client.close()
In case you're wondering what's going on there: it's a custom implementation
of a PromiseLike<Session>
. You can call methods on the promise and it
returns a promise by then
-ing itself with the resolution of its current
promise and calling the method on the resolved value. Essentialy it replaces
lots of awaits
or thens
with some nice sugar. I'm actually going to make
that, but I've decided to write a proper library. Gonna call it HyperPromise,
and it will enable objects with lots of async methods to return promises which
also have functions which enable chaining based on the (nominal) resolved type
of the promise. It will use proxies and reflection to accomplish this, and I'm
certain it will be a pain to write in Typescript. I know it will, because I
already took a crack at it and it was a pain to write in Typescript. But I
learned a lot and I'll now shelve it because I have current project and I
really ought to finish it. Zettelkasten. Let's go.
First let's continue with a modified version of my original draft of this article.
Upgrading Grakn
It's bothering me knowing I'm going to have to scrap so much ahead of the new
Grakn 2.0. I want the advantages that Grakn 2.0 has, but there's so much in
the air right now. The new Grakn node client isn't quite there, it doesn't
have full support yet. But I know what I want, so I'm going to write my own
client. [Editors note: he didn't]
Yeah, I know it's a diversion, but I hope others will find it useful.
[Editors note: they won't]
Upgrading our Grakn
docker run --name grakn -d -v $(pwd)/db/:/grakn-core-all-linux/server/db/ -p 1729:1729 graknlabs/grakn
Alright. Note the different ports than in the official documentation. The documentation is not up to date yet, but still recommends you choose the "latest" which actually fails to work if you follow the documentation.
And back on track
To reiterate my promise, here's what I said I would do next:
- I need to write a serializer for these things
- I need to write a middleware that handles the schema concept retrieval. There's a few reasons for that:
- We can actually use the root schema object to retrieve available attributes
- We can then validate those attributes and
- We can automatically retrieve them from the body of the request.
The same Concept APIs can be used to handle both aspects.
But this works for now. More to come! Those two things I mentioned PLUS I'll be finishing out the general Zettel API (updates, get individual, delete) PLUS I'll see how far I can get on a basic UI.
So let's get on that. Next time, and soon.
The adventure continues in ZettelKasten Part 5