@whereby.com/core 1.2.8 → 1.3.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.
@@ -75,9 +75,9 @@ const createReactor = (selectors, callback) => {
75
75
  });
76
76
  };
77
77
 
78
- const coreVersion = "1.2.8";
78
+ const coreVersion = "1.3.0";
79
79
 
80
- const initialState = {
80
+ const initialState$1 = {
81
81
  isNodeSdk: false,
82
82
  isActive: false,
83
83
  isDialIn: false,
@@ -91,7 +91,7 @@ const initialState = {
91
91
  };
92
92
  const appSlice = toolkit.createSlice({
93
93
  name: "app",
94
- initialState,
94
+ initialState: initialState$1,
95
95
  reducers: {
96
96
  doAppStart: (state, action) => {
97
97
  const url = new URL(action.payload.roomUrl);
@@ -592,6 +592,12 @@ const localMediaSlice = toolkit.createSlice({
592
592
  builder.addCase(doSwitchLocalStream.rejected, (state) => {
593
593
  return Object.assign(Object.assign({}, state), { isSwitchingStream: false });
594
594
  });
595
+ builder.addCase(doLocalStreamEffect.fulfilled, (state, { payload }) => {
596
+ if (!payload) {
597
+ return state;
598
+ }
599
+ return Object.assign(Object.assign({}, state), { beforeEffectTracks: Object.assign(Object.assign({}, state.beforeEffectTracks), payload.beforeEffectTracks) });
600
+ });
595
601
  },
596
602
  });
597
603
  const { deviceBusy, setCurrentCameraDeviceId, setCurrentMicrophoneDeviceId, setCurrentSpeakerDeviceId, toggleCameraEnabled, toggleMicrophoneEnabled, toggleLowDataModeEnabled, setLocalMediaOptions, setLocalMediaStream, localMediaStopped, localStreamMetadataUpdated, } = localMediaSlice.actions;
@@ -721,6 +727,15 @@ const doSwitchLocalStream = createAppAsyncThunk("localMedia/doSwitchLocalStream"
721
727
  if (!replaceStream) {
722
728
  return;
723
729
  }
730
+ const beforeEffectTracks = selectLocalMediaBeforeEffectTracks(state);
731
+ if (audioId !== undefined && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.audio)) {
732
+ beforeEffectTracks.audio.stop();
733
+ beforeEffectTracks.audio = undefined;
734
+ }
735
+ if (videoId !== undefined && (beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks.video)) {
736
+ beforeEffectTracks.video.stop();
737
+ beforeEffectTracks.video = undefined;
738
+ }
724
739
  try {
725
740
  const { replacedTracks } = yield media.getStream(Object.assign(Object.assign({}, constraintsOptions), { audioId: audioId === undefined ? false : audioId, videoId: videoId === undefined ? false : videoId, type: "exact" }), { replaceStream });
726
741
  const deviceId = audioId || videoId;
@@ -729,7 +744,7 @@ const doSwitchLocalStream = createAppAsyncThunk("localMedia/doSwitchLocalStream"
729
744
  deviceId,
730
745
  }));
731
746
  }
732
- return { replacedTracks };
747
+ return { replacedTracks, beforeEffectTracks };
733
748
  }
734
749
  catch (error) {
735
750
  console.error(error);
@@ -780,6 +795,46 @@ const doStopLocalMedia = createAppThunk(() => (dispatch, getState) => {
780
795
  }
781
796
  dispatch(localMediaStopped());
782
797
  });
798
+ const doLocalStreamEffect = createAppAsyncThunk("localMedia/doLocalStreamEffect", (_a, _b) => __awaiter(void 0, [_a, _b], void 0, function* ({ effectStream, only, stopBeforeTrack, }, { getState }) {
799
+ var _c;
800
+ const state = getState();
801
+ let beforeEffectTracks = selectLocalMediaBeforeEffectTracks(state);
802
+ const beforeTrack = beforeEffectTracks === null || beforeEffectTracks === void 0 ? void 0 : beforeEffectTracks[only];
803
+ if (!effectStream && !beforeTrack)
804
+ return;
805
+ try {
806
+ const stream = selectLocalMediaStream(state);
807
+ let replacedTracks = null;
808
+ if (!stream) {
809
+ throw new Error("No local media stream");
810
+ }
811
+ if (effectStream) {
812
+ if (!beforeTrack) {
813
+ beforeEffectTracks = {
814
+ [only]: (_c = (only === "audio" ? stream === null || stream === void 0 ? void 0 : stream.getAudioTracks() : stream === null || stream === void 0 ? void 0 : stream.getVideoTracks())) === null || _c === void 0 ? void 0 : _c[0],
815
+ };
816
+ }
817
+ replacedTracks = media.replaceTracksInStream(stream, effectStream, only);
818
+ }
819
+ else if (!stopBeforeTrack) {
820
+ replacedTracks = media.replaceTracksInStream(stream, beforeTrack ? new MediaStream([beforeTrack]) : new MediaStream(), only);
821
+ beforeEffectTracks = {
822
+ [only]: undefined,
823
+ };
824
+ }
825
+ else if (beforeTrack) {
826
+ beforeEffectTracks = {
827
+ [only]: undefined,
828
+ };
829
+ beforeTrack.stop();
830
+ }
831
+ return { effectStream, beforeEffectTracks, replacedTracks };
832
+ }
833
+ catch (error) {
834
+ console.error("Error applying local stream effect", error);
835
+ return;
836
+ }
837
+ }));
783
838
  const selectBusyDeviceIds = (state) => state.localMedia.busyDeviceIds;
784
839
  const selectCameraDeviceError = (state) => state.localMedia.cameraDeviceError;
785
840
  const selectCurrentCameraDeviceId = (state) => state.localMedia.currentCameraDeviceId;
@@ -800,6 +855,7 @@ const selectLocalMediaStream = (state) => state.localMedia.stream;
800
855
  const selectMicrophoneDeviceError = (state) => state.localMedia.microphoneDeviceError;
801
856
  const selectLocalMediaStartError = (state) => state.localMedia.startError;
802
857
  const selectLocalMediaIsSwitchingStream = (state) => state.localMedia.isSwitchingStream;
858
+ const selectLocalMediaBeforeEffectTracks = (state) => state.localMedia.beforeEffectTracks;
803
859
  const selectLocalMediaConstraintsOptions = toolkit.createSelector(selectLocalMediaDevices, selectCurrentCameraDeviceId, selectCurrentMicrophoneDeviceId, selectIsLowDataModeEnabled, (devices, videoId, audioId, lowDataMode) => ({
804
860
  devices,
805
861
  videoId,
@@ -896,7 +952,7 @@ startAppListening({
896
952
  },
897
953
  });
898
954
  startAppListening({
899
- matcher: toolkit.isAnyOf(doStartLocalMedia.fulfilled, doUpdateDeviceList.fulfilled, doSwitchLocalStream.fulfilled, doSwitchLocalStream.rejected),
955
+ matcher: toolkit.isAnyOf(doStartLocalMedia.fulfilled, doUpdateDeviceList.fulfilled, doSwitchLocalStream.fulfilled, doSwitchLocalStream.rejected, doLocalStreamEffect.fulfilled),
900
956
  effect: (_action, { dispatch, getState }) => {
901
957
  const state = getState();
902
958
  const stream = selectLocalMediaStream(state);
@@ -1960,7 +2016,7 @@ startAppListening({
1960
2016
  },
1961
2017
  });
1962
2018
  startAppListening({
1963
- actionCreator: doSwitchLocalStream.fulfilled,
2019
+ matcher: toolkit.isAnyOf(doSwitchLocalStream.fulfilled, doLocalStreamEffect.fulfilled),
1964
2020
  effect: ({ payload }, { getState }) => {
1965
2021
  var _a;
1966
2022
  const stream = selectLocalMediaStream(getState());
@@ -2988,11 +3044,107 @@ const doRejectWaitingParticipant = createRoomConnectedThunk((payload) => (dispat
2988
3044
  const selectWaitingParticipantsRaw = (state) => state.waitingParticipants;
2989
3045
  const selectWaitingParticipants = (state) => state.waitingParticipants.waitingParticipants;
2990
3046
 
3047
+ const initialState = {
3048
+ isSwitching: false,
3049
+ raw: {},
3050
+ };
3051
+ const cameraEffectsSlice = toolkit.createSlice({
3052
+ name: "cameraEffects",
3053
+ initialState,
3054
+ reducers: {
3055
+ cameraEffectsSwitching(state, action) {
3056
+ state.isSwitching = action.payload.isSwitching;
3057
+ },
3058
+ cameraEffectsCleared(state) {
3059
+ state.currentEffectId = null;
3060
+ state.setup = undefined;
3061
+ state.params = undefined;
3062
+ state.raw = {};
3063
+ state.error = undefined;
3064
+ state.isSwitching = false;
3065
+ },
3066
+ cameraEffectsUpdated(state, action) {
3067
+ const { effectId, setup, params, raw } = action.payload;
3068
+ state.currentEffectId = effectId;
3069
+ state.setup = setup;
3070
+ state.params = params;
3071
+ if (raw)
3072
+ state.raw = raw;
3073
+ state.error = undefined;
3074
+ state.isSwitching = false;
3075
+ },
3076
+ cameraEffectsError(state, action) {
3077
+ state.error = action.payload.error;
3078
+ state.isSwitching = false;
3079
+ },
3080
+ },
3081
+ });
3082
+ const { cameraEffectsSwitching, cameraEffectsCleared, cameraEffectsUpdated, cameraEffectsError } = cameraEffectsSlice.actions;
3083
+ const selectCameraEffectsRaw = (state) => state.cameraEffects.raw;
3084
+ const doCameraEffectsSwitchPreset = createAppAsyncThunk("cameraEffects/switchPreset", (_a, _b) => __awaiter(void 0, [_a, _b], void 0, function* ({ effectId, setup, params, allowSafari, }, { getState, dispatch, rejectWithValue }) {
3085
+ var _c, _d, _e;
3086
+ const state = getState();
3087
+ if (selectLocalMediaIsSwitchingStream(state)) {
3088
+ return;
3089
+ }
3090
+ dispatch(cameraEffectsSwitching({ isSwitching: true }));
3091
+ try {
3092
+ const raw = selectCameraEffectsRaw(state);
3093
+ const localStream = selectLocalMediaStream(state);
3094
+ if (!((_c = localStream === null || localStream === void 0 ? void 0 : localStream.getVideoTracks()) === null || _c === void 0 ? void 0 : _c[0])) {
3095
+ dispatch(cameraEffectsCleared());
3096
+ return;
3097
+ }
3098
+ if (!effectId) {
3099
+ if (raw.effectStream) {
3100
+ yield dispatch(doLocalStreamEffect({ effectStream: undefined, only: "video" }));
3101
+ }
3102
+ (_d = raw.stop) === null || _d === void 0 ? void 0 : _d.call(raw);
3103
+ dispatch(cameraEffectsCleared());
3104
+ return;
3105
+ }
3106
+ if (raw.tryUpdate) {
3107
+ const ok = yield raw.tryUpdate(effectId, Object.assign({}, (setup || {})), Object.assign({}, (params || {})));
3108
+ if (ok) {
3109
+ dispatch(cameraEffectsUpdated({ effectId, setup, params }));
3110
+ return;
3111
+ }
3112
+ }
3113
+ if (raw.effectStream) {
3114
+ yield dispatch(doLocalStreamEffect({ effectStream: undefined, only: "video" }));
3115
+ (_e = raw.stop) === null || _e === void 0 ? void 0 : _e.call(raw);
3116
+ }
3117
+ let mod;
3118
+ try {
3119
+ mod = yield import('@whereby.com/camera-effects');
3120
+ }
3121
+ catch (_f) {
3122
+ throw new Error("@whereby.com/camera-effects is not installed. Add it as a dependency to enable camera effects.");
3123
+ }
3124
+ const { createEffectStream, getUsablePresets } = mod;
3125
+ const usable = getUsablePresets({ filter: () => true, options: { allowSafari } });
3126
+ if (!usable.includes(effectId)) {
3127
+ throw new Error(`Unknown or unsupported effect preset: ${effectId}`);
3128
+ }
3129
+ const { stream: effectStream, stop, tryUpdate, } = yield createEffectStream(localStream, effectId, setup, params);
3130
+ yield dispatch(doLocalStreamEffect({ effectStream, only: "video" }));
3131
+ dispatch(cameraEffectsUpdated({ effectId, setup, params, raw: { stop, tryUpdate, effectStream } }));
3132
+ }
3133
+ catch (error) {
3134
+ dispatch(cameraEffectsError({ error }));
3135
+ return rejectWithValue(error);
3136
+ }
3137
+ }));
3138
+ createAppAsyncThunk("cameraEffects/clear", (_1, _a) => __awaiter(void 0, [_1, _a], void 0, function* (_, { dispatch }) {
3139
+ yield dispatch(doCameraEffectsSwitchPreset({ effectId: null }));
3140
+ }));
3141
+
2991
3142
  const IS_DEV = undefined === "true";
2992
3143
  const appReducer = toolkit.combineReducers({
2993
3144
  app: appSlice.reducer,
2994
3145
  authorization: authorizationSlice.reducer,
2995
3146
  breakout: breakoutSlice.reducer,
3147
+ cameraEffects: cameraEffectsSlice.reducer,
2996
3148
  chat: chatSlice.reducer,
2997
3149
  cloudRecording: cloudRecordingSlice.reducer,
2998
3150
  connectionMonitor: connectionMonitorSlice.reducer,
@@ -3817,6 +3969,7 @@ exports.doHandleStreamingStarted = doHandleStreamingStarted;
3817
3969
  exports.doHandleStreamingStopped = doHandleStreamingStopped;
3818
3970
  exports.doKickParticipant = doKickParticipant;
3819
3971
  exports.doKnockRoom = doKnockRoom;
3972
+ exports.doLocalStreamEffect = doLocalStreamEffect;
3820
3973
  exports.doLockRoom = doLockRoom;
3821
3974
  exports.doOrganizationFetch = doOrganizationFetch;
3822
3975
  exports.doRejectWaitingParticipant = doRejectWaitingParticipant;
@@ -3852,7 +4005,7 @@ exports.doUpdateDeviceList = doUpdateDeviceList;
3852
4005
  exports.initialCloudRecordingState = initialCloudRecordingState;
3853
4006
  exports.initialLocalMediaState = initialLocalMediaState;
3854
4007
  exports.initialNotificationsState = initialNotificationsState;
3855
- exports.initialState = initialState;
4008
+ exports.initialState = initialState$1;
3856
4009
  exports.isAcceptingStreams = isAcceptingStreams;
3857
4010
  exports.isClientSpotlighted = isClientSpotlighted;
3858
4011
  exports.listenerMiddleware = listenerMiddleware;
@@ -3949,6 +4102,7 @@ exports.selectIsMicrophoneEnabled = selectIsMicrophoneEnabled;
3949
4102
  exports.selectIsSettingCameraDevice = selectIsSettingCameraDevice;
3950
4103
  exports.selectIsSettingMicrophoneDevice = selectIsSettingMicrophoneDevice;
3951
4104
  exports.selectIsToggleCamera = selectIsToggleCamera;
4105
+ exports.selectLocalMediaBeforeEffectTracks = selectLocalMediaBeforeEffectTracks;
3952
4106
  exports.selectLocalMediaConstraintsOptions = selectLocalMediaConstraintsOptions;
3953
4107
  exports.selectLocalMediaDevices = selectLocalMediaDevices;
3954
4108
  exports.selectLocalMediaIsSwitchingStream = selectLocalMediaIsSwitchingStream;