react-peer-chat 0.6.3 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/icons.js CHANGED
@@ -1,28 +1,28 @@
1
1
  import React from "react";
2
2
  export function BiSolidMessageDetail(props) {
3
- return React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
3
+ return (React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
4
4
  React.createElement("svg", { viewBox: "0 0 24 24", width: "1.25rem", height: "1.25rem" },
5
- React.createElement("path", { d: "M20 2H4c-1.103 0-2 .894-2 1.992v12.016C2 17.106 2.897 18 4 18h3v4l6.351-4H20c1.103 0 2-.894 2-1.992V3.992A1.998 1.998 0 0 0 20 2zm-6 11H7v-2h7v2zm3-4H7V7h10v2z" })));
5
+ React.createElement("path", { d: "M20 2H4c-1.103 0-2 .894-2 1.992v12.016C2 17.106 2.897 18 4 18h3v4l6.351-4H20c1.103 0 2-.894 2-1.992V3.992A1.998 1.998 0 0 0 20 2zm-6 11H7v-2h7v2zm3-4H7V7h10v2z" }))));
6
6
  }
7
7
  export function BiSolidMessageX(props) {
8
- return React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
8
+ return (React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
9
9
  React.createElement("svg", { viewBox: "0 0 24 24", width: "1.25rem", height: "1.25rem" },
10
- React.createElement("path", { d: "M20 2H4c-1.103 0-2 .894-2 1.992v12.016C2 17.106 2.897 18 4 18h3v4l6.351-4H20c1.103 0 2-.894 2-1.992V3.992A1.998 1.998 0 0 0 20 2zm-3.293 11.293-1.414 1.414L12 11.414l-3.293 3.293-1.414-1.414L10.586 10 7.293 6.707l1.414-1.414L12 8.586l3.293-3.293 1.414 1.414L13.414 10l3.293 3.293z" })));
10
+ React.createElement("path", { d: "M20 2H4c-1.103 0-2 .894-2 1.992v12.016C2 17.106 2.897 18 4 18h3v4l6.351-4H20c1.103 0 2-.894 2-1.992V3.992A1.998 1.998 0 0 0 20 2zm-3.293 11.293-1.414 1.414L12 11.414l-3.293 3.293-1.414-1.414L10.586 10 7.293 6.707l1.414-1.414L12 8.586l3.293-3.293 1.414 1.414L13.414 10l3.293 3.293z" }))));
11
11
  }
12
12
  export function GrSend(props) {
13
- return React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
13
+ return (React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
14
14
  React.createElement("svg", { viewBox: "0 0 24 24", width: "1.25rem", height: "1.25rem", className: "rpc-invert" },
15
- React.createElement("path", { fill: "none", stroke: "#000", strokeWidth: 2, d: "M22,3 L2,11 L20.5,19 L22,3 Z M10,20.5 L13,16 M15.5,9.5 L9,14 L9.85884537,20.0119176 C9.93680292,20.5576204 10.0751625,20.5490248 10.1651297,20.009222 L11,15 L15.5,9.5 Z" })));
15
+ React.createElement("path", { fill: "none", stroke: "#000", strokeWidth: 2, d: "M22,3 L2,11 L20.5,19 L22,3 Z M10,20.5 L13,16 M15.5,9.5 L9,14 L9.85884537,20.0119176 C9.93680292,20.5576204 10.0751625,20.5490248 10.1651297,20.009222 L11,15 L15.5,9.5 Z" }))));
16
16
  }
17
17
  export function BsFillMicFill(props) {
18
- return React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
18
+ return (React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
19
19
  React.createElement("svg", { viewBox: "0 0 16 16", fill: "currentColor", width: "1.25rem", height: "1.25rem" },
20
20
  React.createElement("path", { d: "M5 3a3 3 0 0 1 6 0v5a3 3 0 0 1-6 0V3z" }),
21
- React.createElement("path", { d: "M3.5 6.5A.5.5 0 0 1 4 7v1a4 4 0 0 0 8 0V7a.5.5 0 0 1 1 0v1a5 5 0 0 1-4.5 4.975V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1h3v-2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 .5-.5z" })));
21
+ React.createElement("path", { d: "M3.5 6.5A.5.5 0 0 1 4 7v1a4 4 0 0 0 8 0V7a.5.5 0 0 1 1 0v1a5 5 0 0 1-4.5 4.975V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1h3v-2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 .5-.5z" }))));
22
22
  }
