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

@sanity/comlink

v2.0.3

Published

A library for one-to-many cross-origin communication between Window contexts, built on the postMessage API.

Downloads

409,853

Readme

@sanity/comlink

A library for one-to-many cross-origin communication between Window contexts, built on the postMessage API.

Install

npm install @sanity/comlink

Usage

@sanity/comlink provides a mechanism for sending messages between a parent and one or more child Window contexts. Define Nodes and Channels and @sanity/comlink will establish and maintain connections to new target contexts automatically.

Comlink Diagram

Setup

First, define the types of messages you will send and receive. The data and response values must be a serializable object, or undefined.

Define a message a Channel will send to a Node.

type ChannelMessage = {
  type: 'focus'
  data: {
    selector: string
  }
}

Define messages the Node will send to a Channel. Note that responses are only supported from Channels, i.e. on Node message types.

interface GreetingMessage {
  type: 'greeting'
  data: {
    message: string
  }
}

interface ItemFetchMessage {
  type: 'fetch-item'
  data: {
    id: string
  }
  response: {
    data: Record<string, unknown> | undefined
  }
}

type NodeMessage = GreetingMessage | ItemFetchMessage

Parent Context

In the parent Window context, create a Controller. This is used to create and manage Channels, which connect to Nodes in other Window contexts. Provide a targetOrigin to ensure messages are only sent to and received from trusted origins.

import {createController} from '@sanity/comlink'

const controller = createController({
  targetOrigin: 'https://target-origin.com',
})

Add a target Window context, such as an iframe.

const iframe = document.querySelector('iframe#my-iframe')

controller.addTarget(iframe)

Define a Channel by specifying its name and the name of the Node it will interface with. Optionally enable heartbeat monitoring to allow automatic recovery on unexpected disconnects.

const channel = controller.createChannel<ChannelMessage, NodeMessage>({
  name: 'parent',
  heartbeat: true,
  connectTo: 'child',
})

Listen for status changes.

const unsubscribe = channel.onStatus((event) => {
  console.log('Status of', event.connection, 'changed to', event.status)
})

Listen for messages...

const unsubscribe = channel.on('greeting', (data) => {
  console.log(data.message)
})

...return responses...

const unsubscribe = channel.on('fetch-item', (data) => {
  return items.find((item) => item.id === data.id)
})

...or send messages to all Nodes.

channel.post('focus', {selector: 'foo'})

Child Context

In the child Window context, create a Node. Provide a name and the name of the Channel it should interface with.

import {createNode} from '@sanity/comlink'

const node = createNode<NodeMessage, ChannelMessage>({
  name: 'child',
  connectTo: 'parent',
})

Listen for status changes.

const unsubscribe = node.onStatus((status) => {
  console.log('Status changed to', status)
})

Send messages...

node.post('greeting', {message: 'Hello, Comlink!'})

...fetch data...

const item = await node.fetch('fetch-item', {id: 'foo'})

...or listen for incoming messages.

const unsubscribe = node.on('focus', (data) => {
  document.querySelector(data.selector)?.focus()
})

Core Concepts

Controllers

Controllers are responsible for managing the lifecycle of channels to one or more Nodes. They handle the creation of Channels, adding and removing targets, and managing the overall communication flow.

Controllers ensure that messages are correctly routed to the appropriate Node and that responses are handled appropriately.

Once the Controller is created, Window contexts (i.e. iframes and popups) can be added, and connections established to Nodes within those contexts.

Channels

Channels are the underlying mechanism that facilitate communication between Controllers and Nodes. They are responsible for establishing and maintaining connections.

Channels also support heartbeat monitoring to detect and recover from connection failures.

Nodes

Nodes are created within child Window contexts (e.g., iframes or popups) and establish connections to Channels in the parent Window context.

Nodes provide a simple interface for posting messages, fetching data, and listening for incoming messages.

Connection States

Node and Channel connections can be in the following states:

  • idle: Initial state before connection
  • handshaking: Establishing connection
  • connected: Active connection
  • disconnected: Connection terminated (Connections only)