@fishjam-cloud/react-client 0.13.0 → 0.14.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.
@@ -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,EAAU,MAAM,OAAO,CAAC;AAUvD,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG/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;CAC5B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,2CA8D1D"}
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,EAAU,MAAM,OAAO,CAAC;AAUvD,OAAO,KAAK,EAAE,eAAe,EAAE,yBAAyB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG/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;CAC5B;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,2CAmE1D"}
@@ -15,7 +15,9 @@ import { mergeWithDefaultBandwitdthLimits } from "./utils/bandwidth";
15
15
  */
16
16
  export function FishjamProvider(props) {
17
17
  const fishjamClientRef = useRef(new FishjamClient({ reconnect: props.reconnect }));
18
- const hasDevicesBeenInitializedRef = useRef(false);
18
+ // HACK: This is a workaround to prevent multiple device initialization calls.
19
+ // TODO to be removed in FCE-1278
20
+ const devicesInitializationRef = useRef(null);
19
21
  const storage = props.persistLastDevice;
20
22
  const videoDeviceManagerRef = useRef(new DeviceManager({
21
23
  deviceType: "video",
@@ -37,6 +39,7 @@ export function FishjamProvider(props) {
37
39
  getCurrentPeerStatus,
38
40
  bandwidthLimits: mergedBandwidthLimits,
39
41
  streamConfig: props.videoConfig,
42
+ devicesInitializationRef,
40
43
  });
41
44
  const audioTrackManager = useTrackManager({
42
45
  mediaManager: audioDeviceManagerRef.current,
@@ -44,6 +47,7 @@ export function FishjamProvider(props) {
44
47
  getCurrentPeerStatus,
45
48
  bandwidthLimits: mergedBandwidthLimits,
46
49
  streamConfig: props.audioConfig,
50
+ devicesInitializationRef,
47
51
  });
48
52
  const screenShareManager = useScreenShareManager({ fishjamClient: fishjamClientRef.current, getCurrentPeerStatus });
49
53
  const clientState = useFishjamClientState(fishjamClientRef.current);
@@ -55,7 +59,7 @@ export function FishjamProvider(props) {
55
59
  audioTrackManager,
56
60
  videoDeviceManagerRef,
57
61
  audioDeviceManagerRef,
58
- hasDevicesBeenInitializedRef,
62
+ devicesInitializationRef,
59
63
  clientState,
60
64
  bandwidthLimits: mergedBandwidthLimits,
61
65
  };
@@ -21,6 +21,7 @@ export type DeviceManagerEvents = {
21
21
  deviceDisabled: (state: DeviceState) => void;
22
22
  middlewareSet: (state: DeviceState) => void;
23
23
  error: (event: any, state: DeviceState) => void;
24
+ initializedWithError: (state: DeviceState) => void;
24
25
  };
25
26
  export type DeviceManagerConfig = {
26
27
  deviceType: DeviceType;
@@ -1 +1 @@
1
- {"version":3,"file":"DeviceManager.d.ts","sourceRoot":"","sources":["../../src/devices/DeviceManager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DeviceManager.d.ts","sourceRoot":"","sources":["../../src/devices/DeviceManager.ts"],"names":[],"mappings":"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"}
@@ -58,6 +58,9 @@ export class DeviceManager extends EventEmitter {
58
58
  this.devicesStatus = devicesStatus;
59
59
  this.mediaStatus = devicesStatus;
60
60
  this.error = newError ?? error;
61
+ if (this.error) {
62
+ this.emit("initializedWithError", this.getState());
63
+ }
61
64
  this.updateMedia({
62
65
  stream: track ? stream : null,
63
66
  track,
@@ -91,22 +94,8 @@ export class DeviceManager extends EventEmitter {
91
94
  if (deviceInfo) {
92
95
  this.saveLastDevice?.(deviceInfo);
93
96
  }
94
- // The device manager assumes that there is only one audio and video track.
95
- // All previous tracks are deactivated even if the browser is able to handle multiple active sessions. (Chrome, Firefox)
96
- //
97
- // Safari always deactivates the track and emits the `ended` event.
98
- // Its handling is asynchronous and can be executed even before returning a value from the re-execution of `getUserMedia`.
99
- // In such a case, the tracks are already deactivated at this point (logic in `onTrackEnded` method).
100
- // The track is null, so the stop method will not execute.
101
- //
102
- // However, if Safari has not yet handled this event, the tracks are manually stopped at this point.
103
- // Manually stopping tracks on its own does not generate the `ended` event.
104
- // The ended event in Safari has already been emitted and will be handled in the future.
105
- // Therefore, in the `onTrackEnded` method, events for already stopped tracks are filtered out to prevent the state from being damaged.
106
- if (shouldReplaceDevice) {
107
- this.rawMedia?.track?.stop();
108
- this.processedMediaTrack?.stop();
109
- }
97
+ this.rawMedia?.track?.stop();
98
+ this.processedMediaTrack?.stop();
110
99
  this.updateMedia({
111
100
  stream,
112
101
  track,
@@ -125,9 +114,7 @@ export class DeviceManager extends EventEmitter {
125
114
  parsedError,
126
115
  constraints: exactConstraints,
127
116
  };
128
- if (exactConstraints) {
129
- this.error = parsedError;
130
- }
117
+ this.error = parsedError;
131
118
  this.emit("error", event, this.getState());
132
119
  }
133
120
  }
@@ -144,6 +131,7 @@ export class DeviceManager extends EventEmitter {
144
131
  this.middlewareManager.clearMiddleware();
145
132
  this.processedMediaTrack?.stop();
146
133
  this.rawMedia?.track?.stop();
134
+ this.media?.track?.stop();
147
135
  this.updateMedia(null);
148
136
  this.emit("deviceStopped", this.getState());
149
137
  }
@@ -6,6 +6,6 @@ type AudioVideo<T> = {
6
6
  type MediaConstraints = AudioVideo<MediaTrackConstraints | undefined | boolean>;
7
7
  type PreviousDevices = AudioVideo<MediaDeviceInfo | null>;
8
8
  export declare const getAvailableMedia: (constraints: MediaStreamConstraints, deviceErrors?: AudioVideo<DeviceError | null>) => Promise<[MediaStream | null, AudioVideo<DeviceError | null>]>;
9
- export declare const getCorrectedResult: (stream: MediaStream, deviceErrors: AudioVideo<DeviceError | null>, devices: MediaDeviceInfo[], constraints: MediaConstraints, previousDevices: PreviousDevices) => Promise<[MediaStream | null, AudioVideo<DeviceError | null>]>;
9
+ export declare const correctDevicesOnSafari: (stream: MediaStream, deviceErrors: AudioVideo<DeviceError | null>, devices: MediaDeviceInfo[], constraints: MediaConstraints, previousDevices: PreviousDevices) => Promise<[MediaStream | null, AudioVideo<DeviceError | null>]>;
10
10
  export {};
11
11
  //# sourceMappingURL=mediaInitializer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"mediaInitializer.d.ts","sourceRoot":"","sources":["../../src/devices/mediaInitializer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,KAAK,UAAU,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAE5C,KAAK,gBAAgB,GAAG,UAAU,CAAC,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;AAEhF,KAAK,eAAe,GAAG,UAAU,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAsB1D,eAAO,MAAM,iBAAiB,gBACf,sBAAsB,iBACrB,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,KAC3C,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAuB9D,CAAC;AAIF,eAAO,MAAM,kBAAkB,WACrB,WAAW,gBACL,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,WACnC,eAAe,EAAE,eACb,gBAAgB,mBACZ,eAAe,KAC/B,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAsB9D,CAAC"}
1
+ {"version":3,"file":"mediaInitializer.d.ts","sourceRoot":"","sources":["../../src/devices/mediaInitializer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAInD,KAAK,UAAU,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAE5C,KAAK,gBAAgB,GAAG,UAAU,CAAC,qBAAqB,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;AAChF,KAAK,eAAe,GAAG,UAAU,CAAC,eAAe,GAAG,IAAI,CAAC,CAAC;AAqC1D,eAAO,MAAM,iBAAiB,gBACf,sBAAsB,iBACrB,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,KAC3C,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAwB9D,CAAC;AAIF,eAAO,MAAM,sBAAsB,WACzB,WAAW,gBACL,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,WACnC,eAAe,EAAE,eACb,gBAAgB,mBACZ,eAAe,KAC/B,OAAO,CAAC,CAAC,WAAW,GAAG,IAAI,EAAE,UAAU,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,CAsB9D,CAAC"}
@@ -1,36 +1,55 @@
1
1
  import { NOT_FOUND_ERROR, OVERCONSTRAINED_ERROR, PERMISSION_DENIED, UNHANDLED_ERROR } from "../utils/errors";
2
2
  import { prepareConstraints } from "./constraints";
3
3
  const defaultErrors = { audio: null, video: null };
4
- const tryToGetAudioOnlyThenVideoOnly = async (constraints, deviceErrors = defaultErrors, transformConstraint = () => false) => {
5
- const audioOnly = await getAvailableMedia({ ...constraints, video: transformConstraint(constraints.video) }, { ...deviceErrors, audio: null });
6
- if (audioOnly[0])
7
- return audioOnly;
8
- return getAvailableMedia({ ...constraints, audio: transformConstraint(constraints.audio) }, { ...deviceErrors, video: null });
4
+ const errorMap = {
5
+ NotFoundError: NOT_FOUND_ERROR,
6
+ OverconstrainedError: OVERCONSTRAINED_ERROR,
7
+ NotAllowedError: PERMISSION_DENIED,
8
+ };
9
+ const getSingleMedia = async (type, constraints) => {
10
+ const baseConstraints = { audio: undefined, video: undefined };
11
+ try {
12
+ const stream = await navigator.mediaDevices.getUserMedia({ ...baseConstraints, [type]: constraints });
13
+ return [stream, null];
14
+ }
15
+ catch (err) {
16
+ if (!(err instanceof DOMException))
17
+ return [null, UNHANDLED_ERROR];
18
+ return [null, errorMap[err.name] ?? UNHANDLED_ERROR];
19
+ }
20
+ };
21
+ const tryToGetAudioOnlyThenVideoOnly = async (constraints, initialError) => {
22
+ const [audioStream, audioErr] = await getSingleMedia("audio", constraints.audio);
23
+ if (audioStream)
24
+ return [audioStream, { video: initialError, audio: null }];
25
+ const [videoStream, videoErr] = await getSingleMedia("video", constraints.video);
26
+ return [videoStream, { audio: audioErr, video: videoErr }];
9
27
  };
10
28
  export const getAvailableMedia = async (constraints, deviceErrors = defaultErrors) => {
11
29
  try {
12
30
  return [await navigator.mediaDevices.getUserMedia(constraints), deviceErrors];
13
31
  }
14
32
  catch (err) {
15
- if (!(err instanceof DOMException))
16
- return [null, { audio: UNHANDLED_ERROR, video: UNHANDLED_ERROR }];
17
- if (err.name === deviceErrors.audio?.name || err.name === deviceErrors.video?.name)
18
- return [null, deviceErrors];
19
- switch (err.name) {
20
- case "NotFoundError":
21
- return tryToGetAudioOnlyThenVideoOnly(constraints, { audio: NOT_FOUND_ERROR, video: NOT_FOUND_ERROR });
22
- case "OverconstrainedError":
23
- return tryToGetAudioOnlyThenVideoOnly(constraints, { audio: OVERCONSTRAINED_ERROR, video: OVERCONSTRAINED_ERROR }, removeSpecifiedDeviceFromConstraints);
24
- case "NotAllowedError":
25
- return tryToGetAudioOnlyThenVideoOnly(constraints, { audio: PERMISSION_DENIED, video: PERMISSION_DENIED });
26
- default:
27
- return [null, { audio: UNHANDLED_ERROR, video: UNHANDLED_ERROR }];
33
+ const unhandledErr = { audio: UNHANDLED_ERROR, video: UNHANDLED_ERROR };
34
+ if (err instanceof DOMException) {
35
+ switch (err.name) {
36
+ case deviceErrors.audio?.name:
37
+ case deviceErrors.video?.name:
38
+ return [null, deviceErrors];
39
+ case "NotFoundError":
40
+ return tryToGetAudioOnlyThenVideoOnly(constraints, PERMISSION_DENIED);
41
+ case "OverconstrainedError":
42
+ return getAvailableMedia({ audio: unspecifyDevice(constraints.audio), video: unspecifyDevice(constraints.video) }, { audio: OVERCONSTRAINED_ERROR, video: OVERCONSTRAINED_ERROR });
43
+ case "NotAllowedError":
44
+ return tryToGetAudioOnlyThenVideoOnly(constraints, PERMISSION_DENIED);
45
+ }
28
46
  }
47
+ return [null, unhandledErr];
29
48
  }
30
49
  };
31
50
  // Safari changes deviceId between sessions, therefore we cannot rely on deviceId for identification purposes.
32
51
  // We can switch a random device that comes from safari to one that has the same label as the one used in the previous session.
33
- export const getCorrectedResult = async (stream, deviceErrors, devices, constraints, previousDevices) => {
52
+ export const correctDevicesOnSafari = async (stream, deviceErrors, devices, constraints, previousDevices) => {
34
53
  const shouldCorrectDevices = isAnyDeviceDifferentFromLastSession(previousDevices.video, previousDevices.audio, getCurrentDevicesSettings(stream, devices));
35
54
  if (!shouldCorrectDevices)
36
55
  return [stream, deviceErrors];
@@ -69,7 +88,7 @@ const stopTracks = (requestedDevices) => {
69
88
  track.stop();
70
89
  }
71
90
  };
72
- const removeSpecifiedDeviceFromConstraints = (trackConstraints) => {
91
+ const unspecifyDevice = (trackConstraints) => {
73
92
  if (typeof trackConstraints === "object") {
74
93
  return { ...trackConstraints, deviceId: undefined };
75
94
  }
@@ -1,7 +1,12 @@
1
+ import { type DeviceError } from "../../types/public";
1
2
  export type UseInitializeDevicesParams = {
2
3
  enableVideo?: boolean;
3
4
  enableAudio?: boolean;
4
5
  };
6
+ export type InitializeDevicesErrors = {
7
+ audio: DeviceError | null;
8
+ video: DeviceError | null;
9
+ };
5
10
  /**
6
11
  * Hook allows you to initialize access to the devices before joining the room.
7
12
  * @category Devices
@@ -10,6 +15,6 @@ export declare const useInitializeDevices: () => {
10
15
  /**
11
16
  * Initialize access to the devices before joining the room
12
17
  */
13
- initializeDevices: (params?: UseInitializeDevicesParams) => Promise<void>;
18
+ initializeDevices: (params?: UseInitializeDevicesParams) => Promise<null | InitializeDevicesErrors>;
14
19
  };
15
20
  //# sourceMappingURL=useInitializeDevices.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useInitializeDevices.d.ts","sourceRoot":"","sources":["../../../src/hooks/devices/useInitializeDevices.ts"],"names":[],"mappings":"AAMA,MAAM,MAAM,0BAA0B,GAAG;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,oBAAoB;IAwD7B;;OAEG;iCAvD8B,0BAA0B,KAAK,OAAO,CAAC,IAAI,CAAC;CA0DhF,CAAC"}
1
+ {"version":3,"file":"useInitializeDevices.d.ts","sourceRoot":"","sources":["../../../src/hooks/devices/useInitializeDevices.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,MAAM,MAAM,0BAA0B,GAAG;IACvC,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;CAAE,CAAC;AAE/F;;;GAGG;AACH,eAAO,MAAM,oBAAoB;IA4E7B;;OAEG;iCA3E8B,0BAA0B,KAAK,OAAO,CAAC,IAAI,GAAG,uBAAuB,CAAC;CA8E1G,CAAC"}
@@ -1,42 +1,53 @@
1
1
  import { useCallback } from "react";
2
2
  import { prepareConstraints } from "../../devices/constraints";
3
- import { getAvailableMedia, getCorrectedResult } from "../../devices/mediaInitializer";
3
+ import { correctDevicesOnSafari, getAvailableMedia } from "../../devices/mediaInitializer";
4
+ import { Deferred } from "../../utils/deferred";
4
5
  import { useFishjamContext } from "../internal/useFishjamContext";
5
6
  /**
6
7
  * Hook allows you to initialize access to the devices before joining the room.
7
8
  * @category Devices
8
9
  */
9
10
  export const useInitializeDevices = () => {
10
- const { videoDeviceManagerRef, audioDeviceManagerRef, hasDevicesBeenInitializedRef } = useFishjamContext();
11
+ const { videoDeviceManagerRef, audioDeviceManagerRef, devicesInitializationRef } = useFishjamContext();
11
12
  const initializeDevices = useCallback(async ({ enableVideo = true, enableAudio = true } = {}) => {
12
- if (hasDevicesBeenInitializedRef.current)
13
- return;
14
- hasDevicesBeenInitializedRef.current = true;
15
- const videoManager = videoDeviceManagerRef.current;
16
- const audioManager = audioDeviceManagerRef.current;
17
- const constraints = {
18
- video: enableVideo && videoManager.getConstraints(),
19
- audio: enableAudio && audioManager.getConstraints(),
20
- };
21
- const previousDevices = {
22
- video: videoManager.getLastDevice(),
23
- audio: audioManager.getLastDevice(),
24
- };
25
- // Attempt to start the last selected device to avoid an unnecessary restart.
26
- // Without this, the first device will start, and `getCorrectedResult` will attempt to fix it.
27
- let [stream, deviceErrors] = await getAvailableMedia({
28
- video: enableVideo && prepareConstraints(previousDevices.video?.deviceId, constraints.video),
29
- audio: enableAudio && prepareConstraints(previousDevices.audio?.deviceId, constraints.audio),
30
- });
31
- const devices = await navigator.mediaDevices.enumerateDevices();
32
- const videoDevices = devices.filter(({ kind }) => kind === "videoinput");
33
- const audioDevices = devices.filter(({ kind }) => kind === "audioinput");
34
- if (stream) {
35
- [stream, deviceErrors] = await getCorrectedResult(stream, deviceErrors, devices, constraints, previousDevices);
13
+ if (devicesInitializationRef.current)
14
+ return null;
15
+ const deferred = new Deferred();
16
+ devicesInitializationRef.current = deferred.promise;
17
+ try {
18
+ const videoManager = videoDeviceManagerRef.current;
19
+ const audioManager = audioDeviceManagerRef.current;
20
+ const constraints = {
21
+ video: enableVideo && videoManager.getConstraints(),
22
+ audio: enableAudio && audioManager.getConstraints(),
23
+ };
24
+ const previousDevices = {
25
+ video: videoManager.getLastDevice(),
26
+ audio: audioManager.getLastDevice(),
27
+ };
28
+ // Attempt to start the last selected device to avoid an unnecessary restart.
29
+ // Without this, the first device will start, and `correctDevicesOnSafari` will attempt to fix it.
30
+ let [stream, deviceErrors] = await getAvailableMedia({
31
+ video: enableVideo && prepareConstraints(previousDevices.video?.deviceId, constraints.video),
32
+ audio: enableAudio && prepareConstraints(previousDevices.audio?.deviceId, constraints.audio),
33
+ });
34
+ const devices = await navigator.mediaDevices.enumerateDevices();
35
+ const videoDevices = devices.filter(({ kind }) => kind === "videoinput");
36
+ const audioDevices = devices.filter(({ kind }) => kind === "audioinput");
37
+ if (stream) {
38
+ [stream, deviceErrors] = await correctDevicesOnSafari(stream, deviceErrors, devices, constraints, previousDevices);
39
+ }
40
+ videoManager.initialize(stream, stream?.getVideoTracks()?.[0] ?? null, videoDevices, !!constraints.video, deviceErrors.video);
41
+ audioManager.initialize(stream, stream?.getAudioTracks()?.[0] ?? null, audioDevices, !!constraints.audio, deviceErrors.audio);
42
+ deferred.resolve();
43
+ if (deviceErrors.video || deviceErrors.audio)
44
+ return deviceErrors;
36
45
  }
37
- videoManager.initialize(stream, stream?.getVideoTracks()?.[0] ?? null, videoDevices, !!constraints.video, deviceErrors.video);
38
- audioManager.initialize(stream, stream?.getAudioTracks()?.[0] ?? null, audioDevices, !!constraints.audio, deviceErrors.audio);
39
- }, [videoDeviceManagerRef, audioDeviceManagerRef, hasDevicesBeenInitializedRef]);
46
+ catch {
47
+ deferred.reject();
48
+ }
49
+ return null;
50
+ }, [videoDeviceManagerRef, audioDeviceManagerRef, devicesInitializationRef]);
40
51
  return {
41
52
  /**
42
53
  * Initialize access to the devices before joining the room
@@ -1 +1 @@
1
- {"version":3,"file":"useDeviceManager.d.ts","sourceRoot":"","sources":["../../../../src/hooks/internal/device/useDeviceManager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAuB,MAAM,gCAAgC,CAAC;AACzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAelE,eAAO,MAAM,gBAAgB,kBAAmB,aAAa,uBAoC5D,CAAC"}
1
+ {"version":3,"file":"useDeviceManager.d.ts","sourceRoot":"","sources":["../../../../src/hooks/internal/device/useDeviceManager.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAuB,MAAM,gCAAgC,CAAC;AACzF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAgBlE,eAAO,MAAM,gBAAgB,kBAAmB,aAAa,uBAoC5D,CAAC"}
@@ -10,6 +10,7 @@ const eventNames = [
10
10
  "managerInitialized",
11
11
  "error",
12
12
  "middlewareSet",
13
+ "initializedWithError",
13
14
  ];
14
15
  export const useDeviceManager = (deviceManager) => {
15
16
  const mutationRef = useRef(false);
@@ -1,15 +1,15 @@
1
1
  import type { FishjamClient } from "@fishjam-cloud/ts-client";
2
- import { type MutableRefObject } from "react";
2
+ import { type RefObject } from "react";
3
3
  import type { DeviceManager } from "../../devices/DeviceManager";
4
4
  import type { TrackManager } from "../../types/internal";
5
5
  import type { BandwidthLimits, PeerStatus } from "../../types/public";
6
6
  import type { FishjamClientState } from "./useFishjamClientState";
7
7
  import type { UseScreenshareResult } from "./useScreenshareManager";
8
8
  export type FishjamContextType = {
9
- fishjamClientRef: MutableRefObject<FishjamClient>;
10
- videoDeviceManagerRef: MutableRefObject<DeviceManager>;
11
- audioDeviceManagerRef: MutableRefObject<DeviceManager>;
12
- hasDevicesBeenInitializedRef: MutableRefObject<boolean>;
9
+ fishjamClientRef: RefObject<FishjamClient>;
10
+ videoDeviceManagerRef: RefObject<DeviceManager>;
11
+ audioDeviceManagerRef: RefObject<DeviceManager>;
12
+ devicesInitializationRef: RefObject<Promise<void> | null>;
13
13
  screenShareManager: UseScreenshareResult;
14
14
  peerStatus: PeerStatus;
15
15
  videoTrackManager: TrackManager;
@@ -1 +1 @@
1
- {"version":3,"file":"useFishjamContext.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useFishjamContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAiB,KAAK,gBAAgB,EAAc,MAAM,OAAO,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IAClD,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACvD,qBAAqB,EAAE,gBAAgB,CAAC,aAAa,CAAC,CAAC;IACvD,4BAA4B,EAAE,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACxD,kBAAkB,EAAE,oBAAoB,CAAC;IACzC,UAAU,EAAE,UAAU,CAAC;IACvB,iBAAiB,EAAE,YAAY,CAAC;IAChC,iBAAiB,EAAE,YAAY,CAAC;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,eAAe,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,cAAc,oDAAiD,CAAC;AAE7E,wBAAgB,iBAAiB,IAGb,kBAAkB,CACrC"}
1
+ {"version":3,"file":"useFishjamContext.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useFishjamContext.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAiB,KAAK,SAAS,EAAc,MAAM,OAAO,CAAC;AAElE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,gBAAgB,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAC3C,qBAAqB,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAChD,qBAAqB,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;IAChD,wBAAwB,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1D,kBAAkB,EAAE,oBAAoB,CAAC;IACzC,UAAU,EAAE,UAAU,CAAC;IACvB,iBAAiB,EAAE,YAAY,CAAC;IAChC,iBAAiB,EAAE,YAAY,CAAC;IAChC,WAAW,EAAE,kBAAkB,CAAC;IAChC,eAAe,EAAE,eAAe,CAAC;CAClC,CAAC;AAEF,eAAO,MAAM,cAAc,oDAAiD,CAAC;AAE7E,wBAAgB,iBAAiB,IAGb,kBAAkB,CACrC"}
@@ -1,4 +1,5 @@
1
1
  import { type FishjamClient } from "@fishjam-cloud/ts-client";
2
+ import { type RefObject } from "react";
2
3
  import type { MediaManager, TrackManager } from "../../types/internal";
3
4
  import type { BandwidthLimits, PeerStatus, StreamConfig } from "../../types/public";
4
5
  interface TrackManagerConfig {
@@ -7,7 +8,8 @@ interface TrackManagerConfig {
7
8
  getCurrentPeerStatus: () => PeerStatus;
8
9
  bandwidthLimits: BandwidthLimits;
9
10
  streamConfig?: StreamConfig;
11
+ devicesInitializationRef: RefObject<Promise<void> | null>;
10
12
  }
11
- export declare const useTrackManager: ({ mediaManager, tsClient, getCurrentPeerStatus, bandwidthLimits, streamConfig, }: TrackManagerConfig) => TrackManager;
13
+ export declare const useTrackManager: ({ mediaManager, tsClient, getCurrentPeerStatus, bandwidthLimits, streamConfig, devicesInitializationRef, }: TrackManagerConfig) => TrackManager;
12
14
  export {};
13
15
  //# sourceMappingURL=useTrackManager.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useTrackManager.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useTrackManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAA+B,MAAM,0BAA0B,CAAC;AAG3F,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAGrG,UAAU,kBAAkB;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,oBAAoB,EAAE,MAAM,UAAU,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAWD,eAAO,MAAM,eAAe,qFAMzB,kBAAkB,KAAG,YA8KvB,CAAC"}
1
+ {"version":3,"file":"useTrackManager.d.ts","sourceRoot":"","sources":["../../../src/hooks/internal/useTrackManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAA+B,MAAM,0BAA0B,CAAC;AAC3F,OAAO,EAAE,KAAK,SAAS,EAA4C,MAAM,OAAO,CAAC;AAEjF,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAmB,MAAM,oBAAoB,CAAC;AAGrG,UAAU,kBAAkB;IAC1B,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,aAAa,CAAC;IACxB,oBAAoB,EAAE,MAAM,UAAU,CAAC;IACvC,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,wBAAwB,EAAE,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;CAC3D;AAWD,eAAO,MAAM,eAAe,+GAOzB,kBAAkB,KAAG,YAiLvB,CAAC"}
@@ -6,7 +6,7 @@ const TRACK_TYPE_TO_DEVICE = {
6
6
  audio: "microphone",
7
7
  };
8
8
  const getDeviceType = (mediaManager) => TRACK_TYPE_TO_DEVICE[mediaManager.getDeviceType()];
9
- export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus, bandwidthLimits, streamConfig, }) => {
9
+ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus, bandwidthLimits, streamConfig, devicesInitializationRef, }) => {
10
10
  const currentTrackIdRef = useRef(null);
11
11
  const [paused, setPaused] = useState(false);
12
12
  async function setTrackMiddleware(middleware) {
@@ -90,6 +90,7 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus,
90
90
  }
91
91
  }, [tsClient, getCurrentPeerStatus, resumeStreaming, startStreaming]);
92
92
  const toggle = useCallback(async (mode) => {
93
+ await devicesInitializationRef.current;
93
94
  const mediaStream = mediaManager.getMedia()?.stream;
94
95
  const track = mediaManager.getMedia()?.track ?? null;
95
96
  const enabled = Boolean(track?.enabled);
@@ -111,7 +112,7 @@ export const useTrackManager = ({ mediaManager, tsClient, getCurrentPeerStatus,
111
112
  await mediaManager.start();
112
113
  await stream();
113
114
  }
114
- }, [tsClient, mediaManager, pauseStreaming, stream]);
115
+ }, [devicesInitializationRef, mediaManager, tsClient, pauseStreaming, stream]);
115
116
  /**
116
117
  * @see {@link TrackManager#toggleMute} for more details.
117
118
  */
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { FishjamProvider, type FishjamProviderProps } from "./FishjamProvider";
2
2
  export { useCamera } from "./hooks/devices/useCamera";
3
- export { useInitializeDevices, UseInitializeDevicesParams } from "./hooks/devices/useInitializeDevices";
3
+ export { InitializeDevicesErrors, useInitializeDevices, UseInitializeDevicesParams, } from "./hooks/devices/useInitializeDevices";
4
4
  export { useMicrophone } from "./hooks/devices/useMicrophone";
5
5
  export { type JoinRoomConfig, useConnection } from "./hooks/useConnection";
6
6
  export { type PeerWithTracks, usePeers } from "./hooks/usePeers";
@@ -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,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,KAAK,cAAc,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjE,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,WAAW,EACX,UAAU,EACV,MAAM,EACN,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EACZ,KAAK,EACL,OAAO,EACP,eAAe,EACf,gBAAgB,GACjB,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"}
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,EACL,uBAAuB,EACvB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,sCAAsC,CAAC;AAC9C,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,KAAK,cAAc,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3E,OAAO,EAAE,KAAK,cAAc,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACjE,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,WAAW,EACX,UAAU,EACV,MAAM,EACN,UAAU,EACV,yBAAyB,EACzB,wBAAwB,EACxB,YAAY,EACZ,KAAK,EACL,OAAO,EACP,eAAe,EACf,gBAAgB,GACjB,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
@@ -1,6 +1,6 @@
1
1
  export { FishjamProvider } from "./FishjamProvider";
2
2
  export { useCamera } from "./hooks/devices/useCamera";
3
- export { useInitializeDevices } from "./hooks/devices/useInitializeDevices";
3
+ export { useInitializeDevices, } from "./hooks/devices/useInitializeDevices";
4
4
  export { useMicrophone } from "./hooks/devices/useMicrophone";
5
5
  export { useConnection } from "./hooks/useConnection";
6
6
  export { usePeers } from "./hooks/usePeers";
@@ -0,0 +1,9 @@
1
+ export declare class Deferred<T, E = unknown> {
2
+ readonly promise: Promise<T>;
3
+ private resolveFn;
4
+ private rejectFn;
5
+ constructor();
6
+ resolve(value: T): void;
7
+ reject(reason?: E): void;
8
+ }
9
+ //# sourceMappingURL=deferred.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferred.d.ts","sourceRoot":"","sources":["../../src/utils/deferred.ts"],"names":[],"mappings":"AAAA,qBAAa,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,OAAO;IAClC,SAAgB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;IAEpC,OAAO,CAAC,SAAS,CAAmD;IACpE,OAAO,CAAC,QAAQ,CAAoC;;IAS7C,OAAO,CAAC,KAAK,EAAE,CAAC;IAIhB,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;CAGzB"}
@@ -0,0 +1,17 @@
1
+ export class Deferred {
2
+ promise;
3
+ resolveFn = () => null;
4
+ rejectFn = () => null;
5
+ constructor() {
6
+ this.promise = new Promise((resolve, reject) => {
7
+ this.resolveFn = resolve;
8
+ this.rejectFn = reject;
9
+ });
10
+ }
11
+ resolve(value) {
12
+ this.resolveFn(value);
13
+ }
14
+ reject(reason) {
15
+ this.rejectFn(reason);
16
+ }
17
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fishjam-cloud/react-client",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "React client library for Fishjam",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Fishjam Team",
@@ -10,7 +10,11 @@
10
10
  "files": [
11
11
  "dist/**"
12
12
  ],
13
- "repository": "github:fishjam-cloud/web-client-sdk",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "git+https://github.com/fishjam-cloud/web-client-sdk.git",
16
+ "directory": "packages/react-client"
17
+ },
14
18
  "homepage": "https://github.com/fishjam-cloud/web-client-sdk#readme",
15
19
  "bugs": "https://github.com/fishjam-cloud/web-client-sdk/issues",
16
20
  "keywords": [
@@ -38,19 +42,19 @@
38
42
  "prepack": "yarn workspace @fishjam-cloud/ts-client build && yarn build"
39
43
  },
40
44
  "devDependencies": {
41
- "@playwright/test": "^1.50.0",
45
+ "@playwright/test": "^1.50.1",
42
46
  "@types/events": "^3.0.3",
43
47
  "@types/lodash.isequal": "^4.5.8",
44
- "@types/node": "^22.12.0",
45
- "@types/react": "^19.0.8",
48
+ "@types/node": "^22.13.4",
49
+ "@types/react": "^19.0.10",
46
50
  "react": "^19.0.0",
47
51
  "typed-emitter": "^2.1.0",
48
- "typedoc": "^0.27.6",
49
- "typedoc-plugin-mdn-links": "^4.0.10",
52
+ "typedoc": "^0.27.7",
53
+ "typedoc-plugin-mdn-links": "^4.0.13",
50
54
  "typescript": "^5.7.3"
51
55
  },
52
56
  "dependencies": {
53
- "@fishjam-cloud/ts-client": "0.13.0",
57
+ "@fishjam-cloud/ts-client": "0.14.0",
54
58
  "events": "3.3.0",
55
59
  "lodash.isequal": "4.5.0"
56
60
  },