23
23
  export function BsFillMicMuteFill(props) {
24
- return React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
24
+ return (React.createElement("span", Object.assign({ className: "rpc-icon-container" }, props),
25
25
  React.createElement("svg", { viewBox: "0 0 16 16", fill: "currentColor", width: "1.25rem", height: "1.25rem" },
26
26
  React.createElement("path", { d: "M13 8c0 .564-.094 1.107-.266 1.613l-.814-.814A4.02 4.02 0 0 0 12 8V7a.5.5 0 0 1 1 0v1zm-5 4c.818 0 1.578-.245 2.212-.667l.718.719a4.973 4.973 0 0 1-2.43.923V15h3a.5.5 0 0 1 0 1h-7a.5.5 0 0 1 0-1h3v-2.025A5 5 0 0 1 3 8V7a.5.5 0 0 1 1 0v1a4 4 0 0 0 4 4zm3-9v4.879L5.158 2.037A3.001 3.001 0 0 1 11 3z" }),
27
- React.createElement("path", { d: "M9.486 10.607 5 6.12V8a3 3 0 0 0 4.486 2.607zm-7.84-9.253 12 12 .708-.708-12-12-.708.708z" })));
27
+ React.createElement("path", { d: "M9.486 10.607 5 6.12V8a3 3 0 0 0 4.486 2.607zm-7.84-9.253 12 12 .708-.708-12-12-.708.708z" }))));
28
28
  }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
- import React, { CSSProperties, DetailedHTMLProps, HTMLAttributes, ReactNode } from 'react';
2
- import { PeerOptions as ImportedPeerOptions } from 'peerjs';
1
+ import React, { CSSProperties, DetailedHTMLProps, HTMLAttributes, ReactNode } from "react";
2
+ import { PeerOptions } from "peerjs";
3
3
  export type RemotePeerId = string | string[];
4
- export type PeerOptions = ImportedPeerOptions;
5
- export type DialogPosition = 'left' | 'center' | 'right';
4
+ export type { PeerOptions };
5
+ export type DialogPosition = "left" | "center" | "right";
6
6
  export type DialogOptions = {
7
7
  position?: DialogPosition;
8
8
  style?: CSSProperties;
@@ -37,6 +37,6 @@ export type ChatProps = {
37
37
  children?: Children;
38
38
  props?: Props;
39
39
  };
40
- export type { IconProps } from './icons.js';
40
+ export type { IconProps } from "./icons.js";
41
41
  export default function Chat({ name, peerId, remotePeerId, peerOptions, text, recoverChat, voice, dialogOptions, onError, onMicError, children, props }: ChatProps): React.JSX.Element;
42
42
  export declare const clearChat: () => void;
package/dist/index.js CHANGED
@@ -7,78 +7,72 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
7
7
  step((generator = generator.apply(thisArg, _arguments || [])).next());
8
8
  });
9
9
  };
