@fishjam-cloud/react-client 0.19.0 → 0.20.0
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/FishjamProvider.d.ts +1 -0
- package/dist/FishjamProvider.d.ts.map +1 -1
- package/dist/FishjamProvider.js +2 -1
- package/dist/consts.d.ts +5 -0
- package/dist/consts.d.ts.map +1 -0
- package/dist/consts.js +7 -0
- package/dist/contexts/fishjamId.d.ts +2 -0
- package/dist/contexts/fishjamId.d.ts.map +1 -0
- package/dist/contexts/fishjamId.js +2 -0
- package/dist/hooks/useConnection.d.ts +2 -2
- package/dist/hooks/useConnection.d.ts.map +1 -1
- package/dist/hooks/useConnection.js +10 -1
- package/dist/hooks/useLivestreamStreamer.d.ts +40 -0
- package/dist/hooks/useLivestreamStreamer.d.ts.map +1 -0
- package/dist/hooks/useLivestreamStreamer.js +44 -0
- package/dist/hooks/useLivestreamViewer.d.ts +34 -0
- package/dist/hooks/useLivestreamViewer.d.ts.map +1 -0
- package/dist/hooks/useLivestreamViewer.js +45 -0
- package/dist/hooks/useSandbox.d.ts +18 -0
- package/dist/hooks/useSandbox.d.ts.map +1 -0
- package/dist/hooks/useSandbox.js +58 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/package.json +2 -2
- package/dist/hooks/useLivestream.d.ts +0 -9
- package/dist/hooks/useLivestream.d.ts.map +0 -1
- package/dist/hooks/useLivestream.js +0 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FishjamProvider.d.ts","sourceRoot":"","sources":["../src/FishjamProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"FishjamProvider.d.ts","sourceRoot":"","sources":["../src/FishjamProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC/E,OAAO,EAAE,KAAK,iBAAiB,EAAmB,MAAM,OAAO,CAAC;AAkBhE,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAI/F;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB;IAC7D;;;OAGG;IACH,SAAS,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC;IACtC;;;;OAIG;IACH,WAAW,CAAC,EAAE,IAAI,CAAC,sBAAsB,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC;IAC9D;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,yBAAyB,CAAC;IACxD;;OAEG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAC3B;;OAEG;IACH,WAAW,CAAC,EAAE,YAAY,CAAC;IAK3B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,2CAiF1D"}
|
package/dist/FishjamProvider.js
CHANGED
|
@@ -4,6 +4,7 @@ import { useMemo, useRef } from "react";
|
|
|
4
4
|
import { CameraContext } from "./contexts/camera";
|
|
5
5
|
import { CustomSourceContext } from "./contexts/customSource";
|
|
6
6
|
import { FishjamClientContext } from "./contexts/fishjamClient";
|
|
7
|
+
import { FishjamIdContext } from "./contexts/fishjamId";
|
|
7
8
|
import { FishjamClientStateContext } from "./contexts/fishjamState";
|
|
8
9
|
import { InitDevicesContext } from "./contexts/initDevices";
|
|
9
10
|
import { MicrophoneContext } from "./contexts/microphone";
|
|
@@ -65,5 +66,5 @@ export function FishjamProvider(props) {
|
|
|
65
66
|
peerStatus,
|
|
66
67
|
});
|
|
67
68
|
const fishjamClientState = useFishjamClientState(fishjamClientRef.current);
|
|
68
|
-
return (_jsx(FishjamClientContext.Provider, { value: fishjamClientRef, children: _jsx(FishjamClientStateContext.Provider, { value: fishjamClientState, children: _jsx(InitDevicesContext.Provider, { value: initializeDevices, children: _jsx(PeerStatusContext.Provider, { value: peerStatus, children: _jsx(CameraContext.Provider, { value: cameraContext, children: _jsx(MicrophoneContext.Provider, { value: microphoneContext, children: _jsx(ScreenshareContext.Provider, { value: screenShareManager, children: _jsx(CustomSourceContext.Provider, { value: customSourceManager, children: props.children }) }) }) }) }) }) }) }));
|
|
69
|
+
return (_jsx(FishjamClientContext.Provider, { value: fishjamClientRef, children: _jsx(FishjamClientStateContext.Provider, { value: fishjamClientState, children: _jsx(FishjamIdContext.Provider, { value: props.fishjamId ?? null, children: _jsx(InitDevicesContext.Provider, { value: initializeDevices, children: _jsx(PeerStatusContext.Provider, { value: peerStatus, children: _jsx(CameraContext.Provider, { value: cameraContext, children: _jsx(MicrophoneContext.Provider, { value: microphoneContext, children: _jsx(ScreenshareContext.Provider, { value: screenShareManager, children: _jsx(CustomSourceContext.Provider, { value: customSourceManager, children: props.children }) }) }) }) }) }) }) }) }));
|
|
69
70
|
}
|
package/dist/consts.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const FISHJAM_HTTP_CONNECT_URL = "https://fishjam.io/api/v1/connect";
|
|
2
|
+
export declare const FISHJAM_WS_CONNECT_URL = "wss://fishjam.io/api/v1/connect";
|
|
3
|
+
export declare const FISHJAM_WHIP_URL = "https://fishjam.io/api/v1/live/api/whip";
|
|
4
|
+
export declare const FISHJAM_WHEP_URL = "https://fishjam.io/api/v1/live/api/whep";
|
|
5
|
+
//# sourceMappingURL=consts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,wBAAwB,sCAAoC,CAAC;AAC1E,eAAO,MAAM,sBAAsB,oCAAkC,CAAC;AAItE,eAAO,MAAM,gBAAgB,4CAAiC,CAAC;AAC/D,eAAO,MAAM,gBAAgB,4CAAiC,CAAC"}
|
package/dist/consts.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
const FISHJAM_URL_BASE = "fishjam.io/api/v1";
|
|
2
|
+
const FISHJAM_CONNECT_PATH = `${FISHJAM_URL_BASE}/connect`;
|
|
3
|
+
export const FISHJAM_HTTP_CONNECT_URL = `https://${FISHJAM_CONNECT_PATH}`;
|
|
4
|
+
export const FISHJAM_WS_CONNECT_URL = `wss://${FISHJAM_CONNECT_PATH}`;
|
|
5
|
+
const FISHJAM_LIVE_URL = `https://${FISHJAM_URL_BASE}/live`;
|
|
6
|
+
export const FISHJAM_WHIP_URL = `${FISHJAM_LIVE_URL}/api/whip`;
|
|
7
|
+
export const FISHJAM_WHEP_URL = `${FISHJAM_LIVE_URL}/api/whep`;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fishjamId.d.ts","sourceRoot":"","sources":["../../src/contexts/fishjamId.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,gBAAgB,wCAAqC,CAAC"}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { GenericMetadata } from "@fishjam-cloud/ts-client";
|
|
2
2
|
export interface JoinRoomConfig<PeerMetadata extends GenericMetadata = GenericMetadata> {
|
|
3
3
|
/**
|
|
4
|
-
* Fishjam
|
|
4
|
+
* Overrides the default url derived from the Fishjam ID passed to FishjamProvider
|
|
5
5
|
*/
|
|
6
|
-
url
|
|
6
|
+
url?: string;
|
|
7
7
|
/**
|
|
8
8
|
* Token received from server (or Room Manager)
|
|
9
9
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useConnection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"useConnection.d.ts","sourceRoot":"","sources":["../../src/hooks/useConnection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAShE,MAAM,WAAW,cAAc,CAAC,YAAY,SAAS,eAAe,GAAG,eAAe;IACpF;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,SAAS,EAAE,MAAM,CAAC;IAClB;;OAEG;IACH,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAgB,aAAa;IAgCzB;;OAEG;eAvBF,YAAY,SAAS,eAAe,uDAIlC,cAAc,CAAC,YAAY,CAAC;IAqB/B;;OAEG;;IAEH;;OAEG;;IAEH;;OAEG;;EAGN"}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { useCallback, useContext } from "react";
|
|
2
|
+
import { FISHJAM_WS_CONNECT_URL } from "../consts";
|
|
2
3
|
import { FishjamClientContext } from "../contexts/fishjamClient";
|
|
4
|
+
import { FishjamIdContext } from "../contexts/fishjamId";
|
|
3
5
|
import { PeerStatusContext } from "../contexts/peerStatus";
|
|
4
6
|
import { useReconnection } from "./internal/useReconnection";
|
|
5
7
|
/**
|
|
@@ -9,12 +11,19 @@ import { useReconnection } from "./internal/useReconnection";
|
|
|
9
11
|
*/
|
|
10
12
|
export function useConnection() {
|
|
11
13
|
const fishjamClientRef = useContext(FishjamClientContext);
|
|
14
|
+
const fishjamId = useContext(FishjamIdContext);
|
|
12
15
|
if (!fishjamClientRef)
|
|
13
16
|
throw Error("useConnection must be used within FishjamProvider");
|
|
14
17
|
const peerStatus = useContext(PeerStatusContext);
|
|
15
18
|
const client = fishjamClientRef.current;
|
|
16
19
|
const reconnectionStatus = useReconnection();
|
|
17
|
-
const joinRoom = useCallback(({ url, peerToken, peerMetadata, }) =>
|
|
20
|
+
const joinRoom = useCallback(({ url, peerToken, peerMetadata, }) => {
|
|
21
|
+
if (!url && !fishjamId) {
|
|
22
|
+
throw Error(`You haven't passed your Fishjam ID to the FishjamProvider. You can get your Fishjam ID at https://fishjam.io/app`);
|
|
23
|
+
}
|
|
24
|
+
const connectUrl = `${FISHJAM_WS_CONNECT_URL}/${fishjamId}`;
|
|
25
|
+
return client.connect({ url: url ?? connectUrl, token: peerToken, peerMetadata: peerMetadata ?? {} });
|
|
26
|
+
}, [client, fishjamId]);
|
|
18
27
|
const leaveRoom = useCallback(() => {
|
|
19
28
|
client.disconnect();
|
|
20
29
|
}, [client]);
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LivestreamError } from "@fishjam-cloud/ts-client";
|
|
2
|
+
/** @category Livestream */
|
|
3
|
+
export type StreamerInputs = {
|
|
4
|
+
/** The video source to publish. e.g. `cameraStream` from {@link useCamera} or `stream` from {@link useScreenShare} */
|
|
5
|
+
video: MediaStream;
|
|
6
|
+
/** The audio source to publish. e.g. `microphoneStream` from {@link useMicrophone} or `stream` from {@link useScreenShare} */
|
|
7
|
+
audio?: MediaStream | null;
|
|
8
|
+
} | {
|
|
9
|
+
video?: null;
|
|
10
|
+
audio: MediaStream;
|
|
11
|
+
};
|
|
12
|
+
/** @category Livestream */
|
|
13
|
+
export type ConnectStreamerConfig = {
|
|
14
|
+
inputs: StreamerInputs;
|
|
15
|
+
/** Streamer token used to authenticate with Fishjam */
|
|
16
|
+
token: string;
|
|
17
|
+
};
|
|
18
|
+
/** @category Livestream */
|
|
19
|
+
export interface UseLivestreamStreamerResult {
|
|
20
|
+
/**
|
|
21
|
+
* Callback used to start publishing the selected audio and video media streams.
|
|
22
|
+
*
|
|
23
|
+
* @remarks
|
|
24
|
+
* Calling {@link connect} multiple times will have the effect of only publishing the **last** specified inputs.
|
|
25
|
+
*/
|
|
26
|
+
connect: (inputs: ConnectStreamerConfig, urlOverride?: string) => Promise<void>;
|
|
27
|
+
/** Callback to stop publishing anything previously published with {@link connect} */
|
|
28
|
+
disconnect: () => void;
|
|
29
|
+
/** Any errors encounterd in {@link connect} will populate this field */
|
|
30
|
+
error: LivestreamError | null;
|
|
31
|
+
/** Utility flag which indicates the current connection status */
|
|
32
|
+
isConnected: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Hook for publishing a livestream, which can be then received with {@link useLivestreamViewer}
|
|
36
|
+
* @category Livestream
|
|
37
|
+
* @group Hooks
|
|
38
|
+
*/
|
|
39
|
+
export declare const useLivestreamStreamer: () => UseLivestreamStreamerResult;
|
|
40
|
+
//# sourceMappingURL=useLivestreamStreamer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLivestreamStreamer.d.ts","sourceRoot":"","sources":["../../src/hooks/useLivestreamStreamer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAmD,MAAM,0BAA0B,CAAC;AAK5G,2BAA2B;AAC3B,MAAM,MAAM,cAAc,GACtB;IACE,sHAAsH;IACtH,KAAK,EAAE,WAAW,CAAC;IACnB,8HAA8H;IAC9H,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;CAC5B,GACD;IACE,KAAK,CAAC,EAAE,IAAI,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;CACpB,CAAC;AAEN,2BAA2B;AAC3B,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,EAAE,cAAc,CAAC;IACvB,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,2BAA2B;AAC3B,MAAM,WAAW,2BAA2B;IAC1C;;;;;OAKG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,WAAW,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChF,qFAAqF;IACrF,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,wEAAwE;IACxE,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B,iEAAiE;IACjE,WAAW,EAAE,OAAO,CAAC;CACtB;AAKD;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,QAAO,2BAyCxC,CAAC"}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { LivestreamError, publishLivestream } from "@fishjam-cloud/ts-client";
|
|
2
|
+
import { useCallback, useRef, useState } from "react";
|
|
3
|
+
import { FISHJAM_WHIP_URL } from "../consts";
|
|
4
|
+
const isLivestreamError = (err) => Object.values(LivestreamError).includes(err);
|
|
5
|
+
/**
|
|
6
|
+
* Hook for publishing a livestream, which can be then received with {@link useLivestreamViewer}
|
|
7
|
+
* @category Livestream
|
|
8
|
+
* @group Hooks
|
|
9
|
+
*/
|
|
10
|
+
export const useLivestreamStreamer = () => {
|
|
11
|
+
const [error, setError] = useState(null);
|
|
12
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
13
|
+
const resultRef = useRef(null);
|
|
14
|
+
const disconnect = useCallback(() => {
|
|
15
|
+
resultRef.current?.stopPublishing();
|
|
16
|
+
resultRef.current = null;
|
|
17
|
+
}, []);
|
|
18
|
+
const onConnectionStateChange = useCallback((pc) => {
|
|
19
|
+
if (isConnected && pc.connectionState !== "connected")
|
|
20
|
+
disconnect();
|
|
21
|
+
setIsConnected(pc.connectionState === "connected");
|
|
22
|
+
}, [isConnected, disconnect]);
|
|
23
|
+
const connect = useCallback(async ({ inputs: { video, audio }, token }, urlOverride) => {
|
|
24
|
+
if (resultRef.current !== null)
|
|
25
|
+
disconnect();
|
|
26
|
+
const videoTrack = video?.getVideoTracks().at(0);
|
|
27
|
+
const audioTrack = audio?.getAudioTracks().at(0);
|
|
28
|
+
const stream = new MediaStream([videoTrack, audioTrack].filter((v) => v != null));
|
|
29
|
+
try {
|
|
30
|
+
const result = await publishLivestream(stream, urlOverride ?? FISHJAM_WHIP_URL, token, {
|
|
31
|
+
onConnectionStateChange,
|
|
32
|
+
});
|
|
33
|
+
resultRef.current = result;
|
|
34
|
+
setError(null);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
if (isLivestreamError(e))
|
|
38
|
+
setError(e);
|
|
39
|
+
else
|
|
40
|
+
console.error(e);
|
|
41
|
+
}
|
|
42
|
+
}, [disconnect, onConnectionStateChange]);
|
|
43
|
+
return { connect, disconnect, error, isConnected };
|
|
44
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { LivestreamError } from "@fishjam-cloud/ts-client";
|
|
2
|
+
export type ConnectViewerConfig = {
|
|
3
|
+
token: string;
|
|
4
|
+
streamId?: never;
|
|
5
|
+
} | {
|
|
6
|
+
streamId: string;
|
|
7
|
+
token?: never;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* @category Livestream
|
|
11
|
+
*/
|
|
12
|
+
export interface UseLivestreamViewerResult {
|
|
13
|
+
/** The received livestream media */
|
|
14
|
+
stream: MediaStream | null;
|
|
15
|
+
/**
|
|
16
|
+
* Callback to start receiving a livestream.
|
|
17
|
+
* If the livestream is private, provide `token`.
|
|
18
|
+
* If the livestream is public, provide `streamId`.
|
|
19
|
+
*/
|
|
20
|
+
connect: (config: ConnectViewerConfig, url?: string) => Promise<void>;
|
|
21
|
+
/** Callback used to disconnect from a stream previously connected to with {@link connect} */
|
|
22
|
+
disconnect: () => void;
|
|
23
|
+
/** Any errors encountered in {@link connect} will be present in this field. */
|
|
24
|
+
error: LivestreamError | null;
|
|
25
|
+
/** Utility flag which indicates the current connection status */
|
|
26
|
+
isConnected: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Hook for receiving a published livestream.
|
|
30
|
+
* @category Livestream
|
|
31
|
+
* @group Hooks
|
|
32
|
+
*/
|
|
33
|
+
export declare const useLivestreamViewer: () => UseLivestreamViewerResult;
|
|
34
|
+
//# sourceMappingURL=useLivestreamViewer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useLivestreamViewer.d.ts","sourceRoot":"","sources":["../../src/hooks/useLivestreamViewer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAmD,MAAM,0BAA0B,CAAC;AAK5G,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AAE5G;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,oCAAoC;IACpC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B;;;;OAIG;IACH,OAAO,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,6FAA6F;IAC7F,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,+EAA+E;IAC/E,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;IAC9B,iEAAiE;IACjE,WAAW,EAAE,OAAO,CAAC;CACtB;AAUD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAO,yBAqCtC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { LivestreamError, receiveLivestream } from "@fishjam-cloud/ts-client";
|
|
2
|
+
import { useCallback, useRef, useState } from "react";
|
|
3
|
+
import { FISHJAM_WHEP_URL } from "../consts";
|
|
4
|
+
const isLivestreamError = (err) => Object.values(LivestreamError).includes(err);
|
|
5
|
+
const urlFromConfig = (config) => {
|
|
6
|
+
if (config.streamId)
|
|
7
|
+
return `${FISHJAM_WHEP_URL}/${config.streamId}`;
|
|
8
|
+
return FISHJAM_WHEP_URL;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Hook for receiving a published livestream.
|
|
12
|
+
* @category Livestream
|
|
13
|
+
* @group Hooks
|
|
14
|
+
*/
|
|
15
|
+
export const useLivestreamViewer = () => {
|
|
16
|
+
const [stream, setStream] = useState(null);
|
|
17
|
+
const [error, setError] = useState(null);
|
|
18
|
+
const resultRef = useRef(null);
|
|
19
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
20
|
+
const disconnect = useCallback(() => {
|
|
21
|
+
setStream(null);
|
|
22
|
+
resultRef.current?.stop();
|
|
23
|
+
resultRef.current = null;
|
|
24
|
+
}, []);
|
|
25
|
+
const onConnectionStateChange = useCallback((pc) => {
|
|
26
|
+
if (isConnected && pc.connectionState !== "connected")
|
|
27
|
+
disconnect();
|
|
28
|
+
setIsConnected(pc.connectionState === "connected");
|
|
29
|
+
}, [isConnected, disconnect]);
|
|
30
|
+
const connect = useCallback(async (config, url) => {
|
|
31
|
+
if (resultRef.current !== null)
|
|
32
|
+
disconnect();
|
|
33
|
+
try {
|
|
34
|
+
const result = await receiveLivestream(url ?? urlFromConfig(config), config.token, { onConnectionStateChange });
|
|
35
|
+
resultRef.current = result;
|
|
36
|
+
setError(null);
|
|
37
|
+
setStream(result.stream);
|
|
38
|
+
}
|
|
39
|
+
catch (e) {
|
|
40
|
+
if (isLivestreamError(e))
|
|
41
|
+
setError(e);
|
|
42
|
+
}
|
|
43
|
+
}, [disconnect, onConnectionStateChange]);
|
|
44
|
+
return { stream, connect, disconnect, error, isConnected };
|
|
45
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type UseSandboxProps = {
|
|
2
|
+
configOverride?: {
|
|
3
|
+
fishjamUrl?: string;
|
|
4
|
+
};
|
|
5
|
+
};
|
|
6
|
+
export type RoomType = "conference" | "livestream" | "audio_only";
|
|
7
|
+
export declare const useSandbox: (props?: UseSandboxProps) => {
|
|
8
|
+
getSandboxPeerToken: (roomName: string, peerName: string, roomType?: RoomType) => Promise<string>;
|
|
9
|
+
getSandboxViewerToken: (roomName: string) => Promise<string>;
|
|
10
|
+
getSandboxLivestream: (roomName: string, isPublic?: boolean) => Promise<{
|
|
11
|
+
streamerToken: string;
|
|
12
|
+
room: {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
};
|
|
16
|
+
}>;
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=useSandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSandbox.d.ts","sourceRoot":"","sources":["../../src/hooks/useSandbox.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,eAAe,GAAG;IAE5B,cAAc,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,YAAY,CAAC;AAElE,eAAO,MAAM,UAAU,GAAI,QAAQ,eAAe;oCAUH,MAAM,YAAY,MAAM,aAAY,QAAQ;sCAmB1C,MAAM;qCAkBP,MAAM,aAAY,OAAO;uBAUxC,MAAM;cAAQ;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,IAAI,EAAE,MAAM,CAAA;SAAE;;CAK1E,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useContext } from "react";
|
|
2
|
+
import { FISHJAM_HTTP_CONNECT_URL } from "../consts";
|
|
3
|
+
import { FishjamIdContext } from "../contexts/fishjamId";
|
|
4
|
+
class FishjamIdMisconfiguredError extends Error {
|
|
5
|
+
constructor() {
|
|
6
|
+
super("You haven't passed the fishjamId to the FishjamProvider.");
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export const useSandbox = (props) => {
|
|
10
|
+
const fishjamId = useContext(FishjamIdContext);
|
|
11
|
+
const overridenFishjamUrl = props?.configOverride?.fishjamUrl;
|
|
12
|
+
const fishjamUrl = `${FISHJAM_HTTP_CONNECT_URL}/${fishjamId}`;
|
|
13
|
+
const isFishjamIdMisconfigured = !fishjamId && !props?.configOverride?.fishjamUrl;
|
|
14
|
+
const roomManagerUrl = `${overridenFishjamUrl ?? fishjamUrl}/room-manager`;
|
|
15
|
+
const getSandboxPeerToken = async (roomName, peerName, roomType = "conference") => {
|
|
16
|
+
if (isFishjamIdMisconfigured)
|
|
17
|
+
throw new FishjamIdMisconfiguredError();
|
|
18
|
+
const url = new URL(roomManagerUrl);
|
|
19
|
+
url.searchParams.set("roomName", roomName);
|
|
20
|
+
url.searchParams.set("peerName", peerName);
|
|
21
|
+
url.searchParams.set("roomType", roomType);
|
|
22
|
+
const res = await fetch(url);
|
|
23
|
+
if (!res.ok) {
|
|
24
|
+
const message = `Failed to retrieve peer token for peer '${peerName}' in ${roomType} room '${roomName}'.`;
|
|
25
|
+
throw new Error(message);
|
|
26
|
+
}
|
|
27
|
+
const data = await res.json();
|
|
28
|
+
return data.peerToken;
|
|
29
|
+
};
|
|
30
|
+
const getSandboxViewerToken = async (roomName) => {
|
|
31
|
+
if (isFishjamIdMisconfigured)
|
|
32
|
+
throw new FishjamIdMisconfiguredError();
|
|
33
|
+
const url = new URL(`${roomManagerUrl}/${roomName}/livestream-viewer-token`);
|
|
34
|
+
const res = await fetch(url);
|
|
35
|
+
if (!res.ok) {
|
|
36
|
+
let message = `Failed to retrieve viewer token for '${roomName}' livestream room.`;
|
|
37
|
+
if (res.status === 404) {
|
|
38
|
+
message = `A livestream room of name '${roomName}' does not exist.`;
|
|
39
|
+
}
|
|
40
|
+
throw new Error(message);
|
|
41
|
+
}
|
|
42
|
+
const data = await res.json();
|
|
43
|
+
return data.token;
|
|
44
|
+
};
|
|
45
|
+
const getSandboxLivestream = async (roomName, isPublic = false) => {
|
|
46
|
+
if (isFishjamIdMisconfigured)
|
|
47
|
+
throw new FishjamIdMisconfiguredError();
|
|
48
|
+
const url = new URL(`${roomManagerUrl}/livestream`);
|
|
49
|
+
url.searchParams.set("roomName", roomName);
|
|
50
|
+
url.searchParams.set("public", isPublic.toString());
|
|
51
|
+
const res = await fetch(url);
|
|
52
|
+
if (!res.ok)
|
|
53
|
+
throw new Error(`Failed to retrieve streamer token for '${roomName}' livestream room.`);
|
|
54
|
+
const data = await res.json();
|
|
55
|
+
return data;
|
|
56
|
+
};
|
|
57
|
+
return { getSandboxPeerToken, getSandboxViewerToken, getSandboxLivestream };
|
|
58
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -5,8 +5,10 @@ export { useMicrophone } from "./hooks/devices/useMicrophone";
|
|
|
5
5
|
export { InitializeDevicesSettings } from "./hooks/internal/devices/useMediaDevices";
|
|
6
6
|
export { type JoinRoomConfig, useConnection } from "./hooks/useConnection";
|
|
7
7
|
export { useCustomSource } from "./hooks/useCustomSource";
|
|
8
|
-
export {
|
|
8
|
+
export { type ConnectStreamerConfig, type StreamerInputs, useLivestreamStreamer, type UseLivestreamStreamerResult, } from "./hooks/useLivestreamStreamer";
|
|
9
|
+
export { type ConnectViewerConfig, useLivestreamViewer, type UseLivestreamViewerResult, } from "./hooks/useLivestreamViewer";
|
|
9
10
|
export { type PeerWithTracks, usePeers } from "./hooks/usePeers";
|
|
11
|
+
export { type RoomType, useSandbox, type UseSandboxProps } from "./hooks/useSandbox";
|
|
10
12
|
export { useScreenShare } from "./hooks/useScreenShare";
|
|
11
13
|
export { useUpdatePeerMetadata } from "./hooks/useUpdatePeerMetadata";
|
|
12
14
|
export { useVAD } from "./hooks/useVAD";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,sCAAsC,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0CAA0C,CAAC;AACrF,OAAO,EAAE,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,qBAAqB,EACrB,KAAK,2BAA2B,GACjC,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,KAAK,mBAAmB,EACxB,mBAAmB,EACnB,KAAK,yBAAyB,GAC/B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EAAE,KAAK,cAAc,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,KAAK,QAAQ,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrF,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,YAAY,EACV,eAAe,EACf,KAAK,EACL,YAAY,EACZ,WAAW,EACX,UAAU,EACV,uBAAuB,EACvB,uBAAuB,EACvB,gBAAgB,EAChB,MAAM,EACN,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EACZ,KAAK,EACL,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,eAAe,EACf,eAAe,EACf,QAAQ,EACR,eAAe,EACf,kBAAkB,EAClB,uBAAuB,EACvB,eAAe,EACf,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,10 @@ export { useInitializeDevices } from "./hooks/devices/useInitializeDevices";
|
|
|
4
4
|
export { useMicrophone } from "./hooks/devices/useMicrophone";
|
|
5
5
|
export { useConnection } from "./hooks/useConnection";
|
|
6
6
|
export { useCustomSource } from "./hooks/useCustomSource";
|
|
7
|
-
export {
|
|
7
|
+
export { useLivestreamStreamer, } from "./hooks/useLivestreamStreamer";
|
|
8
|
+
export { useLivestreamViewer, } from "./hooks/useLivestreamViewer";
|
|
8
9
|
export { usePeers } from "./hooks/usePeers";
|
|
10
|
+
export { useSandbox } from "./hooks/useSandbox";
|
|
9
11
|
export { useScreenShare } from "./hooks/useScreenShare";
|
|
10
12
|
export { useUpdatePeerMetadata } from "./hooks/useUpdatePeerMetadata";
|
|
11
13
|
export { useVAD } from "./hooks/useVAD";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fishjam-cloud/react-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"description": "React client library for Fishjam",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Fishjam Team",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"vitest": "^3.1.1"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
-
"@fishjam-cloud/ts-client": "0.
|
|
63
|
+
"@fishjam-cloud/ts-client": "0.20.0",
|
|
64
64
|
"events": "3.3.0",
|
|
65
65
|
"lodash.isequal": "4.5.0"
|
|
66
66
|
},
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { LivestreamError } from "@fishjam-cloud/ts-client";
|
|
2
|
-
export interface UseLivestreamResult {
|
|
3
|
-
stream: MediaStream | null;
|
|
4
|
-
connect: (url: string, token: string) => Promise<void>;
|
|
5
|
-
disconnect: () => void;
|
|
6
|
-
error: LivestreamError | null;
|
|
7
|
-
}
|
|
8
|
-
export declare const useLivestream: () => UseLivestreamResult;
|
|
9
|
-
//# sourceMappingURL=useLivestream.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"useLivestream.d.ts","sourceRoot":"","sources":["../../src/hooks/useLivestream.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAmD,MAAM,0BAA0B,CAAC;AAG5G,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvD,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,KAAK,EAAE,eAAe,GAAG,IAAI,CAAC;CAC/B;AAKD,eAAO,MAAM,aAAa,QAAO,mBAyBhC,CAAC"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { LivestreamError, receiveLivestream } from "@fishjam-cloud/ts-client";
|
|
2
|
-
import { useCallback, useRef, useState } from "react";
|
|
3
|
-
const isLivestreamError = (err) => Object.values(LivestreamError).includes(err);
|
|
4
|
-
export const useLivestream = () => {
|
|
5
|
-
const [stream, setStream] = useState(null);
|
|
6
|
-
const [error, setError] = useState(null);
|
|
7
|
-
const resultRef = useRef(null);
|
|
8
|
-
const connect = useCallback(async (url, token) => {
|
|
9
|
-
try {
|
|
10
|
-
const result = await receiveLivestream(url, token);
|
|
11
|
-
resultRef.current = result;
|
|
12
|
-
setError(null);
|
|
13
|
-
setStream(result.stream);
|
|
14
|
-
}
|
|
15
|
-
catch (e) {
|
|
16
|
-
if (isLivestreamError(e)) {
|
|
17
|
-
setError(e);
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}, []);
|
|
21
|
-
const disconnect = useCallback(() => {
|
|
22
|
-
setStream(null);
|
|
23
|
-
resultRef.current?.stop();
|
|
24
|
-
resultRef.current = null;
|
|
25
|
-
}, []);
|
|
26
|
-
return { stream, connect, disconnect, error };
|
|
27
|
-
};
|