The JS runtimes
Published in

The JS runtimes

Web Storage APIs in Deno

Introduction

From v1.10, Deno comes with support for web storage APIs. The web storage APIs have been very popular with front-end work to store a small amount of simple data (key-value pairs) in the browser’s storage. As Deno’s theme is to support web APIs wherever possible, this is a good addition to Deno. The web storage APIs are specified in https://html.spec.whatwg.org/multipage/webstorage.html#webstorage.

Types of storage

There are two types of storage in Deno based on their persistence:

  • Session storage: This is a temporary in-memory storage created for the duration of a process. This storage loses all the data when the process terminates. This storage can be used as a global memory for the process.
  • Local storage: This is a permanent storage that is created on the disk. This storage maintains data across process restarts.

Data format

Regardless of the type of storage, the data is stored in simple key-value pairs. If needed, values could be a stringified JSON to store structured data.

Data structure

Deno uses SQLite database (https://www.sqlite.org/index.htm) to store the key-value pairs. The actual storage depends on the type:

  • For session storage, the SQLite database resides in memory
  • For local storage SQLite database resides on the disk.

The persistent database is keyed on the location that’s supplied in the command-line argument --location . The temporary database is not keyed.

There is a single table created for each location for persistent storage or for session storage. The table is always named data , and it contains two columns:

  • key: This column contains the key (type VARCHAR). It must be unique.
  • value: This column contains the value (type VARCHAR).

For local storage, the data is keyed on the location argument --location .

local storage for http://abc.com:/Users/mayankc/Library/Caches/deno/location_data/4931ff74b86f4ade4f62ab4b14c8dd5563fa79c7eee8524b939759c1c53e6abb/local_storagelocal storage for http://def.com/Users/mayankc/Library/Caches/deno/location_data/b055868c702511abb2fde73c44f727ff05028d7cac734b72d9b5cd0a0603b277/local_storage

Personal opinion: SQLite is a bit too much for simple KV pairs. Perhaps Deno should have chosen something more simple.

Queries

As SQLite is used for storage, working with data requires sending queries to the database. Here are the equivalent queries for common operations like length, set, get, remove, etc.

  • Create table: CREATE TABLE IF NOT EXISTS data (key VARCHAR UNIQUE, value VARCHAR)
  • Length of storage: SELECT COUNT(*) FROM data
  • Set a key-value: INSERT OR REPLACE INTO data (key, value) VALUES (?, ?)
  • Get a value: SELECT value FROM data WHERE key = ?
  • Remove a key: DELETE FROM data WHERE key = ?
  • Truncate storage: DROP TABLE data & CREATE TABLE data (key VARCHAR UNIQUE, value VARCHAR)

Limits

Deno can store up to 5 MB of data in either of the storage.

Scope

The storage is available only in the main worker. They aren’t accessible in web workers.

Usage

The way the storage are used is the same. They both have the same API. Here are the pre-defined global objects to access the storage:

  • sessionStorage: To access temporary storage
  • localStorage: To access persistent storage

Here is an example to get length of the items in the storage:

sessionStorage.length;
localStorage.length;

The storage comes with a set of APIs. All the APIs are sync. The current thread would be blocked whenever storage is accessed. Here is the list of APIs:

  • length: Returns the number of KVs present in the storage
  • clear: Removes everything from the storage
  • getItem: Returns the value for a given key (returns null if key is not found)
  • removeItem: Removes given key from the storage
  • setItem: Sets a KV in the storage (key and value must be strings)
  • key: Returns the key for a given index. It’s like accessing storage as an array.

That’s all! The API is very simple. Also, it’s very familiar for front-end developers.

Examples

Now that we’ve gone through the theory and APIs, let’s see some examples. We’ll start with session storage, followed by local storage.

At process startup, sessionStorage is empty:

sessionStorage.length; //0

Next, let’s set some keys in the temporary storage:

sessionStorage.setItem('A', 'B');
sessionStorage.setItem('C', 'D');
sessionStorage.setItem('E', '200');
sessionStorage.setItem('F', JSON.stringify({a:1, b: true}));
sessionStorage.length; //length = 4

Next, let’s get some keys:

sessionStorage.setItem('E', '200');
sessionStorage.setItem('F', JSON.stringify({a:1, b: true}));
sessionStorage.getItem('E'); //200
sessionStorage.getItem('F'); //{"a":1,"b":true}

Next, let’s remove some keys:

sessionStorage.removeItem('E');
sessionStorage.removeItem('F');
sessionStorage.length; //2
sessionStorage.getItem('E'); //null
sessionStorage.getItem('F'); //null

The temporary storage can be cleared anytime. If not, it anyways clears when process terminates:

sessionStorage.length; //0
sessionStorage.setItem('A', 'B');
sessionStorage.setItem('C', 'D');
sessionStorage.setItem('E', '200');
sessionStorage.setItem('F', JSON.stringify({a:1, b: true}));
sessionStorage.length; //4
sessionStorage.clear();
sessionStorage.length; //0

Now, let’s move on to some examples of local or persistent storage. This type of storage needs --location argument as the table is keyed on location. This is the same as how it works in browser. The local storage is persistent across restarts. The API is the same as sessionStorage. Therefore, we’ll go over the differences rather than the API.

First, let’s see how local storage works across process restarts. Here is the first run of a simple program that creates a unique using current unix epoch timestamp for key:

localStorage.length; //0
localStorage.setItem(`${Date.now()}`, 'B');
localStorage.key(0); //1620969794978
localStorage.length; //1

Now, let’s run the program again:

localStorage.length; //1
localStorage.setItem(`${Date.now()}`, 'B');
localStorage.key(1); //1620969933244
localStorage.length; //2

Here is the third run:

localStorage.length; //2
localStorage.setItem(`${Date.now()}`, 'B');
localStorage.key(2); //1620969964779
localStorage.length; //3

The local or persistent storage can be cleared by calling localStorage.clear function anytime. Here is the fourth run with clear at the start of the program:

localStorage.clear();
localStorage.length; //0
localStorage.setItem(`${Date.now()}`, 'B');
localStorage.length; //1

This story is a part of the exclusive medium publication on Deno: Deno World.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store