npm package: @hyperbeam/iframe
Description: Web client library for the Hyperbeam multiplayer browser API
Author: Ambareesh Balaji
Latest version: 0.0.14
Deprecated: please use https://www.npmjs.com/package/@hyperbeam/web instead

# DEPRECATED, please use [@hyperbeam/web](https://www.npmjs.com/package/@hyperbeam/web) instead

The JavaScript frontend library for the Hyperbeam multiplayer browser API.

Unfamiliar with the Hyperbeam API? Read the full documentation <a href="https://hyperbeam.support/API-Design-eb9874bd1ef54c22ba7197324ce22231" target="_blank">here</a>.

## Table of Contents

- [Features](#features)
- [Installation](#installation)
- [Example](#example)
- [API](#api)
  - [Loading multiplayer browser](#loading-multiplayer-browser)
  - [Setting video volume](#setting-video-volume)
  - [Getting user ID](#getting-user-id)
  - [Pausing video stream](#pausing-video-stream)
  - [Setting admin token](#setting-admin-token)
  - [Setting permissions](#setting-permissions)
  - [Send events programmatically](#send-events-programmatically)
  - [Control tabs programmatically](#control-tabs-programmatically)
  - [Listen to tab events](#listen-to-tab-events)

## Features

- Connect to a multiplayer browser
- Control browser navigation programmatically
- Query browser state and listen to events
- Manage user control permissions
- Set local multiplayer browser volume

## Installation

Using npm:

```bash
$ npm install @hyperbeam/web --save
```

Using unpkg:

```html
<script type="module">
  import Hyperbeam from "https://unpkg.com/@hyperbeam/web@latest/dist/index.js"
  // ...
</script>
```

## Example

You can save this code snippet as `example.html` and run it in your browser. Make sure you set the embed URL variable to the response data from the [REST API](https://hyperbeam.support/Hyperbeam-API-eb9874bd1ef54c22ba7197324ce22231#d326c958e95244b89cf7ffdbcb07e9bd).

```html
<div style="font-family: Arial">
  <button id="reload">Reload</button>
  <button id="back">Go Back</button>
  <button id="forward">Go Forward</button>
  <button id="youtube">Open Youtube.com</button>
  Volume: <input type="range" min="0" max="100" value="100" id="range">
  <p>User ID: <span id="userId"></span></p>
  <p>Current website: <span id="currentSite"></p>
</div>
<iframe id="container" style="height:720px;width:1280px"></iframe>
<script type="module">
  import Hyperbeam from "https://unpkg.com/@hyperbeam/web@latest/dist/index.js"
  // TODO: Set the embedURL variable
  const embedURL = "<your-embed-url>"
  const hb = await Hyperbeam(container, embedURL)
  userId.innerText = hb.userId
  reload.addEventListener("click", () => {
    hb.tabs.reload()
  })
  back.addEventListener("click", () => {
    hb.tabs.goBack()
  })
  forward.addEventListener("click", () => {
    hb.tabs.goForward()
  })
  youtube.addEventListener("click", () => {
    hb.tabs.update({ url: "https://youtube.com" })
  })
  range.addEventListener("change", (e) => {
    hb.volume = e.target.value / 100
  })
  hb.tabs.onUpdated.addListener((tabId, changeInfo) => {
    if (changeInfo.title) {
      currentSite.innerText = changeInfo.title
    }
  })
</script>
```

## API Reference

### Loading multiplayer browser

**Hyperbeam(container: HTMLIFrameElement | HTMLDivElement, embedURL: string, opts?: HyperbeamOptions): Promise\<HyperbeamClient\>**

Creates a new Hyperbeam client.

```js
// The embedURL is retrieved from the REST API
// Documentation for the REST API can be found here:
// hyperbeam.support/API-Design-eb9874bd1ef54c22ba7197324ce22231
const embedURL = "https://abc.hyperbeam.com/foo?token=bar"
const container = document.getElementById("container-id")

const hb = await Hyperbeam(container, embedURL, {
  // Number of milliseconds until the request to the multiplayer browser times out.
  // If the request times out, the returned promise will be rejected.
  timeout: 5000, // default = 2000

  // An admin token returned from the REST API that will grant this user
  // access to managing user permissions and programmatic navigation.
  adminToken: "admin_token_from_rest_api_response",

  // Starting volume of the multiplayer browser
  volume: 0.2,         // default = 1.0

  // Starting video pause state of the multiplayer browser
  videoPaused: false,  // default = false

  // Data to be provided to your webhook endpoint if you're using webhook authentication
  webhookUserdata: {myAppData: {user: "your-app-user-id"}}
})
```

### Destroying the embed

**hb.destroy()**

Tears down network connections and browser events. Always call this *before* removing the container element from the page.

```js
const hb = await Hyperbeam(container, embedURL)
setTimeout(() => {
  hb.destroy()
}, 10_000)
```

### Setting video volume

**hb.volume = 0.5**

Sets the volume for the multiplayer browser *locally*. Volume changes only apply to the local user. This setting is *not* persisted on refreshing the page.

```js
const hb = await Hyperbeam(container, embedURL)
// Valid values range from 0.0 to 1.0
hb.volume = 0.5        // default = 1.0
console.log(hb.volume) // Get the local volume value
```

### Getting user ID

**hb.userId: string**

Gets the client's user ID. A "user" is defined as a single connection to the multiplayer browser. If a person has multiple tabs connected to the multiplayer browser, each tab with an active connection will be assigned a different user ID.

```js
const hb = await Hyperbeam(container, embedURL)
console.log(hb.userId) // A unique string identifying the user
```

### Pausing video stream

**hb.videoPaused = true**

Pauses/resumes the video stream for the multiplayer browser *locally*. Useful if only the audio component is of interest and you want to minimize CPU usage.

```js
const hb = await Hyperbeam(container, embedURL)
hb.videoPaused = true       // Pause the video stream
hb.videoPaused = false      // Resume the video stream
console.log(hb.videoPaused) // Get the video stream pause state
```

### Setting admin token

**hb.adminToken = "adminToken"**

Sets the client's admin token. The client must have an admin token set to manage user permissions and control the tabs programmatically.

```js
// You can provide the admin token during initialization
const hb = await Hyperbeam(container, embedURL, {
  adminToken: "admin_token_from_rest_api_response"
})

// In some situations, you may want to promote the user to
// an admin after initialization. For example, promoting a "user" to a "moderator".
const hb = await Hyperbeam(container, embedURL)
hb.adminToken = "admin_token_from_rest_api_response"
```

### Setting permissions

**hb.setPermission(userId: string, permissionData: PremissionData): Promise\<void\>**

Sets the permission of a user by their ID. The client must have an admin token set to manage user permissions.

```js
// You can provide the admin token during initialization
const hb = await Hyperbeam(container, embedURL, {
  adminToken: "admin_token_from_rest_api_response"
})

const targetUserId = "a_user_id"

// All keys can be omitted: if the key is omitted, then the existing value will be unchanged
const permissions = {
  // Higher value = higher priority
  // Users with a higher priority will preempt the control of lower priority users.
  priority: 2,           // default = 0

  // Number of milliseconds until a user is considered "idle". Once a user is considered
  // idle, they no longer preempt lower priority users until they interact with the
  // multiplayer browser again.
  idle_timeout: 3000,    // default = 0

  // If control_disabled = true, all control input (mouse movements, keyboard presses)
  // will be ignored. Note that disabling control does not restrict access to any
  // APIs that require admin tokens.
  control_disabled: true // default = control_disable_default (see REST API)
}

hb.setPermissions(targetUserId, permissions)
```

### Send events programmatically

**hb.sendEvent(event: KeyEvent | MouseEvent | WheelEvent): void**

Sends a keyboard, mouse, or mouse wheel event to the Hyperbeam browser.

```js
const keyEvent = {
  type: "keydown", // type can be set to "keydown" and "keyup"
  // String denoting which key is pressed.
  // See https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values
  key: "A",
  ctrlKey: true // Boolean indicating if the Ctrl key is pressed. Default is false.
  metaKey: false // Boolean indicating if the Meta key is pressed. Default is false.
}

const mouseEvent = {
  type: "mousedown" // type can be set to "mousemove", "mousedown", and "mouseup"
  x: 0.5, // The mouse's X position as a ratio, with a range of [0, 1]
  y: 0.5, // The mouse's Y position as a ratio, with a range of [0, 1]
  // Number that indicates which button was pressed on the mouse. Default is 0.
  // See https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/button
  button: 2
}

const wheelEvent = {
  type: "wheel", // Mouse wheel event, used for scrolling up or down
  deltaY: 20 // Positive value signifies scrolling down
}

hb.sendEvent(keyEvent) // Send CTRL+A keystroke
hb.sendEvent(mouseEvent) // Right-click the center of the screen (0.5, 0.5)
hb.sendEvent(wheelEvent) // Scroll down
```

### Control tabs programmatically

Hyperbeam's tab API mirrors Chrome extension tab API, found <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method" target="_blank">here</a>.

Rather than calling `chrome.tabs.create({ active: true })`, you will would call `hb.tabs.create({ active: true })`.

We support the following methods:
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-create" target="_blank">tabs.create</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-detectLanguage" target="_blank">tabs.detectLanguage</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-discard" target="_blank">tabs.discard</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-duplicate" target="_blank">tabs.duplicate</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-get" target="_blank">tabs.get</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-getZoom" target="_blank">tabs.getZoom</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-getZoomSettings" target="_blank">tabs.getZoomSettings</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-goBack" target="_blank">tabs.goBack</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-goForward" target="_blank">tabs.goForward</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-group" target="_blank">tabs.group</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-highlight" target="_blank">tabs.highlight</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-move" target="_blank">tabs.move</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-query" target="_blank">tabs.query</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-reload" target="_blank">tabs.reload</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-remove" target="_blank">tabs.remove</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-setZoom" target="_blank">tabs.setZoom</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-setZoomSettings" target="_blank">tabs.setZoomSettings</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-ungroup" target="_blank">tabs.ungroup</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#method-update" target="_blank">tabs.update</a>

```js
const hb = await Hyperbeam(container, embedURL)

// Create a tab
const tab = await hb.tabs.create({ active: true })

// Duplicate a tab
const tab2 = await hb.tabs.duplicate(tab.id)

// Set the URL of the active tab
const updatedTab = await hb.tabs.update({url: "https://hyperbeam.dev/"})
```

### Listen to tab events

Hyperbeam's tab event listener API mirrors Chrome extension tab API, found <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event" target="_blank">here</a>.

Rather than calling `chrome.tabs.onCreated.addListener((tab) => {})`, you will would call `hb.tabs.onCreated.addListener((tab) => {})`.

We support the following events:
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onActivated" target="_blank">tabs.onActivated</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onCreated" target="_blank">tabs.onCreated</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onHighlighted" target="_blank">tabs.onHighlighted</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onMoved" target="_blank">tabs.onMoved</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onRemoved" target="_blank">tabs.onRemoved</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onReplaced" target="_blank">tabs.onReplaced</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onUpdated" target="_blank">tabs.onUpdated</a>
- <a href="https://developer.chrome.com/docs/extensions/reference/tabs/#event-onZoomChange" target="_blank">tabs.onZoomChange</a>

```js
const hb = await Hyperbeam(container, embedURL)

function onTabCreated(tab) {
  console.log(tab.id)
}

// Listen for when a new tab is created
hb.tabs.onCreated.addListener(onTabCreated)

// Create a new tab
await hb.tabs.create({ active: true })

// Remove the event listener
hb.tabs.onCreated.removeListener(onTabCreated)
```