@fishjam-cloud/react-client 0.5.2 → 0.6.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.
Files changed (58) hide show
  1. package/dist/Client.d.ts +68 -69
  2. package/dist/Client.d.ts.map +1 -1
  3. package/dist/Client.js +9 -9
  4. package/dist/DeviceManager.d.ts +2 -1
  5. package/dist/DeviceManager.d.ts.map +1 -1
  6. package/dist/DeviceManager.js +3 -0
  7. package/dist/fishjamProvider.d.ts +12 -0
  8. package/dist/fishjamProvider.d.ts.map +1 -0
  9. package/dist/fishjamProvider.js +30 -0
  10. package/dist/hooks/clientState.d.ts +4 -0
  11. package/dist/hooks/clientState.d.ts.map +1 -0
  12. package/dist/hooks/clientState.js +81 -0
  13. package/dist/hooks/connection.d.ts +6 -0
  14. package/dist/hooks/connection.d.ts.map +1 -0
  15. package/dist/hooks/connection.js +28 -0
  16. package/dist/hooks/devices.d.ts +4 -0
  17. package/dist/hooks/devices.d.ts.map +1 -0
  18. package/dist/hooks/devices.js +9 -0
  19. package/dist/hooks/fishjamContext.d.ts +4 -0
  20. package/dist/hooks/fishjamContext.d.ts.map +1 -0
  21. package/dist/hooks/fishjamContext.js +8 -0
  22. package/dist/hooks/participants.d.ts +6 -0
  23. package/dist/hooks/participants.d.ts.map +1 -0
  24. package/dist/hooks/participants.js +13 -0
  25. package/dist/hooks/public.d.ts +7 -0
  26. package/dist/hooks/public.d.ts.map +1 -0
  27. package/dist/hooks/public.js +6 -0
  28. package/dist/hooks/screenShare.d.ts +3 -0
  29. package/dist/hooks/screenShare.d.ts.map +1 -0
  30. package/dist/{screenShareTrackManager.js → hooks/screenShare.js} +8 -6
  31. package/dist/hooks/setupMedia.d.ts +3 -0
  32. package/dist/hooks/setupMedia.d.ts.map +1 -0
  33. package/dist/hooks/setupMedia.js +200 -0
  34. package/dist/hooks/state.d.ts +6 -0
  35. package/dist/hooks/state.d.ts.map +1 -0
  36. package/dist/hooks/state.js +15 -0
  37. package/dist/index.d.ts +5 -3
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/index.js +2 -1
  40. package/dist/state.types.d.ts +18 -18
  41. package/dist/state.types.d.ts.map +1 -1
  42. package/dist/trackManager.d.ts +3 -3
  43. package/dist/trackManager.d.ts.map +1 -1
  44. package/dist/trackManager.js +30 -13
  45. package/dist/types.d.ts +48 -45
  46. package/dist/types.d.ts.map +1 -1
  47. package/dist/utils/track.d.ts +2 -1
  48. package/dist/utils/track.d.ts.map +1 -1
  49. package/package.json +4 -5
  50. package/readme.md +1 -15
  51. package/dist/create.d.ts +0 -10
  52. package/dist/create.d.ts.map +0 -1
  53. package/dist/create.js +0 -201
  54. package/dist/screenShareTrackManager.d.ts +0 -4
  55. package/dist/screenShareTrackManager.d.ts.map +0 -1
  56. package/dist/useSetupMedia.d.ts +0 -3
  57. package/dist/useSetupMedia.d.ts.map +0 -1
  58. package/dist/useSetupMedia.js +0 -206
