@whereby.com/core 0.12.1 → 0.13.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/index.mjs CHANGED
@@ -43,9 +43,9 @@ const createReactor = (selectors, callback) => {
43
43
  });
44
44
  };
45
45
 
46
- const coreVersion = "0.12.1";
46
+ const coreVersion = "0.13.0";
47
47
 
48
- const initialState$d = {
48
+ const initialState$e = {
49
49
  isNodeSdk: false,
50
50
  wantsToJoin: false,
51
51
  roomName: null,
@@ -56,7 +56,7 @@ const initialState$d = {
56
56
  };
57
57
  const appSlice = createSlice({
58
58
  name: "app",
59
- initialState: initialState$d,
59
+ initialState: initialState$e,
60
60
  reducers: {
61
61
  doAppJoin: (state, action) => {
62
62
  const url = new URL(action.payload.roomUrl);
@@ -103,6 +103,43 @@ const signalEvents = {
103
103
  videoEnabled: createSignalEventAction("videoEnabled"),
104
104
  };
105
105
 
106
+ const ROOM_ACTION_PERMISSIONS_BY_ROLE = {
107
+ canLockRoom: ["host"],
108
+ canRequestAudioEnable: ["host"],
109
+ canKickClient: ["host"],
110
+ canEndMeeting: ["host"],
111
+ };
112
+ const initialState$d = {
113
+ roomKey: null,
114
+ roleName: "none",
115
+ };
116
+ const authorizationSlice = createSlice({
117
+ name: "authorization",
118
+ initialState: initialState$d,
119
+ reducers: {
120
+ setRoomKey: (state, action) => {
121
+ return Object.assign(Object.assign({}, state), { roomKey: action.payload });
122
+ },
123
+ },
124
+ extraReducers: (builder) => {
125
+ builder.addCase(doAppJoin, (state, action) => {
126
+ return Object.assign(Object.assign({}, state), { roomKey: action.payload.roomKey });
127
+ });
128
+ builder.addCase(signalEvents.roomJoined, (state, action) => {
129
+ var _a, _b;
130
+ const client = (_b = (_a = action.payload) === null || _a === void 0 ? void 0 : _a.room) === null || _b === void 0 ? void 0 : _b.clients.find((c) => { var _a; return c.id === ((_a = action.payload) === null || _a === void 0 ? void 0 : _a.selfId); });
131
+ return Object.assign(Object.assign({}, state), { roleName: (client === null || client === void 0 ? void 0 : client.role.roleName) || "none" });
132
+ });
133
+ },
134
+ });
135
+ const { setRoomKey } = authorizationSlice.actions;
136
+ const selectRoomKey = (state) => state.authorization.roomKey;
137
+ const selectAuthorizationRoleName = (state) => state.authorization.roleName;
138
+ const selectIsAuthorizedToLockRoom = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canLockRoom.includes(localParticipantRole));
139
+ const selectIsAuthorizedToRequestAudioEnable = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canRequestAudioEnable.includes(localParticipantRole));
140
+ const selectIsAuthorizedToKickClient = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canKickClient.includes(localParticipantRole));
141
+ const selectIsAuthorizedToEndMeeting = createSelector(selectAuthorizationRoleName, (localParticipantRole) => ROOM_ACTION_PERMISSIONS_BY_ROLE.canEndMeeting.includes(localParticipantRole));
142
+
106
143
  /******************************************************************************
107
144
  Copyright (c) Microsoft Corporation.
108
145
 
@@ -325,6 +362,92 @@ createReactor([selectShouldIdentifyDevice, selectDeviceCredentialsRaw], ({ dispa
325
362
  }
326
363
  });
327
364
 
365
+ const initialState$a = {
366
+ chatMessages: [],
367
+ };
368
+ const chatSlice = createSlice({
369
+ name: "chat",
370
+ initialState: initialState$a,
371
+ reducers: {},
372
+ extraReducers(builder) {
373
+ builder.addCase(signalEvents.chatMessage, (state, action) => {
374
+ const message = {
375
+ senderId: action.payload.senderId,
376
+ timestamp: action.payload.timestamp,
377
+ text: action.payload.text,
378
+ };
379
+ return Object.assign(Object.assign({}, state), { chatMessages: [...state.chatMessages, message] });
380
+ });
381
+ },
382
+ });
383
+ const doSendChatMessage = createAppThunk((payload) => (_, getState) => {
384
+ const state = getState();
385
+ const socket = selectSignalConnectionRaw(state).socket;
386
+ socket === null || socket === void 0 ? void 0 : socket.emit("chat_message", { text: payload.text });
387
+ });
388
+ const selectChatRaw = (state) => state.chat;
389
+ const selectChatMessages = (state) => state.chat.chatMessages;
390
+
391
+ const initialCloudRecordingState = {
392
+ isRecording: false,
393
+ error: null,
394
+ startedAt: undefined,
395
+ };
396
+ const cloudRecordingSlice = createSlice({
397
+ name: "cloudRecording",
398
+ initialState: initialCloudRecordingState,
399
+ reducers: {
400
+ recordingRequestStarted: (state) => {
401
+ return Object.assign(Object.assign({}, state), { status: "requested" });
402
+ },
403
+ },
404
+ extraReducers: (builder) => {
405
+ builder.addCase(signalEvents.cloudRecordingStopped, (state) => {
406
+ return Object.assign(Object.assign({}, state), { isRecording: false, status: undefined });
407
+ });
408
+ builder.addCase(signalEvents.cloudRecordingStarted, (state, action) => {
409
+ const { payload } = action;
410
+ if (!payload.error) {
411
+ return state;
412
+ }
413
+ return Object.assign(Object.assign({}, state), { isRecording: false, status: "error", error: payload.error });
414
+ });
415
+ builder.addCase(signalEvents.newClient, (state, { payload }) => {
416
+ var _a;
417
+ const { client } = payload;
418
+ if (((_a = client.role) === null || _a === void 0 ? void 0 : _a.roleName) === "recorder") {
419
+ return Object.assign(Object.assign({}, state), { isRecording: true, status: "recording", startedAt: client.startedCloudRecordingAt
420
+ ? new Date(client.startedCloudRecordingAt).getTime()
421
+ : new Date().getTime() });
422
+ }
423
+ return state;
424
+ });
425
+ },
426
+ });
427
+ const { recordingRequestStarted } = cloudRecordingSlice.actions;
428
+ const doStartCloudRecording = createAppThunk(() => (dispatch, getState) => {
429
+ const state = getState();
430
+ const socket = selectSignalConnectionRaw(state).socket;
431
+ const status = selectCloudRecordingStatus(state);
432
+ if (status && ["recording", "requested"].includes(status)) {
433
+ return;
434
+ }
435
+ socket === null || socket === void 0 ? void 0 : socket.emit("start_recording", {
436
+ recording: "cloud",
437
+ });
438
+ dispatch(recordingRequestStarted());
439
+ });
440
+ const doStopCloudRecording = createAppThunk(() => (dispatch, getState) => {
441
+ const state = getState();
442
+ const socket = selectSignalConnectionRaw(state).socket;
443
+ socket === null || socket === void 0 ? void 0 : socket.emit("stop_recording");
444
+ });
445
+ const selectCloudRecordingRaw = (state) => state.cloudRecording;
446
+ const selectCloudRecordingStatus = (state) => state.cloudRecording.status;
447
+ const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
448
+ const selectCloudRecordingError = (state) => state.cloudRecording.error;
449
+ const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
450
+
328
451
  function fakeAudioStream() {
329
452
  const audioCtx = new AudioContext();
330
453
  const oscillator = audioCtx.createOscillator();
@@ -455,6 +578,7 @@ const initialLocalMediaState = {
455
578
  isSettingCameraDevice: false,
456
579
  isSettingMicrophoneDevice: false,
457
580
  isTogglingCamera: false,
581
+ lowDataMode: false,
458
582
  microphoneEnabled: false,
459
583
  status: "",
460
584
  isSwitchingStream: false,
@@ -483,6 +607,10 @@ const localMediaSlice = createSlice({
483
607
  setCurrentMicrophoneDeviceId(state, action) {
484
608
  return Object.assign(Object.assign({}, state), { currentMicrophoneDeviceId: action.payload.deviceId });
485
609
  },
610
+ toggleLowDataModeEnabled(state, action) {
611
+ var _a;
612
+ return Object.assign(Object.assign({}, state), { lowDataMode: (_a = action.payload.enabled) !== null && _a !== void 0 ? _a : !state.lowDataMode });
613
+ },
486
614
  setDevices(state, action) {
487
615
  return Object.assign(Object.assign({}, state), { devices: action.payload.devices });
488
616
  },
@@ -561,7 +689,7 @@ const localMediaSlice = createSlice({
561
689
  });
562
690
  },
563
691
  });
564
- const { deviceBusy, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, toggleCameraEnabled, toggleMicrophoneEnabled, setLocalMediaOptions, setLocalMediaStream, localMediaStopped, localStreamMetadataUpdated, } = localMediaSlice.actions;
692
+ const { deviceBusy, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, toggleCameraEnabled, toggleMicrophoneEnabled, toggleLowDataModeEnabled, setLocalMediaOptions, setLocalMediaStream, localMediaStopped, localStreamMetadataUpdated, } = localMediaSlice.actions;
565
693
  const doToggleCamera = createAppAsyncThunk("localMedia/doToggleCamera", (_, { getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
566
694
  const state = getState();
567
695
  const stream = selectLocalMediaStream(state);
@@ -610,6 +738,16 @@ const doToggleMicrophone = createAppAsyncThunk("localMedia/doToggleMicrophone",
610
738
  }
611
739
  audioTrack.enabled = enabled;
612
740
  });
741
+ const doToggleLowDataMode = createAppThunk(() => (dispatch, getState) => {
742
+ const state = getState();
743
+ const stream = selectLocalMediaStream(state);
744
+ if (!stream) {
745
+ return;
746
+ }
747
+ const videoId = selectCurrentCameraDeviceId(state);
748
+ const audioId = selectCurrentMicrophoneDeviceId(state);
749
+ dispatch(doSwitchLocalStream({ audioId, videoId }));
750
+ });
613
751
  const doSetDevice = createAppAsyncThunk("localMedia/reactSetDevice", ({ audio, video }, { getState, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
614
752
  try {
615
753
  const state = getState();
@@ -633,12 +771,11 @@ const doSetDevice = createAppAsyncThunk("localMedia/reactSetDevice", ({ audio, v
633
771
  }
634
772
  }));
635
773
  const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList", (_, { getState, dispatch, rejectWithValue }) => __awaiter(void 0, void 0, void 0, function* () {
636
- var _a, _b;
774
+ var _a, _b, _c, _d;
637
775
  const state = getState();
638
776
  let newDevices = [];
639
777
  let oldDevices = [];
640
778
  const stream = selectLocalMediaStream(state);
641
- const busy = selectBusyDeviceIds(state);
642
779
  try {
643
780
  newDevices = yield navigator.mediaDevices.enumerateDevices();
644
781
  oldDevices = selectLocalMediaDevices(state);
@@ -650,39 +787,17 @@ const doUpdateDeviceList = createAppAsyncThunk("localMedia/doUpdateDeviceList",
650
787
  if (!shouldHandleDeviceUpdate) {
651
788
  return { devices: newDevices };
652
789
  }
653
- const { changedDevices } = getUpdatedDevices({
790
+ const { changedDevices, addedDevices } = getUpdatedDevices({
654
791
  oldDevices,
655
792
  newDevices,
656
- currentAudioId: selectCurrentMicrophoneDeviceId(state),
657
- currentVideoId: selectCurrentCameraDeviceId(state),
658
793
  });
659
794
  let autoSwitchAudioId = (_a = changedDevices.audioinput) === null || _a === void 0 ? void 0 : _a.deviceId;
660
795
  let autoSwitchVideoId = (_b = changedDevices.videoinput) === null || _b === void 0 ? void 0 : _b.deviceId;
661
- function nextId(devices, id) {
662
- const curIdx = id ? devices.findIndex((d) => d.deviceId === id) : 0;
663
- return (devices[(curIdx + 1) % devices.length] || {}).deviceId;
664
- }
665
- if (autoSwitchVideoId !== undefined) {
666
- const videoDevices = selectLocalMediaDevices(state).filter((d) => d.kind === "videoinput");
667
- const videoId = selectCurrentCameraDeviceId(state);
668
- let nextVideoId = nextId(videoDevices.filter((d) => !busy.includes(d.deviceId)), videoId);
669
- if (!nextVideoId || videoId === nextVideoId) {
670
- nextVideoId = nextId(videoDevices, videoId);
671
- }
672
- if (videoId !== nextVideoId) {
673
- autoSwitchVideoId = nextVideoId;
674
- }
796
+ if (autoSwitchAudioId === undefined) {
797
+ autoSwitchAudioId = (_c = addedDevices.audioinput) === null || _c === void 0 ? void 0 : _c.deviceId;
675
798
  }
676
- if (autoSwitchAudioId !== undefined) {
677
- const audioDevices = selectLocalMediaDevices(state).filter((d) => d.kind === "audioinput");
678
- const audioId = selectCurrentMicrophoneDeviceId(state);
679
- let nextAudioId = nextId(audioDevices.filter((d) => !busy.includes(d.deviceId)), audioId);
680
- if (!nextAudioId || audioId === nextAudioId) {
681
- nextAudioId = nextId(audioDevices, audioId);
682
- }
683
- if (audioId !== nextAudioId) {
684
- autoSwitchAudioId = nextAudioId;
685
- }
799
+ if (autoSwitchVideoId === undefined) {
800
+ autoSwitchVideoId = (_d = addedDevices.videoinput) === null || _d === void 0 ? void 0 : _d.deviceId;
686
801
  }
687
802
  if (autoSwitchAudioId !== undefined || autoSwitchVideoId !== undefined) {
688
803
  dispatch(doSwitchLocalStream({ audioId: autoSwitchAudioId, videoId: autoSwitchVideoId }));
@@ -766,6 +881,7 @@ const selectCurrentCameraDeviceId = (state) => state.localMedia.currentCameraDev
766
881
  const selectCurrentMicrophoneDeviceId = (state) => state.localMedia.currentMicrophoneDeviceId;
767
882
  const selectIsCameraEnabled = (state) => state.localMedia.cameraEnabled;
768
883
  const selectIsMicrophoneEnabled = (state) => state.localMedia.microphoneEnabled;
884
+ const selectIsLowDataModeEnabled = (state) => state.localMedia.lowDataMode;
769
885
  const selectIsSettingCameraDevice = (state) => state.localMedia.isSettingCameraDevice;
770
886
  const selectIsSettingMicrophoneDevice = (state) => state.localMedia.isSettingMicrophoneDevice;
771
887
  const selectIsToggleCamera = (state) => state.localMedia.isTogglingCamera;
@@ -778,14 +894,16 @@ const selectLocalMediaStream = (state) => state.localMedia.stream;
778
894
  const selectMicrophoneDeviceError = (state) => state.localMedia.microphoneDeviceError;
779
895
  const selectLocalMediaStartError = (state) => state.localMedia.startError;
780
896
  const selectLocalMediaIsSwitchingStream = (state) => state.localMedia.isSwitchingStream;
781
- const selectLocalMediaConstraintsOptions = createSelector(selectLocalMediaDevices, (devices) => ({
897
+ const selectLocalMediaConstraintsOptions = createSelector(selectLocalMediaDevices, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectIsLowDataModeEnabled, (devices, videoId, audioId, lowDataMode) => ({
782
898
  devices,
899
+ videoId,
900
+ audioId,
783
901
  options: {
784
902
  disableAEC: false,
785
903
  disableAGC: false,
786
904
  hd: true,
787
905
  lax: false,
788
- lowDataMode: false,
906
+ lowDataMode,
789
907
  simulcast: true,
790
908
  widescreen: true,
791
909
  },
@@ -823,6 +941,17 @@ startAppListening({
823
941
  dispatch(doToggleMicrophone());
824
942
  },
825
943
  });
944
+ startAppListening({
945
+ predicate: (_action, currentState, previousState) => {
946
+ const oldValue = selectIsLowDataModeEnabled(previousState);
947
+ const newValue = selectIsLowDataModeEnabled(currentState);
948
+ const isReady = selectLocalMediaStatus(previousState) === "started";
949
+ return isReady && oldValue !== newValue;
950
+ },
951
+ effect: (_action, { dispatch }) => {
952
+ dispatch(doToggleLowDataMode());
953
+ },
954
+ });
826
955
  startAppListening({
827
956
  predicate: (_action, currentState, previousState) => {
828
957
  const isToggling = selectIsToggleCamera(currentState);
@@ -886,7 +1015,7 @@ startAppListening({
886
1015
  },
887
1016
  });
888
1017
 
889
- const initialState$a = {
1018
+ const initialState$9 = {
890
1019
  displayName: "",
891
1020
  id: "",
892
1021
  isAudioEnabled: true,
@@ -920,7 +1049,7 @@ const doSetDisplayName = createAppAsyncThunk("localParticipant/doSetDisplayName"
920
1049
  }));
921
1050
  const localParticipantSlice = createSlice({
922
1051
  name: "localParticipant",
923
- initialState: initialState$a,
1052
+ initialState: initialState$9,
924
1053
  reducers: {
925
1054
  doSetLocalParticipant: (state, action) => {
926
1055
  return Object.assign(Object.assign({}, state), action.payload);
@@ -950,7 +1079,6 @@ const { doSetLocalParticipant } = localParticipantSlice.actions;
950
1079
  const selectLocalParticipantRaw = (state) => state.localParticipant;
951
1080
  const selectSelfId = (state) => state.localParticipant.id;
952
1081
  const selectLocalParticipantClientClaim = (state) => state.localParticipant.clientClaim;
953
- const selectLocalParticipantRole = (state) => state.localParticipant.roleName;
954
1082
  const selectLocalParticipantIsScreenSharing = (state) => state.localParticipant.isScreenSharing;
955
1083
  startAppListening({
956
1084
  actionCreator: toggleCameraEnabled,
@@ -969,144 +1097,14 @@ startAppListening({
969
1097
  },
970
1098
  });
971
1099
 
972
- const ACTION_PERMISSIONS_BY_ROLE = {
973
- canLockRoom: ["host"],
974
- canRequestAudioEnable: ["host"],
975
- };
976
- const initialState$9 = {
977
- roomKey: null,
978
- roomLocked: false,
979
- };
980
- const authorizationSlice = createSlice({
981
- name: "authorization",
982
- initialState: initialState$9,
983
- reducers: {
984
- setRoomKey: (state, action) => {
985
- return Object.assign(Object.assign({}, state), { roomKey: action.payload });
986
- },
987
- },
988
- extraReducers: (builder) => {
989
- builder.addCase(doAppJoin, (state, action) => {
990
- return Object.assign(Object.assign({}, state), { roomKey: action.payload.roomKey });
991
- });
992
- builder.addCase(signalEvents.roomJoined, (state, action) => {
993
- const { error, isLocked } = action.payload;
994
- if (error) {
995
- return state;
996
- }
997
- return Object.assign(Object.assign({}, state), { roomLocked: isLocked });
998
- });
999
- builder.addCase(signalEvents.roomLocked, (state, action) => {
1000
- const { isLocked } = action.payload;
1001
- return Object.assign(Object.assign({}, state), { roomLocked: isLocked });
1002
- });
1003
- },
1004
- });
1005
- const { setRoomKey } = authorizationSlice.actions;
1006
- const doLockRoom = createAppAuthorizedThunk((state) => selectIsAuthorizedToLockRoom(state), (payload) => (_, getState) => {
1007
- const state = getState();
1008
- const { socket } = selectSignalConnectionRaw(state);
1009
- socket === null || socket === void 0 ? void 0 : socket.emit("set_lock", { locked: payload.locked });
1010
- });
1011
- const selectAuthorizationRoomKey = (state) => state.authorization.roomKey;
1012
- const selectAuthorizationRoomLocked = (state) => state.authorization.roomLocked;
1013
- const selectIsAuthorizedToLockRoom = createSelector(selectLocalParticipantRole, (localParticipantRole) => ACTION_PERMISSIONS_BY_ROLE.canLockRoom.includes(localParticipantRole));
1014
- const selectIsAuthorizedToRequestAudioEnable = createSelector(selectLocalParticipantRole, (localParticipantRole) => ACTION_PERMISSIONS_BY_ROLE.canRequestAudioEnable.includes(localParticipantRole));
1015
-
1016
1100
  const initialState$8 = {
1017
- chatMessages: [],
1018
- };
1019
- const chatSlice = createSlice({
1020
- name: "chat",
1021
- initialState: initialState$8,
1022
- reducers: {},
1023
- extraReducers(builder) {
1024
- builder.addCase(signalEvents.chatMessage, (state, action) => {
1025
- const message = {
1026
- senderId: action.payload.senderId,
1027
- timestamp: action.payload.timestamp,
1028
- text: action.payload.text,
1029
- };
1030
- return Object.assign(Object.assign({}, state), { chatMessages: [...state.chatMessages, message] });
1031
- });
1032
- },
1033
- });
1034
- const doSendChatMessage = createAppThunk((payload) => (_, getState) => {
1035
- const state = getState();
1036
- const socket = selectSignalConnectionRaw(state).socket;
1037
- socket === null || socket === void 0 ? void 0 : socket.emit("chat_message", { text: payload.text });
1038
- });
1039
- const selectChatRaw = (state) => state.chat;
1040
- const selectChatMessages = (state) => state.chat.chatMessages;
1041
-
1042
- const initialCloudRecordingState = {
1043
- isRecording: false,
1044
- error: null,
1045
- startedAt: undefined,
1046
- };
1047
- const cloudRecordingSlice = createSlice({
1048
- name: "cloudRecording",
1049
- initialState: initialCloudRecordingState,
1050
- reducers: {
1051
- recordingRequestStarted: (state) => {
1052
- return Object.assign(Object.assign({}, state), { status: "requested" });
1053
- },
1054
- },
1055
- extraReducers: (builder) => {
1056
- builder.addCase(signalEvents.cloudRecordingStopped, (state) => {
1057
- return Object.assign(Object.assign({}, state), { isRecording: false, status: undefined });
1058
- });
1059
- builder.addCase(signalEvents.cloudRecordingStarted, (state, action) => {
1060
- const { payload } = action;
1061
- if (!payload.error) {
1062
- return state;
1063
- }
1064
- return Object.assign(Object.assign({}, state), { isRecording: false, status: "error", error: payload.error });
1065
- });
1066
- builder.addCase(signalEvents.newClient, (state, { payload }) => {
1067
- var _a;
1068
- const { client } = payload;
1069
- if (((_a = client.role) === null || _a === void 0 ? void 0 : _a.roleName) === "recorder") {
1070
- return Object.assign(Object.assign({}, state), { isRecording: true, status: "recording", startedAt: client.startedCloudRecordingAt
1071
- ? new Date(client.startedCloudRecordingAt).getTime()
1072
- : new Date().getTime() });
1073
- }
1074
- return state;
1075
- });
1076
- },
1077
- });
1078
- const { recordingRequestStarted } = cloudRecordingSlice.actions;
1079
- const doStartCloudRecording = createAppThunk(() => (dispatch, getState) => {
1080
- const state = getState();
1081
- const socket = selectSignalConnectionRaw(state).socket;
1082
- const status = selectCloudRecordingStatus(state);
1083
- if (status && ["recording", "requested"].includes(status)) {
1084
- return;
1085
- }
1086
- socket === null || socket === void 0 ? void 0 : socket.emit("start_recording", {
1087
- recording: "cloud",
1088
- });
1089
- dispatch(recordingRequestStarted());
1090
- });
1091
- const doStopCloudRecording = createAppThunk(() => (dispatch, getState) => {
1092
- const state = getState();
1093
- const socket = selectSignalConnectionRaw(state).socket;
1094
- socket === null || socket === void 0 ? void 0 : socket.emit("stop_recording");
1095
- });
1096
- const selectCloudRecordingRaw = (state) => state.cloudRecording;
1097
- const selectCloudRecordingStatus = (state) => state.cloudRecording.status;
1098
- const selectCloudRecordingStartedAt = (state) => state.cloudRecording.startedAt;
1099
- const selectCloudRecordingError = (state) => state.cloudRecording.error;
1100
- const selectIsCloudRecording = (state) => state.cloudRecording.isRecording;
1101
-
1102
- const initialState$7 = {
1103
1101
  status: "",
1104
1102
  stream: null,
1105
1103
  error: null,
1106
1104
  };
1107
1105
  const localScreenshareSlice = createSlice({
1108
1106
  name: "localScreenshare",
1109
- initialState: initialState$7,
1107
+ initialState: initialState$8,
1110
1108
  reducers: {
1111
1109
  stopScreenshare(state, action) {
1112
1110
  return Object.assign(Object.assign({}, state), { status: "", stream: null });
@@ -1175,13 +1173,13 @@ startAppListening({
1175
1173
  },
1176
1174
  });
1177
1175
 
1178
- const initialState$6 = {
1176
+ const initialState$7 = {
1179
1177
  data: null,
1180
1178
  isFetching: false,
1181
1179
  error: null,
1182
1180
  };
1183
1181
  const organizationSlice = createSlice({
1184
- initialState: initialState$6,
1182
+ initialState: initialState$7,
1185
1183
  name: "organization",
1186
1184
  reducers: {},
1187
1185
  extraReducers: (builder) => {
@@ -1330,12 +1328,12 @@ function addStream(state, payload) {
1330
1328
  presentationStream: stream,
1331
1329
  });
1332
1330
  }
1333
- const initialState$5 = {
1331
+ const initialState$6 = {
1334
1332
  remoteParticipants: [],
1335
1333
  };
1336
1334
  const remoteParticipantsSlice = createSlice({
1337
1335
  name: "remoteParticipants",
1338
- initialState: initialState$5,
1336
+ initialState: initialState$6,
1339
1337
  reducers: {
1340
1338
  streamStatusUpdated: (state, action) => {
1341
1339
  let newState = state;
@@ -1442,6 +1440,47 @@ const selectScreenshares = createSelector(selectLocalScreenshareStream, selectRe
1442
1440
  return screenshares;
1443
1441
  });
1444
1442
 
1443
+ const initialState$5 = {
1444
+ isLocked: false,
1445
+ };
1446
+ const roomSlice = createSlice({
1447
+ name: "room",
1448
+ initialState: initialState$5,
1449
+ reducers: {},
1450
+ extraReducers: (builder) => {
1451
+ builder.addCase(signalEvents.roomJoined, (state, action) => {
1452
+ const { error, isLocked } = action.payload;
1453
+ if (error) {
1454
+ return state;
1455
+ }
1456
+ return Object.assign(Object.assign({}, state), { isLocked: Boolean(isLocked) });
1457
+ });
1458
+ builder.addCase(signalEvents.roomLocked, (state, action) => {
1459
+ const { isLocked } = action.payload;
1460
+ return Object.assign(Object.assign({}, state), { isLocked: Boolean(isLocked) });
1461
+ });
1462
+ },
1463
+ });
1464
+ const doLockRoom = createAppAuthorizedThunk((state) => selectIsAuthorizedToLockRoom(state), (payload) => (_, getState) => {
1465
+ const state = getState();
1466
+ const { socket } = selectSignalConnectionRaw(state);
1467
+ socket === null || socket === void 0 ? void 0 : socket.emit("set_lock", { locked: payload.locked });
1468
+ });
1469
+ const doKickParticipant = createAppAuthorizedThunk((state) => selectIsAuthorizedToKickClient(state), (payload) => (_, getState) => {
1470
+ const state = getState();
1471
+ const { socket } = selectSignalConnectionRaw(state);
1472
+ socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientId: payload.clientId, reasonId: "kick" });
1473
+ });
1474
+ const doEndMeeting = createAppAuthorizedThunk((state) => selectIsAuthorizedToEndMeeting(state), () => (_, getState) => {
1475
+ const state = getState();
1476
+ const clientsToKick = selectRemoteParticipants(state).map((c) => c.id);
1477
+ if (clientsToKick.length) {
1478
+ const { socket } = selectSignalConnectionRaw(state);
1479
+ socket === null || socket === void 0 ? void 0 : socket.emit("kick_client", { clientIds: clientsToKick, reasonId: "end-meeting" });
1480
+ }
1481
+ });
1482
+ const selectRoomIsLocked = (state) => state.room.isLocked;
1483
+
1445
1484
  const initialState$4 = {
1446
1485
  session: null,
1447
1486
  status: "initializing",
@@ -1494,7 +1533,7 @@ const doKnockRoom = createAppThunk(() => (dispatch, getState) => {
1494
1533
  const state = getState();
1495
1534
  const socket = selectSignalConnectionRaw(state).socket;
1496
1535
  const roomName = selectAppRoomName(state);
1497
- const roomKey = selectAuthorizationRoomKey(state);
1536
+ const roomKey = selectRoomKey(state);
1498
1537
  const displayName = selectAppDisplayName(state);
1499
1538
  const userAgent = selectAppUserAgent(state);
1500
1539
  const externalId = selectAppExternalId(state);
@@ -1522,7 +1561,7 @@ const doConnectRoom = createAppThunk(() => (dispatch, getState) => {
1522
1561
  const state = getState();
1523
1562
  const socket = selectSignalConnectionRaw(state).socket;
1524
1563
  const roomName = selectAppRoomName(state);
1525
- const roomKey = selectAuthorizationRoomKey(state);
1564
+ const roomKey = selectRoomKey(state);
1526
1565
  const displayName = selectAppDisplayName(state);
1527
1566
  const userAgent = selectAppUserAgent(state);
1528
1567
  const externalId = selectAppExternalId(state);
@@ -1794,6 +1833,23 @@ startAppListening({
1794
1833
  rtcManager === null || rtcManager === void 0 ? void 0 : rtcManager.removeStream(stream.id, stream, null);
1795
1834
  },
1796
1835
  });
1836
+ startAppListening({
1837
+ actionCreator: doSwitchLocalStream.fulfilled,
1838
+ effect: ({ payload }, { getState }) => {
1839
+ var _a;
1840
+ const stream = selectLocalMediaStream(getState());
1841
+ const { rtcManager } = selectRtcConnectionRaw(getState());
1842
+ if (stream && rtcManager) {
1843
+ const replace = (kind, oldTrack) => {
1844
+ const track = stream.getTracks().find((t) => t.kind === kind);
1845
+ return track && rtcManager.replaceTrack(oldTrack, track);
1846
+ };
1847
+ (_a = payload === null || payload === void 0 ? void 0 : payload.replacedTracks) === null || _a === void 0 ? void 0 : _a.forEach((t) => {
1848
+ replace(t.kind, t);
1849
+ });
1850
+ }
1851
+ },
1852
+ });
1797
1853
  const selectShouldConnectRtc = createSelector(selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectSignalConnectionSocket, (dispatcherCreated, isCreatingDispatcher, signalSocket) => {
1798
1854
  if (!dispatcherCreated && !isCreatingDispatcher && signalSocket) {
1799
1855
  return true;
@@ -1959,7 +2015,7 @@ const rtcAnalyticsCustomEvents = {
1959
2015
  userRole: {
1960
2016
  actions: null,
1961
2017
  rtcEventName: "userRole",
1962
- getValue: (state) => selectLocalParticipantRole(state),
2018
+ getValue: (state) => selectAuthorizationRoleName(state),
1963
2019
  getOutput: (value) => ({ userRole: value }),
1964
2020
  },
1965
2021
  };
@@ -2121,6 +2177,7 @@ const rootReducer = combineReducers({
2121
2177
  localScreenshare: localScreenshareSlice.reducer,
2122
2178
  organization: organizationSlice.reducer,
2123
2179
  remoteParticipants: remoteParticipantsSlice.reducer,
2180
+ room: roomSlice.reducer,
2124
2181
  roomConnection: roomConnectionSlice.reducer,
2125
2182
  rtcAnalytics: rtcAnalyticsSlice.reducer,
2126
2183
  rtcConnection: rtcConnectionSlice.reducer,
@@ -3162,4 +3219,4 @@ function createServices() {
3162
3219
  };
3163
3220
  }
3164
3221
 
3165
- export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, appLeft, appSlice, authorizationSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppAuthorizedThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, debounce, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppJoin, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKnockRoom, doLockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRequestAudioEnable, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSetDevice, doSetDisplayName, doSetLocalParticipant, doSignalDisconnect, doSignalIdentifyDevice, doSignalSocketConnect, doStartCloudRecording, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doUpdateDeviceList, fakeAudioStream, fakeWebcamFrame, initialCloudRecordingState, initialLocalMediaState, isAcceptingStreams, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, observeStore, organizationSlice, parseRoomUrlAndSubdomain, parseUnverifiedRoomKeyData, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, resolutionReported, roomConnectionSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, selectAppDisplayName, selectAppExternalId, selectAppIsNodeSdk, selectAppRaw, selectAppRoomName, selectAppRoomUrl, selectAppUserAgent, selectAppWantsToJoin, selectAuthorizationRoomKey, selectAuthorizationRoomLocked, selectBusyDeviceIds, selectCameraDeviceError, selectCameraDevices, selectChatMessages, selectChatRaw, selectCloudRecordingError, selectCloudRecordingRaw, selectCloudRecordingStartedAt, selectCloudRecordingStatus, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectDeviceCredentialsRaw, selectDeviceId, selectHasFetchedDeviceCredentials, selectIsAcceptingStreams, selectIsAuthorizedToLockRoom, selectIsAuthorizedToRequestAudioEnable, selectIsCameraEnabled, selectIsCloudRecording, selectIsLocalMediaStarting, selectIsMicrophoneEnabled, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsToggleCamera, selectLocalMediaConstraintsOptions, selectLocalMediaDevices, selectLocalMediaIsSwitchingStream, selectLocalMediaOptions, selectLocalMediaOwnsStream, selectLocalMediaRaw, selectLocalMediaShouldStartWithOptions, selectLocalMediaShouldStop, selectLocalMediaStartError, selectLocalMediaStatus, selectLocalMediaStream, selectLocalParticipantClientClaim, selectLocalParticipantIsScreenSharing, selectLocalParticipantRaw, selectLocalParticipantRole, selectLocalScreenshareRaw, selectLocalScreenshareStatus, selectLocalScreenshareStream, selectMicrophoneDeviceError, selectMicrophoneDevices, selectOrganizationId, selectOrganizationRaw, selectRemoteParticipants, selectRemoteParticipantsRaw, selectRoomConnectionError, selectRoomConnectionRaw, selectRoomConnectionSession, selectRoomConnectionSessionId, selectRoomConnectionStatus, selectRtcConnectionRaw, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectRtcManager, selectRtcManagerInitialized, selectRtcStatus, selectScreenshares, selectSelfId, selectShouldConnectRoom, selectShouldConnectRtc, selectShouldConnectSignal, selectShouldDisconnectRtc, selectShouldFetchDeviceCredentials, selectShouldFetchOrganization, selectShouldIdentifyDevice, selectShouldInitializeRtc, selectSignalConnectionDeviceIdentified, selectSignalConnectionRaw, selectSignalConnectionSocket, selectSignalIsIdentifyingDevice, selectSignalStatus, selectSpeakerDevices, selectStreamingRaw, selectStreamsToAccept, selectWaitingParticipants, selectWaitingParticipantsRaw, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setLocalMediaOptions, setLocalMediaStream, setRoomKey, signalConnectionSlice, socketConnected, socketConnecting, socketDisconnected, socketReconnecting, startAppListening, stopScreenshare, streamStatusUpdated, streamingSlice, toggleCameraEnabled, toggleMicrophoneEnabled, updateReportedValues, waitingParticipantsSlice };
3222
+ export { ApiClient, Credentials, CredentialsService, LocalParticipant, OrganizationApiClient, OrganizationService, OrganizationServiceCache, RoomService, addAppListener, appLeft, appSlice, authorizationSlice, chatSlice, cloudRecordingSlice, createAppAsyncThunk, createAppAuthorizedThunk, createAppThunk, createReactor, createServices, createStore, createWebRtcEmitter, debounce, deviceBusy, deviceCredentialsSlice, deviceIdentified, deviceIdentifying, doAcceptWaitingParticipant, doAppJoin, doConnectRoom, doConnectRtc, doDisconnectRtc, doEnableAudio, doEnableVideo, doEndMeeting, doGetDeviceCredentials, doHandleAcceptStreams, doHandleStreamingStarted, doHandleStreamingStopped, doKickParticipant, doKnockRoom, doLockRoom, doOrganizationFetch, doRejectWaitingParticipant, doRequestAudioEnable, doRtcAnalyticsCustomEventsInitialize, doRtcManagerCreated, doRtcManagerInitialize, doRtcReportStreamResolution, doSendChatMessage, doSetDevice, doSetDisplayName, doSetLocalParticipant, doSignalDisconnect, doSignalIdentifyDevice, doSignalSocketConnect, doStartCloudRecording, doStartLocalMedia, doStartScreenshare, doStopCloudRecording, doStopLocalMedia, doStopScreenshare, doSwitchLocalStream, doToggleCamera, doToggleLowDataMode, doUpdateDeviceList, fakeAudioStream, fakeWebcamFrame, initialCloudRecordingState, initialLocalMediaState, isAcceptingStreams, listenerMiddleware, localMediaSlice, localMediaStopped, localParticipantSlice, localScreenshareSlice, localStreamMetadataUpdated, observeStore, organizationSlice, parseRoomUrlAndSubdomain, parseUnverifiedRoomKeyData, participantStreamAdded, participantStreamIdAdded, recordingRequestStarted, remoteParticipantsSlice, resolutionReported, roomConnectionSlice, roomSlice, rootReducer, rtcAnalyticsCustomEvents, rtcAnalyticsSlice, rtcConnectionSlice, rtcDisconnected, rtcDispatcherCreated, rtcManagerCreated, rtcManagerDestroyed, rtcManagerInitialized, selectAppDisplayName, selectAppExternalId, selectAppIsNodeSdk, selectAppRaw, selectAppRoomName, selectAppRoomUrl, selectAppUserAgent, selectAppWantsToJoin, selectAuthorizationRoleName, selectBusyDeviceIds, selectCameraDeviceError, selectCameraDevices, selectChatMessages, selectChatRaw, selectCloudRecordingError, selectCloudRecordingRaw, selectCloudRecordingStartedAt, selectCloudRecordingStatus, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectDeviceCredentialsRaw, selectDeviceId, selectHasFetchedDeviceCredentials, selectIsAcceptingStreams, selectIsAuthorizedToEndMeeting, selectIsAuthorizedToKickClient, selectIsAuthorizedToLockRoom, selectIsAuthorizedToRequestAudioEnable, selectIsCameraEnabled, selectIsCloudRecording, selectIsLocalMediaStarting, selectIsLowDataModeEnabled, selectIsMicrophoneEnabled, selectIsSettingCameraDevice, selectIsSettingMicrophoneDevice, selectIsToggleCamera, selectLocalMediaConstraintsOptions, selectLocalMediaDevices, selectLocalMediaIsSwitchingStream, selectLocalMediaOptions, selectLocalMediaOwnsStream, selectLocalMediaRaw, selectLocalMediaShouldStartWithOptions, selectLocalMediaShouldStop, selectLocalMediaStartError, selectLocalMediaStatus, selectLocalMediaStream, selectLocalParticipantClientClaim, selectLocalParticipantIsScreenSharing, selectLocalParticipantRaw, selectLocalScreenshareRaw, selectLocalScreenshareStatus, selectLocalScreenshareStream, selectMicrophoneDeviceError, selectMicrophoneDevices, selectOrganizationId, selectOrganizationRaw, selectRemoteParticipants, selectRemoteParticipantsRaw, selectRoomConnectionError, selectRoomConnectionRaw, selectRoomConnectionSession, selectRoomConnectionSessionId, selectRoomConnectionStatus, selectRoomIsLocked, selectRoomKey, selectRtcConnectionRaw, selectRtcDispatcherCreated, selectRtcIsCreatingDispatcher, selectRtcManager, selectRtcManagerInitialized, selectRtcStatus, selectScreenshares, selectSelfId, selectShouldConnectRoom, selectShouldConnectRtc, selectShouldConnectSignal, selectShouldDisconnectRtc, selectShouldFetchDeviceCredentials, selectShouldFetchOrganization, selectShouldIdentifyDevice, selectShouldInitializeRtc, selectSignalConnectionDeviceIdentified, selectSignalConnectionRaw, selectSignalConnectionSocket, selectSignalIsIdentifyingDevice, selectSignalStatus, selectSpeakerDevices, selectStreamingRaw, selectStreamsToAccept, selectWaitingParticipants, selectWaitingParticipantsRaw, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setLocalMediaOptions, setLocalMediaStream, setRoomKey, signalConnectionSlice, socketConnected, socketConnecting, socketDisconnected, socketReconnecting, startAppListening, stopScreenshare, streamStatusUpdated, streamingSlice, toggleCameraEnabled, toggleLowDataModeEnabled, toggleMicrophoneEnabled, updateReportedValues, waitingParticipantsSlice };
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@whereby.com/core",
3
3
  "description": "Core library for whereby.com sdk",
4
4
  "author": "Whereby AS",
5
- "version": "0.12.1",
5
+ "version": "0.13.0",
6
6
  "license": "MIT",
7
7
  "scripts": {
8
8
  "build": "rimraf dist && rollup -c rollup.config.js",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "@reduxjs/toolkit": "^2.2.3",
53
- "@whereby.com/media": "*",
53
+ "@whereby.com/media": "1.3.9",
54
54
  "axios": "^1.2.3",
55
55
  "btoa": "^1.2.1",
56
56
  "events": "^3.3.0"