@broadcaster/react
TypeScript icon, indicating that this package has built-in type declarations

2.1.1 • Public • Published

React Broadcaster: Cross Window Serverless Messaging System

npm version

Small, package for managing communication between different browsing contexts, like tabs, windows, iFrames, workers, etc.. It adds extra layer over BroadcastChannel with unified error management and context awareness. This is an extension of @broadcaster/core package.

Broadcaster Example

This package not only sends messages to different browser windows or tabs, but it keeps track about all Broadcaster instances across browsing context. In every moment you can see current instance state of any Broadcaster. You can also enhance state with your own metadata. Under the hood, it utilizes the BroadcastChannel API, yet it can be easily replaced with any alternative communication strategy.

Key Features

  • 🚌 BUS between browsing contexts
    Allows to send messages between different browsing contexts and sync Broadcaster instances state.
  • Serverless
    By default, the Broadcaster employs the BroadcastChannel API as its primary bridge interface. This API enables fundamental communication between different browsing contexts such as windows and tabs, eliminating the necessity for a server.
  • 📝 Context aware
    Each instance of the Broadcaster maintains awareness of other instances throughout their lifecycle. It retains essential information and metadata, making this data accessible to every Broadcaster instance subscribed to the same channel.
  • 💪 Accessible on most modern browsers and Node.JS
    In 2023 all main browsers supports BroadcastChannel API (Most recently Safari v 15.4) - see caniuse
  • ⚙️⚙️⚙️ Modular
    Given Broadcaster's significant dependence on the BroadcastChannel API, users have the flexibility to alter the communication protocol by simply replacing the Bridge instance.
  • Resilient
    Errors identified during the broadcasting phase are transferred into a separate error stream, allowing the channel to remain open for additional incoming messages.

Detailed Broadcaster description

More information about Broadcasters and its architecture can be found in core package.

Quick-start

Installation

NPM

npm i --save @broadcaster/core @broadcaster/react

Yarn

yarn add @broadcaster/core @broadcaster/react

Creating Broadcaster Hooks

import { createBroadcaster } from "@broadcaster/react";

// Custom Broadcaster message shape
export type Message = {
    message: string;
};

// Custom Broadcaster state shape
export type Metadata = {
    iteration: number;
    currentTime: number;
};

/**
 * It is recommended to have only one Broadcaster instance per system per
 * channel. Create Broadcaster instance in a root of you App.
 */
export const { useBroadcaster } = createBroadcaster<Message, Metadata>({
    // All broadcaster with same channel name will be able to communicate.
    channel: "YOUR_CHANNEL_NAME",
    metadata: {
        iteration: 0,
        currentTime: Date.now();
    },
    // For more settings check Broadcaster Constructor Settings section down below
});

Sending and Receiving a Message

// from previous example
import { BroadcasterMessage } from "@broadcaster/core";
import { useBroadcaster, Message } from "path/to/hook";
import React, { FunctionComponent, useState, useEffect, useCallback } from "react";

const MessageExample: FunctionComponent = () => {
    // store all messages
    const [messages, setMessage] = useState<BroadcasterMessage<Message>[]>([]);

    // useBroadcaster hooks returns latest message only
    const { message: latestMessage, postMessage } = useBroadcaster();

    // add message to a list
    useEffect(() => {
        setMessage((currentMessages) => ([...currentMessages, latestMessage]));
    }, [latestMessage]);

    // send a message
    const send: FormEventHandler = useCallback((event)=>{
        event.preventDefault();
        const input = e.target[0];

        postMessage({
            message: input.value,
        });

        e.target[0].value = "";
    }, []);

    return <div className="message-wrapper">
        <div className="messages">
            {/** Payload is wrapped in message object, which has some metadata about message owner*/}
            { messages.map(({from, payload: { message }}, i) => (
                <div className="message" key={message + from}>
                    <span>Owner: {from}</span>
                    <br />
                    <p>{message}</p>
                </div>
            )) }
        </div>
        <form className="post-message" onSubmit={send}>
            <input type="text" />
            <button type="submit">Send</button>
        </form>
    </div>
};

Getting Broadcaster Instance State and Update Metadata

Each Broadcaster instance has it's inner state, which will be shared with other instances. Each Broadcaster instance keeps synced list of all broadcaster instances with their current state and metadata.

// from Create Broadcaster Hooks
import { useBroadcaster } from "path/to/hook";
import React, { FunctionComponent, useEffect } from "react";

const StateExample: FunctionComponent = () => {
    const { broadcasters, updateMetadata } = useBroadcaster();

    // each second update broadcasters metadata
    useEffect(() => {
        const timer = setInterval(() => {
            setState((currentState) => ({
                iteration: currentState.iteration,
                currentTime: Date.now(),
            }));
        }, 1000);
    }, []);

    return <div className="broadcaster-instances-info-wrapper">
        <div className="broadcaster-instances-info">
            {/** Iterate through all broadcaster states*/}
            { broadcasters.map(({id, createdAt, metadata: { iteration, currentTime }}) => (
                <div className="broadcaster-instance" key={id}>
                    <h2>Broadcaster {id}</h2>
                    <ul>
                        <li>Connection Time: {createdAt}</li>
                        <li>State Change Counter: {iteration}</li>
                        <li>Last State Change Time: {currentTime}</li>
                    </ul>
                </div>
            )) }
        </div>
    </div>
};

Package Sidebar

Install

npm i @broadcaster/react

Weekly Downloads

1

Version

2.1.1

License

MIT

Unpacked Size

25.4 kB

Total Files

13

Last publish

Collaborators

  • pavelstencl