@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
JavaScript
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