kview is a web application that provides a visual view of data stored in a Deno KV store. It requires the Deno CLI to
be its host.
The application will use the same logic that the Deno CLI does to determine the default cache location for KV stores,
and will enumerate them. The logic Deno CLI uses to cache "origin storage" is to generate a unique hash of the origin.
This means it is not possible for kview to be able to determine what script the store belongs to. Instead kview
allows you to name individual stores it detects, which get stored in a cookie in the browser.
kview allows you to manually add local KV stores where you specify the path to the store like you would with
Deno.openKv("/path/to/store"). If kview is able to access the store it will add it to the local stores. Specified
local stores will persist across runs of the server by persisting information in local storage. When starting up the
kview instance or updating specified local stores, kview will validate that each store is actually a file and remove
any that are no longer valid.
To name or change a name of a local store, click on the store name and either press Enter or click elsewhere to save the value. Pressing ESC will discard any edits.
Navigating to an individual local KV store will allow you to navigate the contents of the store.
You can connect to arbitrary remote Deno KV stores. This is specifically designed to be able to connect to
hosted denokv instances.
Remote KV stores can be added by selecting the Add remote store button which will open an add dialog. You will be
prompted for the URL and access token to connect to the instance as well as an optional name making it easier to
identify the instance.
Currently, there is no easy way to validate a remote connection URL. Deno will continually try to connect to remote locations even if the connection is wrong. Therefore there is a "Validate connection" button when adding or editing the configuration of a remote store.
You can delete the connection information to a remote store by selecting the store in the list of remotes and choosing
to delete it. This will only delete the configuration information held in kview and does not modify anything in the
remote store.
Remote servers are accessible by everyone who has access to the instance of kview and the connection information is
persisted in Deno CLI via local storage, which means they will be persisted from invocation to invocation of the server.
In order to provide connections to remote Deno Deploy KV stores, the application needs to leverage a Deno Deploy access
token. In order to get an access token, you need to be logged in dash.deno.com and navigate
to the Access Tokens part of your account setting and create a new access
token.
You can then use that token to login with kview which will then start displaying your user account and any
organizations that you belong to. Clicking on your user or an organization will list the projects owned by that user or
organization.
Choosing a project will provide a view of what branches can have KV stores associated with them and navigating to a branch will start displaying the contents of the KV store.
The current access token is stored locally within the browser as a cookie, meaning that access token is not shared across the server.
Once you have navigated to a specific KV store, you will be provided with the contents of the store.
Keys in Deno KV are made up of key parts, which allow you to easily form a hierarchy of keys and values. For example you
have have ["person", 1] and ["person", 2] as keys. kview works on the concept of navigating a KV store by
navigating key parts, where keys are grouped into shared key parts.
For the example above, a key part of person would be displayed and navigating to person would then display two key
parts of 1 and 2. Navigating to those key parts would display the value associated with the key.
If a key part is associated with a key that does not have any sub keys, only a value, the key part will display a right arrow:
If the key part is associated with a key that does have sub keys (and potentially a value), the key part will display an expand icon:
As key parts are descended the Path will be updated, allow navigation back up the stack of key parts. Navigating to the home icon in the path will bring you back to the root of the store.
When navigating to a partial key that does not have a value associated with, the value display will display no value. This different than an actual null value, which is supported by Deno KV.
Deno KV is limited to values of a max of 64k in size. This can make it challenging to manage arbitrary binary data. In
addition, currently Deno KV does not support storing Blob or File
instances, though they are cloneable and should be able to be stored.
To work around these challenges, kv-toolbox provides the ability to store
arbitrarily size blobs and can handle setting values to Blob, File, array buffers, typed arrays, and byte
ReadableStreams. It accomplishes this by storing the binary data into chunks that avoid the 64k value limit along with
meta data about the original form of the data.
kview integrations kv-toolbox to allow management and viewing of the blobs. The user interface detects the blobs and displays them in the way they are intended, as a single entry, though they are made up of several component entries in reality.
For File and Blob entries, kview will detect the any associated context type and if it is media that is viewable
within a browser, it will be displayed as part of the view of the entry value.
Each blob value will have a download link associated with it, which will allow you to download and save the blob.
kview allows adding or updating blobs. When adding an entry or updating the value of an entry, the Value Type will
allow you to select Binary Data, Blob or File and the value will be a file selection input. Binary Data will be
stored as the blob type of a buffer which can be retrieved as a Uint8Array or byte ReadableStream, while Blob and
File will be stored and retrieved as Blobs and Files.
kview supports import data into a Deno KV store in the format of new line deliminated JSON
(ndjson), where each entry is provided as a standalone JSON object delimitated by a new line.
While exploring a KV store, an Import... button will be available. Clicking on the button will bring up a dialog to
select the file to import into the target KV store.
To see information about import jobs, you can select Jobs on the left hand side. The current status will be provided along with other details. Job information is only stored in the memory of the current server, so will disappear when the server is restarted.
kview supports exporting data from a Deno KV store in the format of new line delimitated JSON
(ndjson), where each entry is provided as a standalone JSON object delimitated by a new line. The
main reason for this versus a pure JSON output is that the format supports streaming.
When exploring a KV store, an Export... button will be available. When clicking on the export button, a confirmation
dialog will be displayed. When at the root of the store, the export will export all the entries from the store. When
having navigated to a sub-key, only the entries which have a prefix of the current key will be exported.
Also because the of rich set of key types and value types that Deno KV supports it is necessary to reformat key parts and values into forms that can be fully serialized in JSON. The interface for each line is:
interface KvEntryJSON {
key: KvKeyJSON;
value: KvValueJSON;
versionstamp: string;
}Of which you would expect an entry with a key of ["a"] and a value of "string" to look like this:
{
"key": [{ "type": "string", "value": "a" }],
"value": { "type": "string", "value": "string" },
"versionstamp": "000000000001b3950000"
}A full set of TypeScript types describing how KV entries are serialised is available in
@kitsonk/kv-toolbox/json.
Pressing the Delete... button in the KV explorer will bring up a tree view of all keys that are children of the root
or current key. Selecting keys in here will allow multiple entries to be deleted at once.
When browsing entries there will be an eye icon. When selected this will store the entry to be watched:
Navigating to the Watch section will display all valid watches grouped by KV store and continue to monitor them. A watch can be removed by clicking on the trashcan icon on the entry card:
Deno KV supports keys of a size of up to 2k. Each type of key part is supported by kview.
| Type | Supported | Notes |
|---|---|---|
| String | ✅ | |
| Number | ✅ | Key parts are entered as digits only |
| Boolean | ✅ | Key parts are entered as true or false |
| BigInt | ✅ | Key parts are entered as digits only |
| Uint8Array | ✅ | Key parts are entered as URL safe base64 encoded strings, the value of the key part is not displayed |
Deno KV supports any JavaScript built-in types that are supported via structured clone. The values are limited to 64k in their stored format. kview via kv-toolbox add support for three blob types. These have no hard size limit. The support table is seen below:
| Type | View | Add | Update | Notes |
|---|---|---|---|---|
| String | ✅ | ✅ | ✅ | |
| Number | ✅ | ✅ | ✅ | Deno KV stores NaN and Infinity, but currently kview cannot display them as values or allow you to set or update to those values. |
| Boolean | ✅ | ✅ | ✅ | |
| BigInt | ✅ | ✅ | ✅ | Values are entered/edited as number digits |
| Undefined | ✅ | ✅ | Values can be changed to undefined but the value itself is not editable intentionally. |
|
| Null | ✅ | ✅ | Values can be changed to null but the value itself is not editable intentionally. |
|
KvU64 |
✅ | ✅ | ✅ | Values are entered/edited as number digits |
Array |
✅ | ✅ | ✅ | Values are entered/edited as JSON arrays |
Map |
✅ | ✅ | ✅ | Values are entered/edited as JSON array tuples of key and values |
Set |
✅ | ✅ | ✅ | Values are entered/edited as JSON arrays |
Date |
✅ | ✅ | ✅ | Values are entered/edited as ISO strings in the format of YYYY-MM-DDTHH:mm:ss.sssZ or ±YYYYYY-MM-DDTHH:mm:ss.sssZ |
RegExp |
✅ | ✅ | ✅ | Values are entered/edited as JavaScript regular expression literals (e.g. /abcd/i) |
Error |
✅ | |||
EvalError |
✅ | |||
RangeError |
✅ | |||
ReferenceError |
✅ | |||
SyntaxError |
✅ | |||
TypeError |
✅ | |||
URIError |
✅ | |||
ArrayBuffer |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Int8Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Uint8ClampedArray |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Uint8ClampedArray |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Int16Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Uint16Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Int32Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Uint32Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Float32Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
Float64Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
BigInt64Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
BigUint64Array |
✅ | ✅ | Values are added as URL safe base64 encoded strings. View is displayed as a hex byte viewer. | |
| Binary Data | ✅ | ✅ | ✅ | Values are added/updated by loading files. Only byte length is available as view. This is stored across multiple keys via kv-toolbox. |
Blob |
✅ | ✅ | ✅ | Values are added/updated by loading files. If the type can be displayed in a browser, it will be displayed. This is stored across multiple keys via kv-toolbox. |
File |
✅ | ✅ | ✅ | Values are added/updated by loading files. If the type can be displayed in a browser, it will be displayed. This is stored across multiple keys via kv-toolbox. |
| JSON | ✅ | ✅ | ✅ | Other objects use the structured clone algorithm and added/updated by entering a JSON value. |
- Deno KV supports key parts that are Uint8Array. While
kviewproperly handles these key parts, displaying them is problematic. Each unique Uint8Array will be displayed separately, and in the sort order provided by Deno KV, but there is no way to tell one Uint8Array key part from another. kviewcannot determine the "origin" associated with local KV stores.- Deno currently does not handle remote stores well enough to be resilient to accidental user misconfiguration (see denoland/deno#21211 and denoland/deno#21263. When viewing a remote store that is not correctly configured, it will simply appear to "hang", loading indefinitely. Use the "Validate connection" button when adding or updating the configuration to attempt to diagnose configuration issues.
- For local datastores, currently Deno does not support watches where changes are made in other processes (see
denoland/deno#21640). Therefore changes made outside of
kviewwill not be observed via a watch, but a refresh of the page will update any changes to values.
kview is not yet functionally complete. Here is a roadmap of items that would be great to add to kview:
- Improve editing/adding complex values.
- "Flash" updates on watches.
- Document APIs to enable custom integrations.
- More "batch" tooling, like syncing KV stores, etc.
- Ability to upload binary data as an
Uint8Array. - Ability to download
Uint8Arrayas a file. - Improve accessability.
- Ability to change the cache location for local KV stores.
- Allow deep linking into KV store keys and values.
- Integrate the crypto capabilities of kv-toolbox.