Kitten

Explore Kitten’s build-in session support and how to store data scoped to individual sessions.

Topics covered

Different kittens for different folks

We’ve just seen how we can keep a persisted count of kittens.

The count, however, will be the same at any given time for anyone who visits the site.

So, if I visit the site from my computer and see 10 kittens and you visit the site right afterwards from your phone, you’ll see 11 kittens (because my visit raised the count by one).

This is because we’re persisting a single kitten count.

But what if we wanted every person who visits the site to have their own kitten count, as special and unique as they are?

Enter, sessions.

Sessions, cookies, and JSDB

Kitten has built-in session support to make implementing sessions trivial in your sites.

Since the protocol of the web (HTTP) is stateless, we need to use a database if we want to persist information. But what if we want to persist different information for each person that visits our site?

💡 Or, more precisely, for each browser that visits our site. (More precisely, you will get two different sessions if your browser has as persisted/regular mode and a temporary/private/incognito mode.)

Clearly, we need a way for our server to know that the request that just came in belongs to the same browser that sent that other request a few minutes ago. While there are different ways to do this, the method that Kitten uses is based on cookies.

💡Wait a minute… aren’t cookies evil things that Big Tech uses to violate your privacy?

Yes, and no.

You see, there are two types of cookies: first-party and third-party. The latter are what’s used to track you. The former enable sites to implement basic functionality like sessions.

To make it easier to remember, think of first-party cookies as the ones your mom bakes for your birthday and third-party cookies as the ones a wicked witch makes to lure little kids into her hut.

The great thing about having built-in support for sessions is that you don’t have to worry about any of this. Whenever a request comes into one of your routes, you can simply access the session object for it using:

request.session

So what it that object?

It’s simply an object that’s persisted in your site’s database.

💡You can see the session objects that are generated by your site by viewing the sessions table in your database. For example, on my machine, I can view the sessions table for the project in kitten-playground by running the following command from the project folder:

kitten _db tail sessions --all

(Look at Kitten’s console output to get the path for your machine/operating system.)

While you can pop your data straight into the built-in sessions object, if you do that, you should be careful not to overwrite any of the required properties that are already in there. These are id, createdAt, authenticated, redirectToAfterSignIn, and challenge. Apart from these reserved properties, you can name your properties anything you want and it’s a good idea to namespace them under your own objects to minimise the risk of name clashes.

Using the built-in sessions object to store per-session data is the easiest option and, as with many things in Kitten, it’s there to make it easy for you to get started and to whip up quick experiments, etc. For larger/longer-lived apps where maintenance is importance and where you might want to store custom datatypes (i.e., custom class instances) in your sessions, you should create your own sessions object in your own db and store your data there and specify the custom classes you want to be stored in your database app module.

💡 Session objects are EventEmitter instances so you an .emit() and listen for events on them. This is useful, for example, if you have a Streaming HTML handler and you it to be notified from others routes – like a POST route used to upload files, for example. In fact, this is exactly what Kitten’s own internal Settings app does when you upload a database backup during a database restore.

Kitten Count (with sessions)

So let‘s update our original persisted Kitten example to keep a separate count of Kittens for each browser that accesses it:

export default function ({ request }) {
  if (!request.session.kittens) {
    request.session.kittens = { count: 1 }
  }

  return kitten.html`
    <h1>Kitten count</h1>
    <p>${'🐱️'.repeat(request.session.kittens.count++)}</p>
  `
}

Now run the example using the kitten command and hit it from different browsers. You should see that each has a different count of kittens.

To see the cookie that Kitten sets, open up the Storage tab of your browser’s developer tools and look under the Cookies section.

Delete the cookie and see what happens.

You can find this example in the examples/kitten-count-sessions folder of the Kitten source code. There’s also a more complicated session-based example in examples/trivia that uses the session to store a person’s game state.

Right, now that you know how you can easily work with sessions in Kitten, how about we take a peek at an advanced feature – Database App Modules – a way of working with JavaScript Database (JSDB) that lets you store instances of custom classes and take advantage of type safety in your databases.

Next tutorial: Database App Modules