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

@broadcaster/react

v2.1.1

Published

React implementation of Broadcaster package. Extension of a Broadcast Channel API. Allows to send messages to multiple windows (tabs, workers, iframes,...) and detect opened windows.

Downloads

18

Readme

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>
};