Simple Value Viewer API


Part of what makes RunKit great for data exploration are the intelligent renderings we provide for special data types. We refer to these as Value Viewers, and RunKit provides a large library of built-in viewers automatically. On such example is the Map Viewer you're probably familair with from the Welcome Document:

The Map Viewer appears by default whenever RunKit thinks the object in question looks like a geographic coordinate or GeoJSON. However, there are many cases when RunKit's built-in viewers might not be sufficient and you want to provide a rich viewer of your own.

Building Your Own Value Viewers

RunKit exposes a simple API which gives users and package maintainers control over how their outputs are rendered. This API actually leverages the built-in HTML viewer under the hood, allowing you to render any arbitrary web page for your viewer. To create a new viewer, simply require the ValueViewerSymbol from the @runkit/value-viewer package:

const { ValueViewerSymbol } = require("@runkit/value-viewer")

You can create a custom property in any object using this symbol that contains a title and HTML field. RunKit will check any value that is output for this symbol. If it exists, it will use the contents of that property to render a custom viewer:

const { ValueViewerSymbol } = require("@runkit/value-viewer");
const myCustomObject = {
    [ValueViewerSymbol]: {
        title: "My First Viewer",
        HTML: "<marquee>๐Ÿ”Hello, World!๐Ÿ”</marquee>"
    }
};
    

Case Study: Package Value Viewer

Let's now create a simple viewer as an example. Imagine we are creating a simple API to help users find out about packages on NPM. We can start by simply grabbing the package's data directly from the registry. When you evaluate this code, you'll get a lot of data from the JSON:

const getJSON = require("async-get-json");
const NPMURL = "https://skimdb.npmjs.com/registry/";

async function getPackageData(aPackageName)
{
    return await getJSON(`${NPMURL}/${aPackageName}`);
}

await getPackageData("lodash");
    

We can improve on this by providing a value viewer with a concise summary:

const { ValueViewerSymbol } = require("@runkit/value-viewer");

async function getPackage(aPackageName)
{
    const result = await getPackageData(aPackageName);
    const { description, "dist-tags": { latest } } = result;
    const title = "Package Value Viewer";
    const HTML = `${aPackageName} (${latest}) - ${description || ""}`;

    return Object.assign(result, { [ValueViewerSymbol]: { title, HTML } });
}

await getPackage("lodash");
    

However, we can take things a bit further now by providing some CSS and wrapping it in an ES6 class. We're also hosting some images using a RunKit endpoint, but you can use any CDN you choose, its just HTML: