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

@mashroom/mashroom-messaging

v2.7.1

Published

Adds a Service plugin for server-side messaging and comes with a WebSocket interface that allows sending messages across clients (and browser tabs)

Downloads

106

Readme

Mashroom Messaging

Plugin for Mashroom Server, a Microfrontend Integration Platform.

This plugin adds server side messaging support to Mashroom Server. If an external provider plugin (e.g. MQTT) is configured the messages can also be sent across multiple nodes (cluster support!) and to 3rd party systems.

Optionally it supports sending and receiving messages via WebSocket (Requires mashroom-websocket).

Usage

If node_modules/@mashroom is configured as plugin path just add @mashroom/mashroom-messaging as dependency.

And you can use the messaging service like this:

import type {MashroomMessagingService} from '@mashroom/mashroom-messaging/type-definitions';

export default async (req: Request, res: Response) => {
    const messagingService: MashroomMessagingService = req.pluginContext.services.messaging.service;

    // Subscribe
    await messagingService.subscribe(req, 'my/topic', (data) => {
        // Do something with data
    });

    // Publish
    await messagingService.publish(req, 'other/topic', {
        item: 'Beer',
        quantity: 1,
    });

    // ...
}

You can override the default config in your Mashroom config file like this:

{
  "plugins": {
        "Mashroom Messaging Services": {
            "externalProvider": null,
            "externalTopics": [],
            "userPrivateBaseTopic": "user",
            "enableWebSockets": true,
            "topicACL": "./topicACL.json"
        }
    }
}
  • externalProvider: A plugin that connects to an external messaging system. Allows to receive messages from other systems and to send messages "out" (Default: null)
  • externalTopics: A list of topic roots that should be considered as external. E.g. if the list contains other-system topics published to other-system/foo or other-system/bar would be sent via externalProvider. (Default: [])
  • userPrivateBaseTopic: The base for private user topics. If the prefix is something/user the user john would only be able to subscribe to user/john/something and not to something/user/thomas/weather-update (Default: user).
  • enableWebSockets: Enable WebSocket support when mashroom-websocket is present (Default: true)
  • topicACL: Access control list to restrict the use of certain topic patterns to specific roles (Default: ./topicACL.json)

With a config like that you can place a file topic_acl.json in your server config with a content like this:

{
    "$schema": "https://www.mashroom-server.com/schemas/mashroom-security-topic-acl.json",
    "my/topic": {
        "allow": ["Role1"]
    },
    "foo/bar/#": {
        "allow": "any"
        "deny": ["NotSoTrustedRole"]
    }
}

The general structure is:

    "/my/+/topic/#": {
        "allow": "any"|<array of roles>
        "deny": "any"|<array of roles>
    }

You can use here + or * as a wildcard for a single level and # for multiple levels.

WebSocket interface

If enableWebSockets is true you can connect to the messaging system on <websocket_base_path>/messaging which is by default /websocket/messaging. The server expects and sends serialized JSON.

After a successful connection you can use the following commands:

Subscribe

{
  messageId: 'ABCD',
  command: 'subscribe',
  topic: 'foo/bar',
}

The messageId should be unique. You will get a response message like this when the operation succeeds:

{
  messageId: 'ABCD',
  success: true,
}

Otherwise a error message like this:

{
  messageId: 'ABCD',
  error: true,
  message: 'The error message'
}

Unsubscribe

{
  messageId: 'ABCD',
  command: 'unsubscribe',
  topic: 'foo/bar',
}

Success and error response messages are the same as above.

Publish

{
  messageId: 'ABCD',
  command: 'publish',
  topic: 'foo/bar',
  message: {
     foo: 'bar'
  }
}

Success and error response messages are the same as above.

And the server will push the following if a message for a subscribed topic arrives:

{
  remoteMessage: true,
  topic: 'foo/bar',
  message: {
     what: 'ever'
  }
}

Services

MashroomMessagingService

The exposed service is accessible through pluginContext.services.messaging.service

Interface:

export interface MashroomMessagingService {
    /**
     * Subscribe to given topic.
     * Topics can be hierarchical and also can contain wildcards. Supported wildcards are + for a single level
     * and # for multiple levels. E.g. foo/+/bar or foo/#
     *
     * Throws an exception if there is no authenticated user
     */
    subscribe(req: Request, topic: string, callback: MashroomMessagingSubscriberCallback): Promise<void>;

    /**
     * Unsubscribe from topic
     */
    unsubscribe(topic: string, callback: MashroomMessagingSubscriberCallback): Promise<void>;

    /**
     * Publish to a specific topic
     *
     * Throws an exception if there is no authenticated user
     */
    publish(req: Request, topic: string, data: any): Promise<void>;

    /**
     * The private topic only the current user can access.
     * E.g. if the value is user/john the user john can access to user/john/whatever
     * but not to user/otheruser/foo
     *
     * Throws an exception if there is no authenticated user
     */
    getUserPrivateTopic(req: Request): string;

    /**
     * The connect path to send publish or subscribe via WebSocket.
     * Only available if enableWebSockets is true and mashroom-websocket is preset.
     */
    getWebSocketConnectPath(req: Request): string | null | undefined;
}

Plugin Types

external-messaging-provider

This plugin type connects the messaging system to an external message broker. It also adds cluster support to the messaging system.

To register your custom external-messaging-provider plugin add this to package.json:

{
    "mashroom": {
        "plugins": [
            {
                "name": "My Custom External Messaging Provider",
                "type": "external-messaging-provider",
                "bootstrap": "./dist/mashroom-bootstrap",
                "defaultConfig": {
                   "myProperty": "foo"
                }
            }
        ]
    }
}

The bootstrap returns the provider:

import type {MashroomExternalMessagingProviderPluginBootstrapFunction} from '@mashroom/mashroom-messaging/type-definitions';

const bootstrap: MashroomExternalMessagingProviderPluginBootstrapFunction = async (pluginName, pluginConfig, pluginContextHolder) => {

    return new MyExternalMessagingProvider(/* ... */);
};

export default bootstrap;

The provider has to implement the following interface:

export interface MashroomMessagingExternalProvider {
    /**
     * Add a message listener
     * The message must be a JSON object.
     */
    addMessageListener(listener: MashroomExternalMessageListener): void;

    /**
     * Remove an existing listener
     */
    removeMessageListener(listener: MashroomExternalMessageListener): void;

    /**
     * Send a message to given internal topic.
     * Used to broadcast message between Mashroom instances.
     *
     * The passed topic must be prefixed with the topic the provider is listening to.
     * E.g. if the passed topic is foo/bar and the provider is listening to mashroom/# the message must be
     * sent to mashroom/foo/bars.
     *
     * The message will be a JSON object.
     */
    sendInternalMessage(topic: string, message: any): Promise<void>;

    /**
     * Send a message to given external topic.
     * Used to send messages to 3rd party systems.
     *
     * The message will be a JSON object.
     */
    sendExternalMessage(topic: string, message: any): Promise<void>;
}