10
- import React, { useEffect, useRef, useState } from 'react';
11
- import useStorage, { removeStorage } from './storage.js';
12
- import { BiSolidMessageDetail, BiSolidMessageX, BsFillMicFill, BsFillMicMuteFill, GrSend } from './icons.js';
10
+ import React, { useEffect, useRef, useState } from "react";
11
+ import useStorage, { removeStorage } from "./storage.js";
12
+ import { BiSolidMessageDetail, BiSolidMessageX, BsFillMicFill, BsFillMicMuteFill, GrSend } from "./icons.js";
13
13
  const turnAccounts = [
14
14
  { username: "70061a377b51f3a3d01c11e3", credential: "lHV4NYJ5Rfl5JNa9" },
15
15
  { username: "13b19eb65bbf6e9f96d64b72", credential: "7R9P/+7y7Q516Etv" },
16
16
  { username: "3469603f5cdc7ca4a1e891ae", credential: "/jMyLSDbbcgqpVQv" },
17
17
  { username: "a7926f4dcc4a688d41f89752", credential: "ZYM8jFYeb8bQkL+N" },
18
18
  { username: "0be25ab7f61d9d733ba94809", credential: "hiiSwWVch+ftt3SX" },
19
- { username: "3c25ba948daeab04f9b66187", credential: "FQB3GQwd27Y0dPeK" }
19
+ { username: "3c25ba948daeab04f9b66187", credential: "FQB3GQwd27Y0dPeK" },
20
20
  ];
21
21
  const defaultConfig = {
22
- iceServers: [{
23
- urls: [
24
- "stun:stun.l.google.com:19302",
25
- "stun:stun.relay.metered.ca:80"
26
- ]
27
- }].concat(turnAccounts.map(account => (Object.assign({ urls: [
28
- "turn:standard.relay.metered.ca:80",
29
- "turn:standard.relay.metered.ca:80?transport=tcp",
30
- "turn:standard.relay.metered.ca:443",
31
- "turns:standard.relay.metered.ca:443?transport=tcp"
32
- ] }, account))))
22
+ iceServers: [
23
+ {
24
+ urls: ["stun:stun.l.google.com:19302", "stun:stun.relay.metered.ca:80"],
25
+ },
26
+ ].concat(turnAccounts.map((account) => (Object.assign({ urls: ["turn:standard.relay.metered.ca:80", "turn:standard.relay.metered.ca:80?transport=tcp", "turn:standard.relay.metered.ca:443", "turns:standard.relay.metered.ca:443?transport=tcp"] }, account)))),
33
27
  };
34
28
  function closeConnection(conn) {
35
29
  conn.removeAllListeners();
36
30
  conn.close();
37
31
  }
