HyperMap

A Collection of Interesting Ideas,

This version:
https://hypermap.dev/spec
Editor:

Abstract

This specification defines HyperMap, a JSON-based hypermedia format for REST APIs. It defines the application/vnd.hypermap+json media type, the HyperMap data model, and the programmatic interfaces for interacting with HyperMap resources.

1. Introduction

This section is non-normative.

HyperMap is a format for REST APIs that turns them into explorable, interactive networks similar to the World Wide Web. It is built around two core ideas:

  1. It is self-descriptive — metadata about using the API is embedded in responses themselves, reducing the need for out-of-band documentation or machine-readable specifications.

  2. It supports code on demand — servers can send JavaScript or WebAssembly to the client for execution, enabling dynamic features such as reactive data, streaming, and client-side computation.

A HyperMap resource is a JSON object served with the application/vnd.hypermap+json media type. It uses a reserved # key to carry attributes such as navigation links, HTTP methods, and script references.

When parsed, a HyperMap resource becomes a tree of nodes — maps, lists, and values — that form a DOM-like data model. This tree supports mutation, event dispatch with bubbling, and script execution.

A simple HyperMap resource representing a stock price:
{
  "#": {
    "href": "/stocks/AAPL",
    "scripts": ["/js/price-stream.js"]
  },
  "ticker": "AAPL",
  "price": 187.42,
  "company": {
    "#": { "href": "/companies/AAPL" },
    "name": "Apple Inc."
  }
}

2. Infrastructure

2.1. Conformance

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].

2.2. Terminology

This specification depends on the following:

[JSON]

The JSON data interchange format.

[URL]

URL parsing and resolution.

[FETCH]

The Fetch standard for network requests.

[ECMASCRIPT]

The ECMAScript language specification.

[DOM]

The DOM standard, specifically the EventTarget interface.

[HTML]

The HTML standard, specifically browsing contexts, navigation, and module script loading.

[WEBIDL]

Web IDL type definitions and binding semantics.

2.3. URL Resolution

The base URL of a HyperMap resource is the URL from which the resource was fetched, after any redirects. All relative URLs in a resource — including href values in attributes and script URLs — are resolved against this base URL using the URL resolution algorithm defined in [URL].

This mirrors the behavior of HTML documents, where relative URLs are resolved against the document’s URL unless overridden by a <base> element. HyperMap does not currently define a mechanism to override the base URL.

3. The HyperMap Format

3.1. Media Type

A HyperMap resource is served with the media type application/vnd.hypermap+json.

Servers MUST use this media type for all HyperMap responses. Clients SHOULD use this media type in Accept headers when requesting HyperMap resources.

3.2. Top-Level Structure

The top level of a HyperMap resource MUST be a JSON object (not an array, string, number, boolean, or null).

If an existing API returns a bare array at the top level, it must be wrapped in an object to be a valid HyperMap resource. For example, [{"title": "Learn HyperMap"}] should become {"todos": [{"title": "Learn HyperMap"}]}.

3.3. The # Key

The key # is reserved in HyperMap’s JSON serialization. When present on a JSON object, its value MUST be a JSON object containing zero or more attributes.

An attributes object MAY contain the following members:

href

A string representing a URL, either absolute or relative to the resource’s base URL. When present, the containing object becomes a control.

method

A string representing an HTTP method (e.g., "GET", "POST", "PATCH", "DELETE"). Defaults to "GET" if omitted. Method strings MUST be uppercase. Clients MUST send the method string as-is without normalizing case. Implementations MUST NOT assume a fixed set of HTTP methods — any valid HTTP method is permitted.

scripts

An array of strings, each a URL pointing to a script to be loaded and executed by the HyperMap user agent. Scripts are scoped to the MapNode that declares them. See § 6 Script Execution.

The # key MUST NOT be treated as regular data. Implementations MUST extract it during parsing and store its contents as the attributes on the resulting MapNode.

3.4. Controls

A control is a JSON object whose attributes include an href value. Controls represent navigable references to other resources or actions that can be triggered.

