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

@airtame/dove

v3.35.4

Published

Message definitions and utilities for entities in the arc project.

Downloads

42

Readme

Dove

This package contains message definitions for the different entitites in the ARC project.

It serves as both a contract, definition and implementation for the communication between arc-control and the Desktop Application, as well as between arc-screen and the DisplayManager.

Usage

In your project

To start, make sure that your project is setup to use Airtame's private NPM repository:

echo @airtame:registry=https://gitlab.com/api/v4/packages/npm/ >> .npmrc

And the you can simply install the library:

npm install --save @airtame/dove

Note:

You will need to set up your NPM config to log onto our Gitlab instance:

npm config set '//gitlab.com/api/v4/packages/npm/:_authToken' "<your token>"

But you should replace your token with a token that you generate here: https://gitlab.com/profile/personal_access_tokens.

Your token should have read_api and read_repository rights to work.

API

Four core Messenger classes are available, which serves, in pairs, to provide means of message passing between the different entitites in ARC. The messages between messengers are passed by using [postMessage()] on a Window-like object.

Predefined typed messages can be passed between the classes as shown below. The available message types are specified in Messages.ts.

DisplayManagerMessenger ↔︎ ScreenMessenger

DesktopAppMessenger ↔︎ ControlMessenger

ZoomScreenMessenger ↔︎ ZoomIframeMessenger

All Messenger classes provides the same core api.

addRequestListener(listener: (msg: ReceiveRequestType, next: NextFunction) => Promise<SendRequestType>): void

Adds a handler for the request.

The handler must return a Promise which is resolved when the request is successfully handled, rejected if an error occurs or call next() if the message received is not handled by this current handler.

removeRequestListener(listener: (msg: ReceiveRequestType, next: NextFunction) => Promise<SendRequestType>): void

Removes the listener from the list.

addNotificationListener(listener: (msg: ReceiveNotificationType) => void): void

Adds a listener for notifications. This will be called for each notifications.

removeNotificationListener(listener: (msg: ReceiveNotificationType) => void): void

Removes the listener.

sendRequest( msg: SendMessageType, timeout = DEFAULT_REQUEST_TIMEOUT): Promise<SendMessageType>

Sends a request to a receiving messenger, and returns a promise which either resolves or rejects, depending on whether the receiver handled the message or not.

If the call times out, it means that the request was either not handled, or took too long to be processed.

sendNotification(msg: SendNotificationType): void

Dispatches a message without waiting for a confirmation of receival.

Examples

Create 2 messengers and send/handle/reply a message

