JSPM

@hotsock/hotsock-js

1.2.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 12
  • Score
    100M100P100Q79150F
  • License MIT

JavaScript library for Hotsock WebSocket connections, subscriptions, and messages

Package Exports

  • @hotsock/hotsock-js
  • @hotsock/hotsock-js/src/hotsock.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@hotsock/hotsock-js) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

Hotsock JavaScript Client

This JS client allows you to connect and handle Hotsock messages on a WebSocket connection. It's designed for use in the browser, provides a small and stable API with no dependencies, and handles reconnects gracefully. React Native is also supported.

Installation

Install and import the library

npm add @hotsock/hotsock-js

or

yarn add @hotsock/hotsock-js

Usage

import { HotsockClient } from "@hotsock/hotsock-js"

Construct a client object

Each client object manages a WebSocket connection to your Hotsock installation. This client can subscribe to any number of channels and fire callback functions when messages are received.

The HotsockClient constructor takes 2 arguments - the WebSocket URL for your installation (WebSocketsWssUrl from the installation's CloudFormation stack output) and an object containing a connectTokenFn function that returns a valid connect-scoped JWT authorizing a connection to the WebSocket.

connectTokenFn must return a JWT string or return a Promise that resolves to a JWT string (async/await).

Here's an example with a connect function that returns a static JWT string. In a real application, this function would typically be a network call to fetch a token for this user, if they're permitted.

const client = new HotsockClient(
  "wss://996iaxdp6g.execute-api.us-east-1.amazonaws.com/v1",
  {
    connectTokenFn: async () => {
      // Implement your token fetching logic here that returns a connect-scoped
      // JWT accepted by your Hotsock installation.
      return "your-jwt-token"
    },
    connectTokenFnMaxAttempts: 3, // Optional, defaults to 2
    lazyConnection: true, // Optional, prevents connection until needed, defaults to false
    logLevel: "debug", // Optional, default log level is "warn"
  }
)

Connection management

You can control the WebSocket connection by suspending, resuming, or terminating it.

client.suspend() // Suspend the connection while retaining event bindings
client.resume() // Resume the connection and re-subscribe to channels
client.terminate() // Terminate the connection and clear all bindings

Make a callback function

All message handler functions must accept a single Object argument, which is the message pre-parsed from the JSON that came over the WebSocket.

function handleMessage(messageObj) {
  console.log("Received Hotsock message", messageObj)
}

Given the previous handler, you'd see something like this upon receiving a message in a browser console.

Received Hotsock message Object { id: "01HP8BGSHWY952BXW1PE25DSJA", event: "my-event", channel: "my-channel", data: "๐Ÿ‘‹ Hello from Hotsock! ใ“ใ‚“ใซใกใฏ" }

Subscribe to channel events

By default, a channel subscribe action will use the permissions granted from the connect-scoped token that authorized the connection.

The initial connect token often does not include permissions for all channels that will be subscribed to during the lifetime of a connection or may need modified uid / umd claims. In this case, you can pass a subscribeTokenFn that will be called, which must return a valid subscribe-scoped JWT that authorizes the channel subscription.

const myChannel = client.channels("my-channel")
myChannel.subscribeTokenFn = async ({ channel, connectionId }) => {
  // Implement your token fetching logic here that returns a subscribe-scoped
  // JWT accepted by your Hotsock installation.
  return "your-jwt-token"
}
myChannel.bind("my-event", (message) => {
  console.log("Received message:", message)
})
myChannel.bind("my-other-event", myOtherFn)

Bind from the client directly

Subscribe to events matching the event name my-event on the my-channel channel. Each matching message will invoke handleMessage with the message object passed as an argument.

const binding = client.bind("my-event", handleMessage, {
  channel: "my-channel",
})

Or with an inline function:

const binding = client.bind("my-event", ({ data }) => console.log(data), {
  channel: "my-channel",
})

You can also subscribe with a regex matcher. The following subscribes to all events on the my-channel channel.

const binding = client.bind(/.+/, handleMessage, { channel: "my-channel" })

Get info about the channel

From a binding, you can access information about the channel as well as how you're represented in the channel.

Get your connection's uid as it is represented in this channel.

binding.channel.uid
// "12345"

Get your connection's umd as it is represented in this channel.

binding.channel.umd
// {"name": "Jim"}

Get the channel name.

binding.channel.name
// "my-channel"

Get info about other members of the channel (only populated for presence channels).

binding.channel.members
// [{"uid":"12345","umd":{"name":"Jim"},{"uid":"23456","umd":{"name":"Dwight"}]

Publish messages to a channel

If the channel subscription permits client-initiated messages, use sendMessage to publish messages. data can be anything that is valid JSON (Object|Array|string|number|boolean|null) up to 32 KiB.

const myChannel = client.channels("my-channel")
myChannel.sendMessage("isTyping")
myChannel.sendMessage("chat", { data: { message: "Hello!" } })

You can also publish from the client directly, specifying the channel.

client.sendMessage("isTyping", { channel: "my-channel" })
client.sendMessage("chat", {
  channel: "my-channel",
  data: { message: "Hello!" },
})

Send a raw message on the WebSocket

If you prepared your message and it's already stringified JSON, you can publish it directly.

client.sendRawMessage(`{"event":"hotsock.ping"}`)
client.sendRawMessage(
  `{"event":"chat","channel":"discussion.123","data":{"message":"Hello!"}}`
)

Unsubscribe from channel events

You can unsubscribe from the binding object that was returned when subscribing.

binding.unbind()

Or, unsubscribe from a channel via the top-level client.

client.unbind("my-event", { channel: "my-channel" })

Special connection events

You can subscribe to ALL incoming or outgoing messages at the connection-level, as well as the connection's connect, disconnect, and error events with a special @@ event prefix for the following events.

// Call a function for any message received on the WebSocket, regardless of
// event or channel name.
client.bind("@@message", (event) =>
  console.log("Received WebSocket data", event.data)
)

// Call a function for any message sent on the WebSocket from this client.
client.bind("@@messageSent", (rawMessage) =>
  console.log("Sent WebSocket message", rawMessage)
)

// Call a function when the WebSocket connection is established.
client.bind("@@connect", (event) => console.log("Connected!"))

// Call a function when the WebSocket connection is terminated.
client.bind("@@disconnect", (event) => console.log("Disconnected!"))

// Call a function when a WebSocket-level error occurs. This is not called for
// "hotsock.error" events.
client.bind("@@error", (event) => console.log("An error occurred", event))