UNPKG

use-broadcast-channel

Version:
112 lines 5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.useBroadcastState = exports.useBroadcastChannel = void 0; const React = __importStar(require("react")); /** * React hook to create and manage a Broadcast Channel across multiple browser windows. * * @param channelName Static name of channel used across the browser windows. * @param handleMessage Callback to handle the event generated when `message` is received. * @param handleMessageError [optional] Callback to handle the event generated when `error` is received. * @returns A function to send/post message on the channel. * @example * ```tsx * import {useBroadcastChannel} from 'react-broadcast-channel'; * * function App () { * const postUserIdMessage = useBroadcastChannel('userId', (e) => alert(e.data)); * return (<button onClick={() => postUserIdMessage('ABC123')}>Send UserId</button>); * } * ``` * --- * Works in browser that support Broadcast Channel API natively. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API#browser_compatibility). * To support other browsers, install and use [broadcastchannel-polyfill](https://www.npmjs.com/package/broadcastchannel-polyfill). */ function useBroadcastChannel(channelName, handleMessage, handleMessageError) { const [channel] = React.useState(typeof window !== "undefined" && "BroadcastChannel" in window ? new BroadcastChannel(channelName + "-channel") : null); useChannelEventListener(channel, "message", handleMessage); useChannelEventListener(channel, "messageerror", handleMessageError); return React.useCallback((data) => channel?.postMessage(data), [channel]); } exports.useBroadcastChannel = useBroadcastChannel; /** * React hook to manage state across browser windows. Has the similar signature as `React.useState`. * * @param channelName Static name of channel used across the browser windows. * @param initialState Initial state. * @returns Tuple of state and setter for the state. * @example * ```tsx * import {useBroadcastState} from 'react-broadcast-channel'; * * function App () { * const [count, setCount] = useBroadcastState('count', 0); * return ( * <div> * <button onClick={() => setCount(prev => prev - 1)}>Decrement</button> * <span>{count}</span> * <button onClick={() => setCount(prev => prev + 1)}>Increment</button> * </div> * ); * } * ``` * --- * Works in browser that support Broadcast Channel API natively. See [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Broadcast_Channel_API#browser_compatibility). * To support other browsers, install and use [broadcastchannel-polyfill](https://www.npmjs.com/package/broadcastchannel-polyfill). */ function useBroadcastState(channelName, initialState) { const [isPending, startTransition] = React.useTransition(); const [state, setState] = React.useState(initialState); const broadcast = useBroadcastChannel(channelName, (ev) => setState(ev.data)); const updateState = React.useCallback((input) => { setState((prev) => { const newState = typeof input === "function" ? input(prev) : input; startTransition(() => broadcast(newState)); return newState; }); }, [broadcast]); return [state, updateState, isPending]; } exports.useBroadcastState = useBroadcastState; // Helpers /** Hook to subscribe/unsubscribe from channel events. */ function useChannelEventListener(channel, event, handler) { const callbackRef = React.useRef(handler); if (callbackRef.current !== handler) { callbackRef.current = handler; } React.useEffect(() => { const callback = callbackRef.current; if (!channel || !callback) { return; } channel.addEventListener(event, callback); return () => channel.removeEventListener(event, callback); }, [channel, event]); } //# sourceMappingURL=index.js.map