This example will be demonstrated with the (display-manager-utils)[https://gitlab.com/airtame/device/display-manager-utils] library but it could be replaced by anything else.

/***********************/
/* DESKTOP APPLICATION */
/***********************/
import {
  DesktopAppMessage,
  DesktopAppMessenger,
  ControlMessage,
  ControlMessageName,
  DesktopAppMessageName,
} from '@airtame/dove';
import {
  AutoReadyMessagingProxy,
  PageEndpoint,
  ProxyEnvelope,
  Sender,
} from '@airtame/display-manager-utils';

const dmEndpoint = new PageEndpoint<
  ProxyEnvelope<DesktopAppMessage, ControlMessage>
>({
  sendWindow: window,
  receiveWindow: window,
  name: Sender.ContentScript,
  peerName: Sender.Page,
});
const proxy = new AutoReadyMessagingProxy<DesktopAppMessage, ControlMessage>({
  endpoint: dmEndpoint,
});
const desktopMessenger = new DesktopAppMessenger(proxy);

try {
  const message = await desktopMessenger.sendRequest({
    name: DesktopAppMessageName.CALL_INFO_REQUEST,
  });

  if (message.name === ControlMessageName.CALL_INFO_RESPONSE) {
    if (message.isInCall) {
      await this.leaveCall();
    } else {
      await this.endCall();
    }
  }
} catch (err) {
  logger.error('Failed to get call info', { err });
} finally {
  this.stop();
}

/***********/
/* CONTROL */
/***********/
import {
  ControlMessenger,
  ControlMessage,
  DesktopAppMessage,
  NextFunction,
} from '@airtame/dove';
import {
  AutoReadyMessagingProxy,
  PageEndpoint,
  ProxyEnvelope,
  Sender,
} from '@airtame/display-manager-utils';

const endpoint = new PageEndpoint<
  ProxyEnvelope<ControlMessage, DesktopAppMessage>
>({
  sendWindow: window.parent,
  receiveWindow: window,
  name: Sender.Page,
  peerName: Sender.ContentScript,
});
const proxy = new AutoReadyMessagingProxy<ControlMessage, DesktopAppMessage>({
  endpoint,
});
controlMessenger = new ControlMessenger(proxy);

const handleRequest = (
  message: DesktopAppMessage,
  next: NextFunction
): Promise<ControlMessage> => {
  if (message.name === DesktopAppMessageName.CALL_INFO_REQUEST_v1) {
    return Promise.resolve({
      name: ControlMessageName.CALL_INFO_RESPONSE,
      isInCall: meetingJoined !== -1 && meetingLeft === -1,
    });
  }

  next();
};

controlMessenger.addRequestListener(handleRequest);

Examples in tests

A few tests are included which showcases usage of the various Messenger classes:

Versioning of messages

The versioning of messages is relatively simple: we will have the versioning made via new messages (see adr).

That means that for if a message need to be upgraded, we simply create a new message.

Here is an example:

// You are using the message to send the SDP offer:
type ControlMessages = {
  name: ControlMessageName.SDP_OFFER_v1;
  description: RTCSessionDescriptionJSON;
};

// All is well but now there is a new field that is useful in the new version that
// would allow you to tell the peer if this is a renewal or not. For that you need
// to create a new version of the message:
type ControlMessages =
  | {
      name: ControlMessageName.SDP_OFFER_v1;
      description: RTCSessionDescriptionJSON;
    }
  | {
      name: ControlMessageName.SDP_OFFER_v2;
      description: RTCSessionDescriptionJSON;
      renewal: boolean;
    };

// In the handler, in an effort to keep backward compatibility you could have:
desktopAppMessenger.addRequestListener(
  (message: ControlMessage, next: NextFunction): Promise<DesktopAppMessage> => {
    switch (message.name) {
      case ControlMessageName.SDP_OFFER_v2: {
        if (!this.isActive) {
          return Promise.reject();
        }
        const { description, renewal } = message;
        return this.handleSDPOffer(description, renewal).then(
          (descriptionResp) => {
            const replyMessage: DesktopAppMessage = {
              name: DesktopAppMessageName.SDP_ANSWER_v2,
              description: descriptionResp,
              renewal,
            };
            return Promise.resolve(replyMessage);
          }
        );
      }

      case ControlMessageName.SDP_OFFER_v1: {
        if (!this.isActive) {
          return Promise.reject();
        }
        const { description } = message;
        return this.handleSDPOffer(
          description,
          true /* Imagine this would be our default in case*/
        ).then((descriptionResp) => {
          const replyMessage: DesktopAppMessage = {
            name: DesktopAppMessageName.SDP_ANSWER_v1,
            description: descriptionResp,
          };
          return Promise.resolve(replyMessage);
        });
      }

      default:
        next();
    }
  }
);

This would be the same for notifications and replies.

Build

To build the library:

# Install the dependencies
npm install

# Run the build script
npm run build

After that you have the artifacts in the dist/ folder.

Development

Use yalc package to publish and install local version of @airtame/dove to another local project.

To install yalc globally, run:

npm i -g yalc

To publish, first build the changes, then run:

npx yalc publish

Then inside another project run:

npx yalc install @airtame/dove

Release

To create a release, you need to update related files, merge changes into master branch and create a tag from master named as version number prefixed with v as follows: v1.2.3.

To update related files run the following command:

npm run release:prepare [major | minor | patch]

Then push to remote, review and merge the changes.

After that switch back to master, pull the latest changes, and create a tag:

git checkout master
git pull --rebase
git tag v1.2.3
git push origin v1.2.3

CHANGELOG

Architecture Decision Records

  1. Record architecture decisions
  2. Message versioning