@@ -0,0 +1,6 @@
1
+ import type { PeerStateWithTracks } from "../types";
2
+ export declare function useParticipants(): {
3
+ localParticipant: PeerStateWithTracks | null;
4
+ participants: PeerStateWithTracks[];
5
+ };
6
+ //# sourceMappingURL=participants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"participants.d.ts","sourceRoot":"","sources":["../../src/hooks/participants.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAWpD,wBAAgB,eAAe;;;EAQ9B"}
@@ -0,0 +1,13 @@
1
+ import { useFishjamContext } from "./fishjamContext";
2
+ function getPeerWithDistinguishedTracks(peerState) {
3
+ const localTracks = Object.values(peerState.tracks ?? {});
4
+ const videoTracks = localTracks.filter(({ track }) => track?.kind === "video");
5
+ const audioTracks = localTracks.filter(({ track }) => track?.kind === "audio");
6
+ return { ...peerState, videoTracks, audioTracks };
7
+ }
8
+ export function useParticipants() {
9
+ const { state } = useFishjamContext();
10
+ const localParticipant = state.local ? getPeerWithDistinguishedTracks(state.local) : null;
11
+ const participants = Object.values(state.remote).map(getPeerWithDistinguishedTracks);
12
+ return { localParticipant, participants };
13
+ }
@@ -0,0 +1,7 @@
1
+ export { useConnect, useDisconnect, useReconnection } from "./connection";
2
+ export { useCamera, useMicrophone } from "./devices";
3
+ export { useParticipants } from "./participants";
4
+ export { useScreenShare } from "./screenShare";
5
+ export { useSelector, useStatus, useTracks, useClient } from "./state";
6
+ export { useSetupMedia } from "./setupMedia";
7
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/hooks/public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { useConnect, useDisconnect, useReconnection } from "./connection";
2
+ export { useCamera, useMicrophone } from "./devices";
3
+ export { useParticipants } from "./participants";
4
+ export { useScreenShare } from "./screenShare";
5
+ export { useSelector, useStatus, useTracks, useClient } from "./state";
6
+ export { useSetupMedia } from "./setupMedia";
@@ -0,0 +1,3 @@
1
+ import type { ScreenshareApi } from "../types";
2
+ export declare const useScreenShare: () => ScreenshareApi;
3
+ //# sourceMappingURL=screenShare.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenShare.d.ts","sourceRoot":"","sources":["../../src/hooks/screenShare.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAoB,MAAM,UAAU,CAAC;AAUjE,eAAO,MAAM,cAAc,QAAO,cAwGjC,CAAC"}
@@ -1,22 +1,24 @@
1
1
  import { useCallback, useEffect } from "react";
2
- import { getRemoteOrLocalTrack } from "./utils/track";
2
+ import { getRemoteOrLocalTrack } from "../utils/track";
3
+ import { useFishjamContext } from "./fishjamContext";
3
4
  const getTracks = (stream) => {
4
5
  const video = stream.getVideoTracks()[0];
5
6
  const audio = stream.getAudioTracks()[0] ?? null;
6
7
  return [video, audio];
7
8
  };