A control’s method defaults to "GET" if not specified. The child nodes of the control (excluding the # key) serve as form fields. For GET requests, form data is serialized as URL query parameters. For all other methods, form data is serialized as a JSON request body.

A list of todos with a control linking to each individual todo, and a control for creating new todos:
{
  "todos": [
    {
      "#": { "href": "5J0rwwsyh/" },
      "title": "Learn HyperMap",
      "completed": false
    }
  ],
  "newTodo": {
    "#": { "href": "/todos/", "method": "POST" },
    "title": ""
  }
}

The first todo has an href pointing to its individual resource. The newTodo control will POST its contents to /todos/ when triggered.

3.5. Value Types

Within a HyperMap resource, values can be:

JSON objects

Parsed into MapNode instances. If the object contains a # key, its contents become the node’s attributes.

JSON arrays

Parsed into ListNode instances.

JSON primitives

null, booleans, numbers, and strings are parsed into ValueNode instances.

4. Data Model

When a HyperMap resource is parsed, it produces a tree of nodes. This tree is the HyperMap data model — the equivalent of the DOM in HTML.

The class hierarchy is:

EventTarget
  └── HypermapNode
        ├── ValueNode
        └── CollectionNode
              ├── MapNode
              │     └── Hypermap
              └── ListNode

4.1. HypermapNode

HypermapNode is the abstract base of all nodes in the HyperMap tree. It extends EventTarget.

[Exposed=*]
interface HypermapNode : EventTarget {
  readonly attribute HypermapNode? parentNode;
};
The interface is named HypermapNode in this specification to avoid collision with the DOM’s Node interface. Implementations MAY use the name Node internally.

Every HypermapNode has a parent, which is either another HypermapNode or null. The root node of a HyperMap resource has a null parent.

A node’s parent is set when it is attached to a tree and MUST NOT be changed after attachment, except by internal tree operations (reparenting).

4.1.1. Event Dispatch

When dispatchEvent() is called on a HypermapNode, the event propagates through the tree following the event dispatch algorithm defined in [DOM]:

  1. Capture phase: Starting from the root node, the event is dispatched on each ancestor down to (but not including) the target node. Only listeners registered with capture: true are invoked.

  2. Target phase: The event is dispatched on the target node itself.

  3. Bubble phase: The event is dispatched on each ancestor from the target’s parent up to the root node. This provides event bubbling through the HyperMap tree.

Listeners may call stopPropagation() to prevent further dispatch in any phase.

4.1.2. Reparenting

Before attaching a node as a child, implementations MUST check for cycles. If the node to be attached is an ancestor of the target parent, a cycle exists and the operation MUST throw an error.

If the node being attached already has a parent, it MUST first be detached from its current parent.

4.2. CollectionNode

CollectionNode is the base type for nodes that contain other nodes — either as key-value pairs (MapNode) or as an ordered sequence (ListNode).

[Exposed=*]
interface CollectionNode : HypermapNode {
  readonly attribute unsigned long size;
  any toJSON();
  any toView();
};
collection.size
Returns the number of children in the collection.
collection.toJSON()
Returns a lossless JSON-serializable representation of the collection. Child nodes are recursively serialized via their own toJSON(). The output can be passed back to fromJSON() to reconstruct an equivalent node tree.
collection.toView()
Returns a lossy JSON-serializable representation suitable for consumers. Child nodes are recursively converted via their own toView(). Controls have their # key replaced with {"type": "control"} —​consumers see that the node is a control but do not receive its full attributes. This is the representation intended for rendering and integration scripts that do not need to know about hypermedia affordances.

4.3. MapNode

A MapNode represents an ordered map of string keys to node values. It corresponds to a JSON object in the wire format.

dictionary HypermapAttributes {
  USVString href;
  USVString method = "GET";
  sequence<USVString> scripts;
};

[Exposed=*]
interface MapNode : CollectionNode {
  readonly attribute HypermapAttributes attributes;
  boolean has(DOMString key);
  HypermapNode? at(DOMString key);
  MapNode set(DOMString key, HypermapNode value);
  MapNode delete(DOMString key);
};

The attributes of a MapNode are extracted from the # key during parsing. If no # key is present, the attributes are an empty object.

map.has(key)
Returns true if map contains an entry for key.
map.at(key)
Returns the node associated with key, or null if no such entry exists.
map.set(key, value)
Sets the entry for key to value. The value MUST be a HypermapNode instance. If value has an existing parent, it is first reparented. The value is then attached as a child of map. A mutation event is dispatched. Returns map.
map.delete(key)
Removes the entry for key. If the entry exists, the child node is detached. A mutation event is dispatched. Returns map.

4.4. ListNode

A ListNode represents an ordered sequence of node values. It corresponds to a JSON array in the wire format.

[Exposed=*]
interface ListNode : CollectionNode {
  HypermapNode? at(long index);
  ListNode set(long index, HypermapNode value);
  ListNode append(HypermapNode value);
  ListNode prepend(HypermapNode value);
  ListNode insert(long index, HypermapNode value);
  ListNode delete(long index);
};
list.at(index)
Returns the node at index. Supports negative indices (from the end).
list.set(index, value)
Replaces the node at index with value. The value MUST be a HypermapNode instance. The previous node at that index, if any, is detached. A mutation event is dispatched. Returns list.
list.append(value)
Adds value to the end of the list. A mutation event is dispatched. Returns list.
list.prepend(value)
Adds value to the beginning of the list. A mutation event is dispatched. Returns list.
list.insert(index, value)
Inserts value at index, shifting subsequent elements. A mutation event is dispatched. Returns list.
list.delete(index)
Removes the node at index, shifting subsequent elements. The removed node is detached. A mutation event is dispatched. Returns list.

4.5. ValueNode

A ValueNode wraps a single primitive value.

[Exposed=*]
interface ValueNode : HypermapNode {
  attribute any value;
  any toJSON();
  any toView();
};

The value of a ValueNode MUST be one of: null, a boolean, a number, or a string. These correspond to the JSON primitive types.

node.value
The primitive value held by this node.
node.toJSON()
Returns the primitive value. For ValueNode, toJSON() is lossless by definition.
node.toView()
Returns the primitive value. For ValueNode, toView() is identical to toJSON().

4.6. Hypermap

The Hypermap interface is the top-level entry point, representing a parsed HyperMap resource. It extends MapNode.

[Exposed=*]
interface Hypermap : MapNode {
  readonly attribute Document? document;
  static Hypermap fromJSON(USVString json);
  Promise<sequence<any>> start();
  ValueNode input(sequence<(DOMString or long)> path, any value);
  HypermapNode use(sequence<(DOMString or long)> path);
  HypermapNode nodeFromPath(sequence<(DOMString or long)> path);
};
hypermap.document
Returns the Document of the browsing context in which this Hypermap was loaded, or null if running outside a browser environment.
Hypermap.fromJSON(json)
Parses a JSON string into a Hypermap node tree. See § 4.7 Parsing.
hypermap.start()
Walks the node tree and loads scripts for every MapNode that declares them. See § 6.2 Script Loading.
hypermap.input(path, value)
Resolves path to a ValueNode, sets its value, and dispatches an input event on the target node. Returns the target node.
hypermap.use(path)
Resolves path to a HypermapNode and dispatches a use event on it. Returns the target node.
hypermap.nodeFromPath(path)
Resolves an array of keys and indices to a node by traversing the tree. Each element of path is used as a key (for MapNode) or index (for ListNode) to descend one level.

4.7. Parsing

The Hypermap.fromJSON(json) static method parses a JSON string into a Hypermap node tree. The algorithm is as follows:

To parse a HyperMap resource from a JSON string json:

  1. Let result be the result of parsing json using a JSON reviver that applies the following rules to each value:

    1. If value is a JSON primitive (null, boolean, number, or string), return a new ValueNode with its value set to value.

    2. If value is a JSON array, return a new ListNode whose elements are the recursively converted items of the array.

    3. If value is a JSON object:

      1. If value has a # key, let attrs be its value. attrs MUST be a JSON object. Extract from attrs the href, method, and scripts members and construct a HypermapAttributes dictionary.

      2. Remove the # key from value.

      3. Return a new MapNode whose attributes are the extracted HypermapAttributes (or an empty dictionary if no # key was present), with the remaining key-value pairs as children, each recursively converted.

  2. Assert: result is a MapNode (since the top level MUST be a JSON object per § 3.2 Top-Level Structure).

  3. Wrap result in a new Hypermap instance and return it.

5. Events

The HyperMap data model uses events to signal changes and interactions.

5.1. Mutation Events

A mutation event is an Event with the name "mutation".

Whenever a tree-modifying operation occurs on a MapNode or ListNode — specifically set(), delete(), set(), append(), prepend(), insert(), or delete() — a mutation event MUST be dispatched on the global object (window in browser environments).

The current mutation event model dispatches synchronously on the global object. This is analogous to the deprecated DOM Mutation Events, which were replaced by MutationObserver in [DOM] due to performance concerns. Future versions of this specification are expected to adopt an observer-based model, where scripts register observers on specific nodes and receive batched, asynchronous notifications of changes within their subtree. This would align with both the DOM’s current approach and HyperMap’s scoped script model, where each script naturally observes only its own portion of the tree.

5.2. Input Events

An input event is a CustomEvent with the name "input". It is dispatched when input() is called.

The event’s detail object contains a target property referencing the ValueNode whose value was set.

Input events are dispatched on the target node and bubble up the tree.

5.3. Use Events

A use event is a CustomEvent with the name "use". It is dispatched when use() is called.

The event’s detail object contains a target property referencing the HypermapNode that was used.

Use events are dispatched on the target node and bubble up the tree.

5.4. Event Bubbling

As defined in § 4.1.1 Event Dispatch, events dispatched on any HypermapNode propagate through the tree via capture and bubble phases. This enables listeners at any level of the tree to observe events from their descendants.

6. Script Execution

HyperMap supports code on demand: servers can include script references in their responses, and clients execute those scripts.

6.1. Script Declaration

Scripts are declared in the attributes of any MapNode using the scripts key. The value MUST be an array of strings, each being a URL (absolute or relative) pointing to a script resource.

A resource with scripts at multiple levels of the tree:
{
  "#": {
    "href": "/stocks",
    "scripts": ["/js/portfolio-summary.js"]
  },
  "AAPL": {
    "#": {
      "href": "/stocks/AAPL",
      "scripts": ["/js/price-stream.js"]
    },
    "price": 187.42
  },
  "GOOG": {
    "#": {
      "href": "/stocks/GOOG",
      "scripts": ["/js/price-stream.js"]
    },
    "price": 141.80
  }
}

Each stock node loads its own price streaming script. The root loads a portfolio summary script. The same script URL may appear on multiple nodes —​each instance runs independently with its own scoped reference.

6.2. Script Loading

When start() is called, the HyperMap user agent walks the node tree and begins loading scripts for every MapNode that declares them.

To load scripts for a MapNode node:

  1. Let scripts be the scripts array from node’s attributes, or an empty array if not present.

  2. For each scriptURL in scripts, in parallel:

    1. Resolve scriptURL against the resource’s base URL.

    2. Load the script as an ECMAScript module using dynamic import().

    3. The script’s hypermap global MUST be set to node. See § 6.3 Script Environment.

Scripts load asynchronously. No ordering is guaranteed between scripts on the same node or across different nodes.

6.2.1. Reactive Script Loading

Script loading is reactive to tree mutations. When a tree mutation adds or modifies a scripts attribute on a MapNode, the HyperMap user agent MUST load scripts for that node.

When a MapNode is removed from the tree, any scripts that are still loading for that node MUST be cancelled. Scripts that have already loaded SHOULD be given an opportunity to clean up (e.g., closing network connections) before being discarded.

A script may modify the tree in ways that trigger further script loading. For example, a script could modify the scripts array in a child node’s attributes, causing new scripts to be loaded for that node. This enables dynamic composition of behavior.

6.3. Script Environment

Scripts loaded by a MapNode execute as ECMAScript modules. Each script receives a hypermap global that references the MapNode whose attributes declared it — not the root of the tree.

This scoping ensures that scripts are composable: a script that manages a stock price stream only needs to know about its own node, not the structure of the larger tree. The same script can be attached to multiple nodes and each instance operates independently.

Implementations SHOULD isolate script execution contexts to prevent scripts from accessing nodes outside their scope through global state. The mechanism for achieving this isolation (e.g., Secure ECMAScript compartments, iframes, or similar sandboxing) is implementation-defined.

Scripts interact with their portion of the HyperMap tree through the node interfaces defined in § 4 Data Model. A script may:

A script that streams price updates for a single stock. This script is attached to a stock node and only modifies its own subtree:
// hypermap refers to the MapNode this script is attached to,
// e.g. the "AAPL" node, not the root.
const href = hypermap.attributes.href;
const stockSocket = new WebSocket(wss://example.com${href}/stream);

stockSocket.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  hypermap.set("price", new ValueNode(msg.price));
};

7. Processing Model

This section defines the end-to-end lifecycle of a HyperMap resource from initial load through interaction.

7.1. Resource Lifecycle

When a HyperMap user agent loads a resource, it performs the following steps:

  1. Fetch the resource from the network, including any applicable credentials for user agent requests.

  2. Parse the HyperMap resource from the response body to produce a Hypermap node tree.

  3. Set the base URL to the response’s final URL (after redirects).

  4. If running in a browser, set the Hypermap’s document attribute to the enclosing Document.

  5. Call start() to load scripts for all MapNodes in the tree that declare them.

  6. The resource is now live — scripts may modify the tree, listen for events, and establish network connections.

When navigation occurs (via control activation or equivalent), the current resource’s lifecycle ends: pending script loads are cancelled, the node tree is discarded, and the lifecycle begins again from step 1 with the new resource.

8. Fetching and Navigation

8.1. Control Activation

When a control is activated (via use() or equivalent client interaction), the HyperMap user agent SHOULD perform the following:

To activate a control on a MapNode control:

  1. Let href be control’s attributes' href.

  2. Let method be control’s attributes' method, defaulting to "GET".

  3. Resolve href against the resource’s base URL to obtain url.

  4. If method is "GET", serialize the contents of control (excluding the # key) as URL-encoded query parameters and append them to url. Fetch url with method GET.

  5. Otherwise, serialize the contents of control (excluding the # key) as JSON. Fetch url with the specified method, a Content-Type of application/json, and the serialized JSON as the request body.

  6. Process the response as defined in § 8.2 Form Submission.

8.2. Form Submission

A form submission occurs when a control is activated. The child nodes of the control (excluding the # key) serve as form fields — analogous to input elements in an HTML form.

To populate a form, a client calls input() on the ValueNode children of the control to set their values before activation.

A control for placing a stock order:
{
  "placeOrder": {
    "#": { "href": "/stocks/AAPL/orders/", "method": "POST" },
    "quantity": 0
  }
}

The client sets the quantity value via hypermap.input(["placeOrder", "quantity"], 10), then activates the control via hypermap.use(["placeOrder"]).

After submitting the request, the HyperMap user agent processes the response as follows:

  1. If the response is a redirect (3xx with a Location header), the user agent MUST follow the redirect and navigate to the target URL.

  2. If the response is a success (2xx) with a HyperMap resource body, the user agent parses it and navigates to the new resource.

Servers SHOULD respond to form submissions with a redirect (e.g., 303 See Other) rather than a direct response. This is the Post/Redirect/Get pattern, as used in HTML form submission — the redirect ensures the resulting page is a GET-able resource, preventing duplicate submissions when the user navigates back.

8.3. Content Negotiation

Clients requesting HyperMap resources SHOULD include application/vnd.hypermap+json in their Accept header.

Servers MUST respond with the application/vnd.hypermap+json content type when the client requests a HyperMap resource with a matching Accept header.

Servers MAY also respond with text/html when the client accepts HTML (see § 9.1 Browser-Based User Agents).

9. User Agents

This section is non-normative where noted.

A HyperMap user agent is any software that fetches, parses, and presents HyperMap resources. This includes browser-based clients, command-line tools, and programmatic API clients.

A conforming HyperMap user agent MUST:

  1. Fetch resources and parse them according to § 4.7 Parsing.

  2. Construct the node tree defined in § 4 Data Model.

  3. Support event dispatch as defined in § 5 Events.

  4. Execute scripts as defined in § 6 Script Execution, if the agent supports scripting.

9.1. Browser-Based User Agents

When a HyperMap user agent runs within a web browser, the HyperMap resource is embedded in an HTML document. The user agent script manages the lifecycle of the HyperMap node tree within the browsing context of that document.

To deliver a HyperMap resource to a browser, a server responds with an HTML document that:

  1. Embeds the JSON representation of the resource in the document body.

  2. Includes a user agent script that parses the embedded JSON, constructs the node tree, and calls start() to begin script execution.

The root Hypermap node’s document attribute MUST be set to the Document of the enclosing browsing context. This gives scripts access to same-origin platform APIs such as localStorage and other APIs scoped to the document’s origin.

The HTML document serves as a host for the HyperMap node tree, analogous to how an HTML page hosts a DOM tree. The specific mechanism for embedding the JSON — such as a <pre> element or an inline script — is left to the user agent implementation.
This example is non-normative.

A minimal HTML document delivering a HyperMap resource:

<!DOCTYPE html>
<html>
  <head>
    <script type="module" src="/hypermap-shim.js"></script>
  </head>
  <body>
    <pre>{"#": {"href": "/todos"}, "todos": []}</pre>
  </body>
</html>

When control activation produces a new HyperMap resource, the HyperMap user agent replaces the current resource with the new one. The previous node tree is discarded and a new tree is constructed from the response.

In browser-based user agents, navigation updates the browsing context’s URL and browsing history using the mechanisms defined in [HTML].

10. Security Considerations

The security goal for HyperMap is that scripts operate with minimal authority by default. This section describes the desired security properties and the constraints on achieving them.

10.1. Credential Model

This specification distinguishes between two classes of network request:

User agent requests

Requests made by the HyperMap user agent itself — during control activation, navigation, and initial resource loading. These represent the user’s intent and SHOULD include ambient credentials (cookies, session tokens) as normal, analogous to a browser navigating to a URL when the user clicks a link.

Script-initiated requests

Requests made by scripts via fetch(), WebSocket, EventSource, or similar APIs. These run autonomously and SHOULD NOT include ambient credentials. Specifically, script-initiated requests SHOULD omit cookies (credentials: "omit"), the Referer header (referrerPolicy: "no-referrer"), and any Authorization headers from the browsing context.

Enforcing this distinction requires script execution isolation — the user agent must be able to provide scripts with a restricted environment where network APIs do not carry ambient credentials. In a browser-based user agent running as a JavaScript shim, scripts share the same global scope and fetch() as the user agent itself, making this distinction unenforceable without additional isolation mechanisms such as Secure ECMAScript (SES) compartments. Implementations that achieve script isolation MUST enforce credential stripping; implementations without isolation SHOULD document this limitation.

10.2. Script Scope Isolation

As described in § 6.3 Script Environment, each script’s hypermap global references only the MapNode that declared it. When script isolation is enforced, implementations SHOULD additionally ensure:

The combination of scoped globals and credential stripping limits the blast radius of a compromised or malicious script. A script attached to a leaf node can only read and modify its own subtree, and cannot make authenticated requests on behalf of the user.

10.3. Open Questions

This section is non-normative.

The following security topics are recognized but not yet addressed by this specification:

Conformance

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch Standard. Living Standard. URL: https://fetch.spec.whatwg.org/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[JSON]
T. Bray, Ed.. The JavaScript Object Notation (JSON) Data Interchange Format. December 2017. Internet Standard. URL: https://www.rfc-editor.org/rfc/rfc8259
[NAVIGATION-TIMING-2]
Yoav Weiss; Noam Rosenthal. Navigation Timing Level 2. URL: https://w3c.github.io/navigation-timing/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[URL]
Anne van Kesteren. URL Standard. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/

IDL Index

[Exposed=*]
interface HypermapNode : EventTarget {
  readonly attribute HypermapNode? parentNode;
};

[Exposed=*]
interface CollectionNode : HypermapNode {
  readonly attribute unsigned long size;
  any toJSON();
  any toView();
};

dictionary HypermapAttributes {
  USVString href;
  USVString method = "GET";
  sequence<USVString> scripts;
};

[Exposed=*]
interface MapNode : CollectionNode {
  readonly attribute HypermapAttributes attributes;
  boolean has(DOMString key);
  HypermapNode? at(DOMString key);
  MapNode set(DOMString key, HypermapNode value);
  MapNode delete(DOMString key);
};

[Exposed=*]
interface ListNode : CollectionNode {
  HypermapNode? at(long index);
  ListNode set(long index, HypermapNode value);
  ListNode append(HypermapNode value);
  ListNode prepend(HypermapNode value);
  ListNode insert(long index, HypermapNode value);
  ListNode delete(long index);
};

[Exposed=*]
interface ValueNode : HypermapNode {
  attribute any value;
  any toJSON();
  any toView();
};

[Exposed=*]
interface Hypermap : MapNode {
  readonly attribute Document? document;
  static Hypermap fromJSON(USVString json);
  Promise<sequence<any>> start();
  ValueNode input(sequence<(DOMString or long)> path, any value);
  HypermapNode use(sequence<(DOMString or long)> path);
  HypermapNode nodeFromPath(sequence<(DOMString or long)> path);
};