UNPKG

@webrtc-remote-control/react

Version:

Thin abstraction layer above peerjs that will let you be more productive at making WebRTC data channels based apps.

125 lines (106 loc) 4.01 kB
import React, { createContext, useRef, useEffect, useState, useContext } from 'react'; import PropTypes from 'prop-types'; import { prepareUtils, master, remote } from '@webrtc-remote-control/core'; // eslint-disable-next-line import/no-extraneous-dependencies const MyContext = createContext(); function Provider({ children, sessionStorageKey, humanErrors, mode, masterPeerId, init }) { const allowedMode = ["master", "remote"]; if (!allowedMode.includes(mode)) { throw new Error(`Unsupported "${mode}" mode. Only ${allowedMode.map(a => `"${a}"`).join(", ")} accepted.`); } if (mode === "master" && masterPeerId) { console.log(typeof masterPeerId); throw new Error(`\`masterPeerId\` prop not allowed in "master" mode - "${masterPeerId}" was passed.`); } if (mode === "remote" && !masterPeerId) { throw new Error(`\`masterPeerId\` prop required in "remote" mode.`); } const utils = prepareUtils({ sessionStorageKey, humanErrors }); const providerValue = useRef({ peer: null, promise: null, mode, masterPeerId }); useEffect(() => { // expose the following on the ref forwarded to the provider providerValue.current.mode = mode; providerValue.current.humanizeError = utils.humanizeError; if (mode === "master") { providerValue.current.isConnectionFromRemote = utils.isConnectionFromRemote; } // init callback that should return a peer instance like: // `({ getPeerId }) => new Peer(getPeerId())` providerValue.current.peer = init({ humanizeError: utils.humanizeError, getPeerId: utils.getPeerId, isConnectionFromRemote: mode === "master" ? utils.isConnectionFromRemote : undefined }); providerValue.current.promise = (mode === "master" ? master : remote).default(utils).bindConnection(providerValue.current.peer, remote ? masterPeerId : undefined); // start resolving the promise as soon as possible (it will be used in `usePeer`) providerValue.current.promise.then(() => {}); return () => { if (providerValue.current) { // eslint-disable-next-line react-hooks/exhaustive-deps providerValue.current.peer.disconnect(); } }; }, [mode, masterPeerId, init, utils]); return /*#__PURE__*/React.createElement(MyContext.Provider, { value: providerValue.current }, children); } Provider.propTypes = { children: PropTypes.any, sessionStorageKey: PropTypes.string, humanErrors: PropTypes.object, mode: PropTypes.oneOf(["master", "remote"]), masterPeerId: PropTypes.string, init: PropTypes.func }; function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } function usePeer() { // track if the hook is fully ready const [ready, setReady] = useState(false); // track if the peer object is ready (to allow consumer to subscribe to error event) const [, setPeerReady] = useState(false); const context = useContext(MyContext); const resolvedWrcApi = useRef(null); useEffect(() => { // run on next tick (ensure the `then` of the Provider has executed + retrieve the api from the resolve promise) Promise.resolve().then(() => { var _context$promise; setPeerReady(true); // peer object is not null anymore context == null ? void 0 : (_context$promise = context.promise) == null ? void 0 : _context$promise.then(wrcApi => { resolvedWrcApi.current = wrcApi; setReady(true); }); }); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); return _extends({ ready, api: resolvedWrcApi.current }, context); } export { Provider as WebRTCRemoteControlProvider, usePeer }; //# sourceMappingURL=react.modern.js.map