8
- export const useScreenShare = (
9
- // these arguments will be removed after we get rid of create() fn, we will just use the context
10
- [state, setState], tsClient) => {
9
+ export const useScreenShare = () => {
10
+ const ctx = useFishjamContext();
11
+ const [state, setState] = ctx.screenshareState;
12
+ const tsClient = ctx.state.client.getTsClient();
11
13
  const startStreaming = async (props) => {
12
14
  const stream = await navigator.mediaDevices.getDisplayMedia({
13
15
  video: props?.videoConstraints ?? true,
14
16
  audio: props?.audioConstraints ?? true,
15
17
  });
16
18
  const [video, audio] = getTracks(stream);
17
- const addTrackPromises = [tsClient.addTrack(video, props?.metadata)];
19
+ const addTrackPromises = [tsClient.addTrack(video)];
18
20
  if (audio)
19
- addTrackPromises.push(tsClient.addTrack(audio, props?.metadata));
21
+ addTrackPromises.push(tsClient.addTrack(audio));
20
22
  const [videoId, audioId] = await Promise.all(addTrackPromises);
21
23
  setState({ stream, trackIds: { videoId, audioId } });
22
24
  };
@@ -0,0 +1,3 @@
1
+ import type { UseSetupMediaConfig, UseSetupMediaResult } from "../types";
2
+ export declare const useSetupMedia: (config: UseSetupMediaConfig) => UseSetupMediaResult;
3
+ //# sourceMappingURL=setupMedia.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setupMedia.d.ts","sourceRoot":"","sources":["../../src/hooks/setupMedia.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAYzE,eAAO,MAAM,aAAa,WAAY,mBAAmB,KAAG,mBA6O3D,CAAC"}
@@ -0,0 +1,200 @@
1
+ import { useEffect, useMemo, useRef } from "react";
2
+ import { useFishjamContext } from "./fishjamContext";
3
+ const isBroadcastedTrackChanged = (client, pending) => client.status === "joined" && !pending && !client.isReconnecting();
4
+ const isBroadcastedTrackStopped = (status, stream) => status === "joined" && stream;
5
+ export const useSetupMedia = (config) => {
6
+ const { state, videoTrackManager, audioTrackManager } = useFishjamContext();
7
+ const configRef = useRef(config);
8
+ useEffect(() => {
9
+ configRef.current = config;
10
+ state.client.setDeviceManagerConfig({
11
+ storage: config.storage,
12
+ });
13
+ }, [config, state.client]);
14
+ useEffect(() => {
15
+ if (!configRef.current.startOnMount)
16
+ return;
17
+ state.client.initializeDevices({
18
+ audioTrackConstraints: configRef?.current.microphone.trackConstraints,
19
+ videoTrackConstraints: configRef?.current.camera.trackConstraints,
20
+ });
21
+ // eslint-disable-next-line
22
+ }, []);
23
+ useEffect(() => {
24
+ let pending = false;
25
+ const broadcastOnCameraStart = async (client) => {
26
+ const config = configRef.current.camera;
27
+ const onDeviceChange = config.onDeviceChange ?? "replace";
28
+ const stream = videoTrackManager.getCurrentTrack()?.stream;
29
+ if (isBroadcastedTrackChanged(client, pending)) {
30
+ if (!stream && config.broadcastOnDeviceStart) {
31
+ pending = true;
32
+ await videoTrackManager
33
+ .startStreaming(config.defaultSimulcastConfig, config.defaultMaxBandwidth)
34
+ .finally(() => {
35
+ pending = false;
36
+ });
37
+ }
38
+ else if (stream && onDeviceChange === "replace") {
39
+ pending = true;
40
+ await videoTrackManager.refreshStreamedTrack().finally(() => {
41
+ pending = false;
42
+ });
43
+ }
44
+ else if (stream && onDeviceChange === "remove") {
45
+ pending = true;
46
+ await videoTrackManager.stopStreaming().finally(() => {
47
+ pending = false;
48
+ });
49
+ }
50
+ }
51
+ };
52
+ const managerInitialized = async (event, client) => {
53
+ if (event.video?.media?.stream) {
54
+ await broadcastOnCameraStart(client);
55
+ }
56
+ };
57
+ const devicesReady = async (event, client) => {
58
+ if (event.trackType === "video" && event.restarted && event?.media?.stream) {
59
+ await broadcastOnCameraStart(client);
60
+ }
61
+ };
62
+ const deviceReady = async (event, client) => {
63
+ if (event.trackType === "video") {
64
+ await broadcastOnCameraStart(client);
65
+ }
66
+ };
67
+ state.client.on("managerInitialized", managerInitialized);
68
+ state.client.on("devicesReady", devicesReady);
69
+ state.client.on("deviceReady", deviceReady);
70
+ return () => {
71
+ state.client.removeListener("managerInitialized", managerInitialized);
72
+ state.client.removeListener("devicesReady", devicesReady);
73
+ state.client.removeListener("deviceReady", deviceReady);
74
+ };
75
+ }, [state.client, videoTrackManager]);
76
+ useEffect(() => {
77
+ const removeOnCameraStopped = async (event, client) => {
78
+ const stream = videoTrackManager.getCurrentTrack()?.stream;
79
+ const onDeviceStop = configRef.current.camera.onDeviceStop ?? "mute";
80
+ if (event.mediaDeviceType === "userMedia" &&
81
+ event.trackType === "video" &&
82
+ isBroadcastedTrackStopped(client.status, stream)) {
83
+ if (onDeviceStop === "mute") {
84
+ await videoTrackManager.pauseStreaming();
85
+ }
86
+ else {
87
+ await videoTrackManager.stopStreaming();
88
+ }
89
+ }
90
+ };
91
+ state.client.on("deviceStopped", removeOnCameraStopped);
92
+ return () => {
93
+ state.client.removeListener("deviceStopped", removeOnCameraStopped);
94
+ };
95
+ }, [state.client, videoTrackManager]);
96
+ useEffect(() => {
97
+ const broadcastCameraOnConnect = async (_, client) => {
98
+ const camera = client.devices.camera;
99
+ const stream = camera.stream;
100
+ const config = configRef.current.camera;
101
+ if (stream && config.broadcastOnConnect) {
102
+ await videoTrackManager.startStreaming(config.defaultSimulcastConfig, config.defaultMaxBandwidth);
103
+ }
104
+ };
105
+ state.client.on("joined", broadcastCameraOnConnect);
106
+ return () => {
107
+ state.client.removeListener("joined", broadcastCameraOnConnect);
108
+ };
109
+ }, [state.client, videoTrackManager]);
110
+ useEffect(() => {
111
+ let pending = false;
112
+ const broadcastOnMicrophoneStart = async (client) => {
113
+ const stream = audioTrackManager.getCurrentTrack()?.stream;
114
+ const config = configRef.current.microphone;
115
+ const onDeviceChange = config.onDeviceChange ?? "replace";
116
+ if (isBroadcastedTrackChanged(client, pending)) {
117
+ if (!stream && config.broadcastOnDeviceStart) {
118
+ pending = true;
119
+ await audioTrackManager.startStreaming(undefined, config.defaultMaxBandwidth).finally(() => {
120
+ pending = false;
121
+ });
122
+ }
123
+ else if (stream && onDeviceChange === "replace") {
124
+ pending = true;
125
+ await audioTrackManager.refreshStreamedTrack().finally(() => {
126
+ pending = false;
127
+ });
128
+ }
129
+ else if (stream && onDeviceChange === "remove") {
130
+ pending = true;
131
+ await audioTrackManager.stopStreaming().finally(() => {
132
+ pending = false;
133
+ });
134
+ }
135
+ }
136
+ };
137
+ const managerInitialized = async (event, client) => {
138
+ if (event.audio?.media?.stream) {
139
+ await broadcastOnMicrophoneStart(client);
140
+ }
141
+ };
142
+ const devicesReady = async (event, client) => {
143
+ if (event.trackType === "audio" && event.restarted && event?.media?.stream) {
144
+ await broadcastOnMicrophoneStart(client);
145
+ }
146
+ };
147
+ const deviceReady = async (event, client) => {
148
+ if (event.trackType === "audio") {
149
+ await broadcastOnMicrophoneStart(client);
150
+ }
151
+ };
152
+ state.client.on("managerInitialized", managerInitialized);
153
+ state.client.on("deviceReady", deviceReady);
154
+ state.client.on("devicesReady", devicesReady);
155
+ return () => {
156
+ state.client.removeListener("managerInitialized", managerInitialized);
157
+ state.client.removeListener("deviceReady", deviceReady);
158
+ state.client.removeListener("devicesReady", devicesReady);
159
+ };
160
+ }, [state.client, audioTrackManager]);
161
+ useEffect(() => {
162
+ const onMicrophoneStopped = async (event, client) => {
163
+ const stream = audioTrackManager.getCurrentTrack()?.stream;
164
+ const onDeviceStop = configRef.current.microphone.onDeviceStop ?? "mute";
165
+ const isRightDeviceType = event.mediaDeviceType === "userMedia";
166
+ const isRightTrackType = event.trackType === "audio";
167
+ if (isRightDeviceType && isRightTrackType && isBroadcastedTrackStopped(client.status, stream)) {
168
+ if (onDeviceStop === "mute") {
169
+ await audioTrackManager.pauseStreaming();
170
+ }
171
+ else {
172
+ await audioTrackManager.stopStreaming();
173
+ }
174
+ }
175
+ };
176
+ state.client.on("deviceStopped", onMicrophoneStopped);
177
+ return () => {
178
+ state.client.removeListener("deviceStopped", onMicrophoneStopped);
179
+ };
180
+ }, [state.client, audioTrackManager]);
181
+ useEffect(() => {
182
+ const broadcastMicrophoneOnConnect = async (_, client) => {
183
+ const config = configRef.current.microphone;
184
+ const microphone = client.devices.microphone;
185
+ if (microphone.stream && config.broadcastOnConnect) {
186
+ await audioTrackManager.startStreaming(undefined, config.defaultMaxBandwidth);
187
+ }
188
+ };
189
+ state.client.on("joined", broadcastMicrophoneOnConnect);
190
+ return () => {
191
+ state.client.removeListener("joined", broadcastMicrophoneOnConnect);
192
+ };
193
+ }, [state.client, audioTrackManager]);
194
+ return useMemo(() => ({
195
+ init: () => state.client.initializeDevices({
196
+ audioTrackConstraints: configRef.current?.microphone?.trackConstraints,
197
+ videoTrackConstraints: configRef.current?.camera?.trackConstraints,
198
+ }),
199
+ }), [state.client]);
200
+ };
@@ -0,0 +1,6 @@
1
+ import type { Selector } from "../state.types";
2
+ export declare function useSelector<Result>(selector: Selector<Result>): Result;
3
+ export declare function useStatus(): import("../state.types").PeerStatus;
4
+ export declare function useTracks(): Record<string, import("../state.types").TrackWithOrigin>;
5
+ export declare function useClient(): import("..").Client;
6
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/hooks/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE/C,wBAAgB,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,MAAM,CAItE;AAED,wBAAgB,SAAS,wCAExB;AAED,wBAAgB,SAAS,6DAExB;AAED,wBAAgB,SAAS,wBAExB"}
@@ -0,0 +1,15 @@
1
+ import { useMemo } from "react";
2
+ import { useFishjamContext } from "./fishjamContext";
3
+ export function useSelector(selector) {
4
+ const { state } = useFishjamContext();
5
+ return useMemo(() => selector(state), [selector, state]);
6
+ }
7
+ export function useStatus() {
8
+ return useSelector((s) => s.status);
9
+ }
10
+ export function useTracks() {
11
+ return useSelector((s) => s.tracks);
12
+ }
13
+ export function useClient() {
14
+ return useSelector((s) => s.client);
15
+ }
package/dist/index.d.ts CHANGED
@@ -1,9 +1,11 @@
1
- export { create } from "./create";
1
+ export * from "./hooks/public";
2
+ export * from "./fishjamProvider";
2
3
  export { Client } from "./Client";
3
4
  export type { ClientEvents } from "./Client";
4
5
  export type { PeerState, Track, PeerId, TrackId, TrackWithOrigin, Origin, PeerStatus, Selector, State, SetStore, } from "./state.types";
5
- export type { DeviceManagerConfig, StorageConfig, Devices, UserMediaAPI, UseSetupMediaResult, UseSetupMediaConfig, CreateFishjamClient, ScreenshareApi, UseConnect, TrackManager, TrackMiddleware, } from "./types";
6
+ export type { DeviceManagerConfig, Participiants, StorageConfig, Devices, UserMediaAPI, UseSetupMediaResult, UseSetupMediaConfig, CreateFishjamClient, ScreenshareApi, UseConnect, ConnectConfig, TrackManager, TrackMiddleware, TrackMetadata, // only for compatibility reasons, will be removed in: FCE-415
7
+ PeerMetadata, } from "./types";
6
8
  export { AUDIO_TRACK_CONSTRAINTS, VIDEO_TRACK_CONSTRAINTS, SCREEN_SHARING_MEDIA_CONSTRAINTS } from "./constraints";
7
- export type { Peer, MessageEvents, CreateConfig, TrackBandwidthLimit, SimulcastBandwidthLimit, BandwidthLimit, WebRTCEndpointEvents, TrackContextEvents, Endpoint, SimulcastConfig, TrackContext, VadStatus, EncodingReason, MetadataParser, ConnectConfig, AuthErrorReason, Encoding, } from "@fishjam-cloud/ts-client";
9
+ export type { Peer, MessageEvents, CreateConfig, TrackBandwidthLimit, SimulcastBandwidthLimit, BandwidthLimit, WebRTCEndpointEvents, TrackContextEvents, Endpoint, SimulcastConfig, TrackContext, VadStatus, EncodingReason, MetadataParser, AuthErrorReason, Encoding, } from "@fishjam-cloud/ts-client";
8
10
  export { FishjamClient } from "@fishjam-cloud/ts-client";
9
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,YAAY,EACV,SAAS,EACT,KAAK,EACL,MAAM,EACN,OAAO,EACP,eAAe,EACf,MAAM,EACN,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,GACT,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,YAAY,EACZ,eAAe,GAChB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAEnH,YAAY,EACV,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,SAAS,EACT,cAAc,EACd,cAAc,EACd,aAAa,EACb,eAAe,EACf,QAAQ,GACT,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAElC,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,YAAY,EACV,SAAS,EACT,KAAK,EACL,MAAM,EACN,OAAO,EACP,eAAe,EACf,MAAM,EACN,UAAU,EACV,QAAQ,EACR,KAAK,EACL,QAAQ,GACT,MAAM,eAAe,CAAC;AAEvB,YAAY,EACV,mBAAmB,EACnB,aAAa,EACb,aAAa,EACb,OAAO,EACP,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,cAAc,EACd,UAAU,EACV,aAAa,EACb,YAAY,EACZ,eAAe,EACf,aAAa,EAAE,8DAA8D;AAC7E,YAAY,GACb,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,gCAAgC,EAAE,MAAM,eAAe,CAAC;AAEnH,YAAY,EACV,IAAI,EACJ,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,SAAS,EACT,cAAc,EACd,cAAc,EACd,eAAe,EACf,QAAQ,GACT,MAAM,0BAA0B,CAAC;AAElC,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
- export { create } from "./create";
1
+ export * from "./hooks/public";
2
+ export * from "./fishjamProvider";
2
3
  export { Client } from "./Client";
3
4
  export { AUDIO_TRACK_CONSTRAINTS, VIDEO_TRACK_CONSTRAINTS, SCREEN_SHARING_MEDIA_CONSTRAINTS } from "./constraints";
4
5
  export { FishjamClient } from "@fishjam-cloud/ts-client";
@@ -1,36 +1,36 @@
1
1
  import type { Encoding, VadStatus, SimulcastConfig, ReconnectionStatus } from "@fishjam-cloud/ts-client";
2
- import type { MediaState } from "./types";
2
+ import type { MediaState, PeerMetadata, TrackMetadata } from "./types";
3
3
  import type { Devices } from "./types";
4
4
  import type { Client } from "./Client";
5
5
  export type TrackId = string;
6
6
  export type PeerId = string;
7
- export type Track<TrackMetadata> = {
7
+ export type Track = {
8
8
  stream: MediaStream | null;
9
9
  encoding: Encoding | null;
10
10
  trackId: TrackId;
11
11
  metadata?: TrackMetadata;
12
- rawMetadata: any;
12
+ rawMetadata: Record<string, unknown>;
13
13
  metadataParsingError?: any;
14
14
  simulcastConfig: SimulcastConfig | null;
15
15
  vadStatus: VadStatus;
16
16
  track: MediaStreamTrack | null;
17
17
  };
18
- export interface Origin<OriginMetadata> {
18
+ export interface Origin {
19
19
  id: string;
20
20
  type: string;
21
- metadata?: OriginMetadata;
22
- rawMetadata: any;
21
+ metadata?: PeerMetadata;
22
+ rawMetadata: Record<string, unknown>;
23
23
  metadataParsingError?: any;
24
24
  }
25
- export type TrackWithOrigin<PeerMetadata, TrackMetadata> = Track<TrackMetadata> & {
26
- origin: Origin<PeerMetadata>;
25
+ export type TrackWithOrigin = Track & {
26
+ origin: Origin;
27
27
  };
28
- export type PeerState<PeerMetadata, TrackMetadata> = {
28
+ export type PeerState = {
29
29
  id: PeerId;
30
30
  metadata?: PeerMetadata;
31
- rawMetadata: any;
31
+ rawMetadata: Record<string, unknown>;
32
32
  metadataParsingError?: any;
33
- tracks: Record<TrackId, Track<TrackMetadata>>;
33
+ tracks: Record<TrackId, Track>;
34
34
  };
35
35
  export type PeerStatus = "connecting" | "connected" | "authenticated" | "joined" | "error" | "closed" | null;
36
36
  export type UseReconnection = {
@@ -39,17 +39,17 @@ export type UseReconnection = {
39
39
  isError: boolean;
40
40
  isIdle: boolean;
41
41
  };
42
- export type State<PeerMetadata, TrackMetadata> = {
43
- local: PeerState<PeerMetadata, TrackMetadata> | null;
44
- remote: Record<PeerId, PeerState<PeerMetadata, TrackMetadata>>;
45
- tracks: Record<TrackId, TrackWithOrigin<PeerMetadata, TrackMetadata>>;
42
+ export type State = {
43
+ local: PeerState | null;
44
+ remote: Record<PeerId, PeerState>;
45
+ tracks: Record<TrackId, TrackWithOrigin>;
46
46
  bandwidthEstimation: bigint;
47
47
  status: PeerStatus;
48
48
  media: MediaState | null;
49
49
  devices: Devices;
50
- client: Client<PeerMetadata, TrackMetadata>;
50
+ client: Client;
51
51
  reconnectionStatus: ReconnectionStatus;
52
52
  };
53
- export type SetStore<PeerMetadata, TrackMetadata> = (setter: (prevState: State<PeerMetadata, TrackMetadata>) => State<PeerMetadata, TrackMetadata>) => void;
54
- export type Selector<PeerMetadata, TrackMetadata, Result> = (snapshot: State<PeerMetadata, TrackMetadata>) => Result;
53
+ export type SetStore = (setter: (prevState: State) => State) => void;
54
+ export type Selector<Result> = (snapshot: State) => Result;
55
55
  //# sourceMappingURL=state.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.types.d.ts","sourceRoot":"","sources":["../src/state.types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.types.d.ts","sourceRoot":"","sources":["../src/state.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACzG,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC;AAC7B,MAAM,MAAM,MAAM,GAAG,MAAM,CAAC;AAE5B,MAAM,MAAM,KAAK,GAAG;IAClB,MAAM,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,GAAG,CAAC;IAC3B,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,SAAS,EAAE,SAAS,CAAC;IACrB,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAChC,CAAC;AAEF,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,GAAG,CAAC;CAC5B;AAED,MAAM,MAAM,eAAe,GAAG,KAAK,GAAG;IACpC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,CAAC,EAAE,YAAY,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,oBAAoB,CAAC,EAAE,GAAG,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;CAChC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,WAAW,GAAG,eAAe,GAAG,QAAQ,GAAG,OAAO,GAAG,QAAQ,GAAG,IAAI,CAAC;AAE7G,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,cAAc,EAAE,OAAO,CAAC;IACxB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,KAAK,GAAG;IAClB,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAClC,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;IACzC,mBAAmB,EAAE,MAAM,CAAC;IAC5B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,kBAAkB,EAAE,kBAAkB,CAAC;CACxC,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,CAAC,MAAM,EAAE,CAAC,SAAS,EAAE,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;AAErE,MAAM,MAAM,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,EAAE,KAAK,KAAK,MAAM,CAAC"}
@@ -1,9 +1,9 @@
1
1
  import type { FishjamClient } from "@fishjam-cloud/ts-client";
2
- import type { MediaManager, TrackManager } from "./types";
3
- interface TrackManagerConfig<PeerMetadata, TrackMetadata> {
2
+ import type { MediaManager, PeerMetadata, TrackManager, TrackMetadata } from "./types";
3
+ interface TrackManagerConfig {
4
4
  mediaManager: MediaManager;
5
5
  tsClient: FishjamClient<PeerMetadata, TrackMetadata>;
6
6
  }
7
- export declare const useTrackManager: <PeerMetadata, TrackMetadata>({ mediaManager, tsClient, }: TrackManagerConfig<PeerMetadata, TrackMetadata>) => TrackManager<TrackMetadata>;
7
+ export declare const useTrackManager: ({ mediaManager, tsClient }: TrackManagerConfig) => TrackManager;
8
8
  export {};
9
9
  //# sourceMappingURL=trackManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"trackManager.d.ts","sourceRoot":"","sources":["../src/trackManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAwC,MAAM,0BAA0B,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAmB,MAAM,SAAS,CAAC;AAK3E,UAAU,kBAAkB,CAAC,YAAY,EAAE,aAAa;IACtD,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;CACtD;AAED,eAAO,MAAM,eAAe,GAAI,YAAY,EAAE,aAAa,+BAGxD,kBAAkB,CAAC,YAAY,EAAE,aAAa,CAAC,KAAG,YAAY,CAAC,aAAa,CA8H9E,CAAC"}
1
+ {"version":3,"file":"trackManager.d.ts","sourceRoot":"","sources":["../src/trackManager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAwC,MAAM,0BAA0B,CAAC;AACpG,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,aAAa,EAAmB,MAAM,SAAS,CAAC;AAKxG,UAAU,kBAAkB;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;CACtD;AAOD,eAAO,MAAM,eAAe,+BAAgC,kBAAkB,KAAG,YA6IhF,CAAC"}
@@ -1,8 +1,15 @@
1
1
  import { getRemoteOrLocalTrack } from "./utils/track";
2
2
  import { useEffect, useState } from "react";
3
- export const useTrackManager = ({ mediaManager, tsClient, }) => {
3
+ const TRACK_TYPE_TO_DEVICE = {
4
+ video: "camera",
5
+ audio: "microphone",
6
+ };
7
+ export const useTrackManager = ({ mediaManager, tsClient }) => {
4
8
  const [currentTrackId, setCurrentTrackId] = useState(null);
9
+ const [paused, setPaused] = useState(false);
5
10
  const [currentTrackMiddleware, setCurrentTrackMiddleware] = useState(null);
11
+ const type = TRACK_TYPE_TO_DEVICE[mediaManager.getDeviceType()];
12
+ const metadata = { type, paused };
6
13
  useEffect(() => {
7
14
  const disconnectedHandler = () => {
8
15
  setCurrentTrackId(null);
@@ -32,13 +39,13 @@ export const useTrackManager = ({ mediaManager, tsClient, }) => {
32
39
  function getCurrentTrack() {
33
40
  return getRemoteOrLocalTrack(tsClient, currentTrackId);
34
41
  }
35
- async function initialize(deviceId) {
36
- mediaManager?.start(deviceId ?? true);
42
+ function initialize(deviceId) {
43
+ return mediaManager?.start(deviceId ?? true);
37
44
  }
38
- async function stop() {
39
- mediaManager?.stop();
45
+ function stop() {
46
+ return mediaManager?.stop();
40
47
  }
41
- async function startStreaming(trackMetadata, simulcastConfig, maxBandwidth) {
48
+ async function startStreaming(simulcastConfig, maxBandwidth) {
42
49
  if (currentTrackId)
43
50
  throw Error("Track already added");
44
51
  const media = mediaManager.getMedia();
@@ -49,11 +56,13 @@ export const useTrackManager = ({ mediaManager, tsClient, }) => {
49
56
  return track.trackId;
50
57
  // see `getRemoteOrLocalTrackContext()` explanation
51
58
  setCurrentTrackId(media.track.id);
59
+ const trackMetadata = { ...metadata, paused: false };
52
60
  const remoteTrackId = await tsClient.addTrack(media.track, trackMetadata, simulcastConfig, maxBandwidth);
53
61
  setCurrentTrackId(remoteTrackId);
62
+ setPaused(false);
54
63
  return remoteTrackId;
55
64
  }
56
- async function refreshStreamedTrack() {
65
+ function refreshStreamedTrack() {
57
66
  const prevTrack = getPreviousTrack();
58
67
  const newTrack = mediaManager.getTracks()[0];
59
68
  if (!newTrack)
@@ -63,24 +72,31 @@ export const useTrackManager = ({ mediaManager, tsClient, }) => {
63
72
  function stopStreaming() {
64
73
  const prevTrack = getPreviousTrack();
65
74
  setCurrentTrackId(null);
75
+ setPaused(true);
66
76
  return tsClient.removeTrack(prevTrack.trackId);
67
77
  }
68
- function pauseStreaming() {
78
+ async function pauseStreaming() {
69
79
  const prevTrack = getPreviousTrack();
70
- return tsClient.replaceTrack(prevTrack.trackId, null);
80
+ setPaused(true);
81
+ await tsClient.replaceTrack(prevTrack.trackId, null);
82
+ const trackMetadata = { ...metadata, paused: true };
83
+ return tsClient.updateTrackMetadata(prevTrack.trackId, trackMetadata);
71
84
  }
72
- function resumeStreaming() {
85
+ async function resumeStreaming() {
73
86
  const prevTrack = getPreviousTrack();
74
87
  const media = mediaManager.getMedia();
75
88
  if (!media)
76
89
  throw Error("Device is unavailable");
77
- return tsClient.replaceTrack(prevTrack.trackId, media.track);
90
+ setPaused(false);
91
+ await tsClient.replaceTrack(prevTrack.trackId, media.track);
92
+ const trackMetadata = { ...metadata, paused: false };
93
+ return tsClient.updateTrackMetadata(prevTrack.trackId, trackMetadata);
78
94
  }
79
95
  function disableTrack() {
80
- return mediaManager.disable();
96
+ mediaManager.disable();
81
97
  }
82
98
  function enableTrack() {
83
- return mediaManager.enable();
99
+ mediaManager.enable();
84
100
  }
85
101
  return {
86
102
  getCurrentTrack,
@@ -95,5 +111,6 @@ export const useTrackManager = ({ mediaManager, tsClient, }) => {
95
111
  enableTrack,
96
112
  currentTrackMiddleware,
97
113
  refreshStreamedTrack,
114
+ paused,
98
115
  };
99
116
  };