npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@hotsock/hotsock-js

v1.1.0

Published

JavaScript library for Hotsock WebSocket connections, subscriptions, and messages

Downloads

87

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))