38
- export default function Chat({ name, peerId, remotePeerId = [], peerOptions, text = true, recoverChat = false, voice = true, dialogOptions, onError = () => alert('Browser not supported! Try some other browser.'), onMicError = () => alert('Microphone not accessible!'), children, props = {} }) {
32
+ export default function Chat({ name, peerId, remotePeerId = [], peerOptions, text = true, recoverChat = false, voice = true, dialogOptions, onError = () => alert("Browser not supported! Try some other browser."), onMicError = () => alert("Microphone not accessible!"), children, props = {} }) {
39
33
  const [peer, setPeer] = useState();
40
34
  const [notification, setNotification] = useState(false);
41
- const [remotePeers, setRemotePeers] = useStorage('rpc-remote-peer', {});
42
- const [messages, setMessages] = useStorage('rpc-messages', []);
35
+ const [remotePeers, setRemotePeers] = useStorage("rpc-remote-peer", {});
36
+ const [messages, setMessages] = useStorage("rpc-messages", []);
43
37
  const connRef = useRef({});
44
38
  const [dialog, setDialog] = useState(false);
45
39
  const dialogRef = useRef(null);
46
40
  const containerRef = useRef(null);
47
41
  const inputRef = useRef(null);
48
- const [audio, setAudio] = useStorage('rpc-audio', false, true);
42
+ const [audio, setAudio] = useStorage("rpc-audio", false, true);
49
43
  const streamRef = useRef(null);
50
44
  const localStream = useRef();
51
45
  peerId = `rpc-${peerId}`;
52
- if (typeof remotePeerId === 'string')
46
+ if (typeof remotePeerId === "string")
53
47
  remotePeerId = [remotePeerId];
54
- const remotePeerIds = remotePeerId.map(id => `rpc-${id}`);
55
- const handleRemoteStream = (remoteStream) => streamRef.current.srcObject = remoteStream;
48
+ const remotePeerIds = remotePeerId.map((id) => `rpc-${id}`);
49
+ const handleRemoteStream = (remoteStream) => (streamRef.current.srcObject = remoteStream);
56
50
  function addMessage(message, sendToRemotePeer = false) {
57
51
  var _a;
58
- setMessages(prev => prev.concat(message));
52
+ setMessages((prev) => prev.concat(message));
59
53
  if (sendToRemotePeer)
60
- Object.values(connRef.current).forEach(conn => conn.send({ type: 'message', message }));
54
+ Object.values(connRef.current).forEach((conn) => conn.send({ type: "message", message }));
61
55
  else if (!((_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.open))
62
56
  setNotification(true);
63
57
  }
64
58
  function handleConnection(conn) {
65
59
  connRef.current[conn.peer] = conn;
66
- conn.on('open', () => {
67
- conn.on('data', ({ type, message, remotePeerName, messages }) => {
68
- if (type === 'message')
60
+ conn.on("open", () => {
61
+ conn.on("data", ({ type, message, remotePeerName, messages }) => {
62
+ if (type === "message")
69
63
  addMessage(message);
70
- else if (type === 'init') {
71
- setRemotePeers(prev => {
72
- prev[conn.peer] = remotePeerName || 'Anonymous User';
64
+ else if (type === "init") {
65
+ setRemotePeers((prev) => {
66
+ prev[conn.peer] = remotePeerName || "Anonymous User";
73
67
  return prev;
74
68
  });
75
69
  if (recoverChat)
76
- setMessages(old => messages.length > old.length ? messages : old);
70
+ setMessages((old) => (messages.length > old.length ? messages : old));
77
71
  }
78
72
  });
79
- conn.send({ type: 'init', remotePeerName: name, messages });
73
+ conn.send({ type: "init", remotePeerName: name, messages });
80
74
  });
81
- conn.on('close', conn.removeAllListeners);
75
+ conn.on("close", conn.removeAllListeners);
82
76
  }
83
77
  function handleError() {
84
78
  setAudio(false);
@@ -91,7 +85,7 @@ export default function Chat({ name, peerId, remotePeerId = [], peerOptions, tex
91
85
  }
92
86
  (function () {
93
87
  return __awaiter(this, void 0, void 0, function* () {
94
- const { Peer, util: { supports: { audioVideo, data } } } = yield import('peerjs');
88
+ const { Peer, util: { supports: { audioVideo, data }, }, } = yield import("peerjs");
95
89
  if (!data || !audioVideo)
96
90
  return onError();
97
91
  const peer = new Peer(peerId, Object.assign({ config: defaultConfig }, peerOptions));
@@ -103,8 +97,8 @@ export default function Chat({ name, peerId, remotePeerId = [], peerOptions, tex
103
97
  if (!peer)
104
98
  return;
105
99
  let calls = {};
106
- peer.on('open', () => {
107
- remotePeerIds.forEach(id => {
100
+ peer.on("open", () => {
101
+ remotePeerIds.forEach((id) => {
108
102
  if (text)
109
103
  handleConnection(peer.connect(id));
110
104
  });
@@ -116,20 +110,20 @@ export default function Chat({ name, peerId, remotePeerId = [], peerOptions, tex
116
110
  audio: {
117
111
  autoGainControl: false,
118
112
  noiseSuppression: true,
119
- echoCancellation: true
120
- }
113
+ echoCancellation: true,
114
+ },
121
115
  }, (stream) => {
122
116
  localStream.current = stream;
123
- remotePeerIds.forEach(id => {
117
+ remotePeerIds.forEach((id) => {
124
118
  const call = peer.call(id, stream);
125
- call.on('stream', handleRemoteStream);
126
- call.on('close', call.removeAllListeners);
119
+ call.on("stream", handleRemoteStream);
120
+ call.on("close", call.removeAllListeners);
127
121
  calls[id] = call;
128
122
  });
129
- peer.on('call', call => {
123
+ peer.on("call", (call) => {
130
124
  call.answer(stream);
131
- call.on('stream', handleRemoteStream);
132
- call.on('close', call.removeAllListeners);
125
+ call.on("stream", handleRemoteStream);
126
+ call.on("close", call.removeAllListeners);
133
127
  calls[call.peer] = call;
134
128
  });
135
129
  }, handleError);
@@ -139,10 +133,10 @@ export default function Chat({ name, peerId, remotePeerId = [], peerOptions, tex
139
133
  }
140
134
  }
141
135
  });
142
- peer.on('connection', handleConnection);
136
+ peer.on("connection", handleConnection);
143
137
  return () => {
144
138
  var _a;
145
- (_a = localStream.current) === null || _a === void 0 ? void 0 : _a.getTracks().forEach(track => track.stop());
139
+ (_a = localStream.current) === null || _a === void 0 ? void 0 : _a.getTracks().forEach((track) => track.stop());
146
140
  Object.values(connRef.current).forEach(closeConnection);
147
141
  connRef.current = {};
148
142
  Object.values(calls).forEach(closeConnection);
@@ -162,41 +156,41 @@ export default function Chat({ name, peerId, remotePeerId = [], peerOptions, tex
162
156
  if (container)
163
157
  container.scrollTop = container.scrollHeight;
164
158
  }, [dialog, remotePeers, messages]);
165
- return React.createElement("div", Object.assign({ className: 'rpc-main rpc-font' }, props),
166
- typeof children === 'function' ? children({ remotePeers, messages, addMessage, audio, setAudio }) : React.createElement(React.Fragment, null,
167
- text && React.createElement("div", { className: 'rpc-dialog-container' },
168
- dialog ? React.createElement(BiSolidMessageX, { title: 'Close chat', onClick: () => setDialog(false) }) : React.createElement("div", { className: 'rpc-notification' },
169
- React.createElement(BiSolidMessageDetail, { title: 'Open chat', onClick: () => {
159
+ return (React.createElement("div", Object.assign({ className: "rpc-main rpc-font" }, props),
160
+ typeof children === "function" ? (children({ remotePeers, messages, addMessage, audio, setAudio })) : (React.createElement(React.Fragment, null,
161
+ text && (React.createElement("div", { className: "rpc-dialog-container" },
162
+ dialog ? (React.createElement(BiSolidMessageX, { title: "Close chat", onClick: () => setDialog(false) })) : (React.createElement("div", { className: "rpc-notification" },
163
+ React.createElement(BiSolidMessageDetail, { title: "Open chat", onClick: () => {
170
164
  setNotification(false);
171
165
  setDialog(true);
172
166
  } }),
173
- notification && React.createElement("span", { className: 'rpc-badge' })),
174
- React.createElement("dialog", { ref: dialogRef, className: `${dialog ? 'rpc-dialog' : ''} rpc-position-${(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.position) || 'center'}`, style: dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.style },
175
- React.createElement("div", { className: 'rpc-heading' }, "Chat"),
176
- React.createElement("hr", { className: 'rpc-hr' }),
167
+ notification && React.createElement("span", { className: "rpc-badge" }))),
168
+ React.createElement("dialog", { ref: dialogRef, className: `${dialog ? "rpc-dialog" : ""} rpc-position-${(dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.position) || "center"}`, style: dialogOptions === null || dialogOptions === void 0 ? void 0 : dialogOptions.style },
169
+ React.createElement("div", { className: "rpc-heading" }, "Chat"),
170
+ React.createElement("hr", { className: "rpc-hr" }),
177
171
  React.createElement("div", null,
178
- React.createElement("div", { ref: containerRef, className: 'rpc-message-container' }, messages.map(({ id, text }, i) => React.createElement("div", { key: i },
172
+ React.createElement("div", { ref: containerRef, className: "rpc-message-container" }, messages.map(({ id, text }, i) => (React.createElement("div", { key: i },
179
173
  React.createElement("strong", null,
180
- id === peerId ? 'You' : remotePeers[id],
174
+ id === peerId ? "You" : remotePeers[id],
181
175
  ": "),
182
- React.createElement("span", null, text)))),
183
- React.createElement("hr", { className: 'rpc-hr' }),
184
- React.createElement("form", { className: 'rpc-input-container', onSubmit: e => {
176
+ React.createElement("span", null, text))))),
177
+ React.createElement("hr", { className: "rpc-hr" }),
178
+ React.createElement("form", { className: "rpc-input-container", onSubmit: (e) => {
185
179
  var _a;
186
180
  e.preventDefault();
187
181
  const text = (_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.value;
188
182
  if (text) {
189
- inputRef.current.value = '';
183
+ inputRef.current.value = "";
190
184
  addMessage({ id: peerId, text }, true);
191
185
  }
192
186
  } },
193
- React.createElement("input", { ref: inputRef, className: 'rpc-input rpc-font', placeholder: 'Enter a message' }),
194
- React.createElement("button", { type: 'submit', className: 'rpc-button' },
195
- React.createElement(GrSend, { title: 'Send message' })))))),
196
- voice && React.createElement("div", null, audio ? React.createElement(BsFillMicFill, { title: 'Turn mic off', onClick: () => setAudio(false) }) : React.createElement(BsFillMicMuteFill, { title: 'Turn mic on', onClick: () => setAudio(true) }))),
197
- voice && audio && React.createElement("audio", { ref: streamRef, autoPlay: true, style: { display: 'none' } }));
187
+ React.createElement("input", { ref: inputRef, className: "rpc-input rpc-font", placeholder: "Enter a message" }),
188
+ React.createElement("button", { type: "submit", className: "rpc-button" },
189
+ React.createElement(GrSend, { title: "Send message" }))))))),
190
+ voice && React.createElement("div", null, audio ? React.createElement(BsFillMicFill, { title: "Turn mic off", onClick: () => setAudio(false) }) : React.createElement(BsFillMicMuteFill, { title: "Turn mic on", onClick: () => setAudio(true) })))),
191
+ voice && audio && React.createElement("audio", { ref: streamRef, autoPlay: true, style: { display: "none" } })));
198
192
  }
199
193
  export const clearChat = () => {
200
- removeStorage('rpc-remote-peer');
201
- removeStorage('rpc-messages');
194
+ removeStorage("rpc-remote-peer");
195
+ removeStorage("rpc-messages");
202
196
  };
package/dist/storage.js CHANGED
@@ -28,7 +28,7 @@ export default function useStorage(key, initialValue, local = false) {
28
28
  });
29
29
  const setValue = (value) => {
30
30
  setStoredValue((old) => {
31
- const updatedValue = typeof value === 'function' ? value(old) : value;
31
+ const updatedValue = typeof value === "function" ? value(old) : value;
32
32
  setStorage(key, updatedValue, local);
33
33
  return updatedValue;
34
34
  });
package/dist/styles.css CHANGED
@@ -19,10 +19,10 @@
19
19
  .rpc-notification .rpc-badge {
20
20
  background-color: red;
21
21
  position: absolute;
22
- top: 0.25rem;
23
- right: 0.25rem;
24
- width: 0.3rem;
25
- height: 0.3rem;
22
+ top: 0;
23
+ right: 0;
24
+ width: 6px;
25
+ aspect-ratio: 1;
26
26
  border-radius: 100%;
27
27
  }
28
28
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-peer-chat",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
4
4
  "description": "An easy to use react component for impleting peer-to-peer chatting.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -32,11 +32,11 @@
32
32
  },
33
33
  "homepage": "https://github.com/SahilAggarwal2004/react-peer-chat#readme",
34
34
  "peerDependencies": {
35
- "react": ">=16.0.0",
36
- "react-dom": ">=16.0.0"
35
+ "react": ">=17.0.0",
36
+ "react-dom": ">=17.0.0"
37
37
  },
38
38
  "devDependencies": {
39
- "@types/react": "^18.2.48"
39
+ "@types/react": "^18.2.57"
40
40
  },
41
41
  "dependencies": {
42
42
  "peerjs": "^1.5.2"