react-use-opentok
Version:
React Hook for @opentok/client SDK
512 lines (460 loc) • 18.1 kB
JavaScript
var _defineProperty = require('@babel/runtime/helpers/defineProperty');
var _regeneratorRuntime = require('@babel/runtime/regenerator');
var _asyncToGenerator = require('@babel/runtime/helpers/asyncToGenerator');
var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
var react = require('react');
var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
var OT = require('@opentok/client');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var _defineProperty__default = /*#__PURE__*/_interopDefaultLegacy(_defineProperty);
var _regeneratorRuntime__default = /*#__PURE__*/_interopDefaultLegacy(_regeneratorRuntime);
var _asyncToGenerator__default = /*#__PURE__*/_interopDefaultLegacy(_asyncToGenerator);
var _slicedToArray__default = /*#__PURE__*/_interopDefaultLegacy(_slicedToArray);
var _toConsumableArray__default = /*#__PURE__*/_interopDefaultLegacy(_toConsumableArray);
var OT__default = /*#__PURE__*/_interopDefaultLegacy(OT);
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
var initialState = {
// connection info
isSessionInitialized: false,
connectionId: undefined,
isSessionConnected: false,
// connected data
session: undefined,
connections: [],
streams: [],
subscribers: [],
publisher: {}
}; // ACTION TYPE
var UPDATE = 'UPDATE';
var ADD_CONNECTION = 'ADD_CONNECTION';
var REMOVE_CONNECTION = 'REMOVE_CONNECTION';
var ADD_STREAM = 'ADD_STREAM';
var REMOVE_STREAM = 'REMOVE_STREAM';
var SET_PUBLISHER = 'SET_PUBLISHER';
var REMOVE_PUBLISHER = 'REMOVE_PUBLISHER';
var ADD_SUBSCRIBER = 'ADD_SUBSCRIBER';
var REMOVE_SUBSCRIBER = 'REMOVE_SUBSCRIBER';
var reducer = function reducer(state, action) {
var type = action.type,
payload = action.payload;
switch (type) {
// CONNECT_SUCCESS
case UPDATE:
{
return _objectSpread(_objectSpread({}, state), payload);
}
case ADD_CONNECTION:
{
return _objectSpread(_objectSpread({}, state), {}, {
connections: [].concat(_toConsumableArray__default['default'](state.connections), [payload])
});
}
case REMOVE_CONNECTION:
{
return _objectSpread(_objectSpread({}, state), {}, {
connections: _toConsumableArray__default['default'](state.connections.filter(function (c) {
return c.connectionId !== payload.connectionId;
}))
});
}
case ADD_STREAM:
{
return _objectSpread(_objectSpread({}, state), {}, {
streams: [].concat(_toConsumableArray__default['default'](state.streams), [payload])
});
}
case REMOVE_STREAM:
{
return _objectSpread(_objectSpread({}, state), {}, {
streams: _toConsumableArray__default['default'](state.streams.filter(function (s) {
return s.streamId !== payload.streamId;
}))
});
}
case SET_PUBLISHER:
{
var name = payload.name,
publisher = payload.publisher;
return _objectSpread(_objectSpread({}, state), {}, {
publisher: _objectSpread(_objectSpread({}, state.publisher), {}, _defineProperty__default['default']({}, name, publisher))
});
}
case REMOVE_PUBLISHER:
{
var _name = payload.name;
return _objectSpread(_objectSpread({}, state), {}, {
publisher: _objectSpread(_objectSpread({}, state.publisher), {}, _defineProperty__default['default']({}, _name, null))
});
}
case ADD_SUBSCRIBER:
{
return _objectSpread(_objectSpread({}, state), {}, {
subscribers: [].concat(_toConsumableArray__default['default'](state.subscribers), [payload])
});
}
case REMOVE_SUBSCRIBER:
{
return _objectSpread(_objectSpread({}, state), {}, {
subscribers: _toConsumableArray__default['default'](state.subscribers.filter(function (s) {
return s.streamId !== payload.streamId;
}))
});
}
default:
return state;
}
};
var useOpenTokReducer = function useOpenTokReducer() {
var _useReducer = react.useReducer(reducer, initialState),
_useReducer2 = _slicedToArray__default['default'](_useReducer, 2),
state = _useReducer2[0],
dispatch = _useReducer2[1];
var action = react.useMemo(function () {
return {
update: function update(payload) {
dispatch({
type: UPDATE,
payload: payload
});
},
addConnection: function addConnection(connection) {
dispatch({
type: ADD_CONNECTION,
payload: connection
});
},
removeConnection: function removeConnection(connection) {
dispatch({
type: REMOVE_CONNECTION,
payload: connection
});
},
addStream: function addStream(stream) {
dispatch({
type: ADD_STREAM,
payload: stream
});
},
removeStream: function removeStream(stream) {
dispatch({
type: REMOVE_STREAM,
payload: stream
});
},
setPublisher: function setPublisher(_ref) {
var name = _ref.name,
publisher = _ref.publisher;
dispatch({
type: SET_PUBLISHER,
payload: {
name: name,
publisher: publisher
}
});
},
removePublisher: function removePublisher(_ref2) {
var name = _ref2.name;
dispatch({
type: REMOVE_PUBLISHER,
payload: {
name: name
}
});
},
addSubscriber: function addSubscriber(subscriber) {
dispatch({
type: ADD_SUBSCRIBER,
payload: subscriber
});
},
removeSubscriber: function removeSubscriber(subscriber) {
dispatch({
type: REMOVE_SUBSCRIBER,
payload: subscriber
});
}
};
}, []);
return [state, action];
};
var events = ['archiveStarted', 'archiveStopped', 'connectionCreated', 'connectionDestroyed', 'sessionConnected', 'sessionDisconnected', 'sessionReconnected', 'sessionReconnecting', 'signal', 'streamCreated', 'streamDestroyed', 'streamPropertyChanged'];
var useSessionEventHandler = (function (type, callback, session) {
var isEventTypeSupported = events.some(function (e) {
return type.startsWith(e);
});
if (!isEventTypeSupported) {
throw new Error('[ReactUseOpenTok] useSessionEventHandler: The event type is NOT supported');
}
if (typeof callback !== 'function') {
throw new Error('[ReactUseOpenTok] useSessionEventHandler: Incorrect value or type of callback');
}
react.useEffect(function () {
var _ref = session || {},
sessionId = _ref.sessionId;
if (typeof sessionId !== 'string') {
return;
}
session.on(type, callback);
return function () {
session.off(type, callback);
};
}, [session, type, callback]);
});
function ownKeys$1(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread$1(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys$1(Object(source), true).forEach(function (key) { _defineProperty__default['default'](target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys$1(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
var defaultOptions = {
insertMode: 'append',
width: '100%',
height: '100%'
};
var useOpenTok = function useOpenTok() {
var _useOpenTokReducer = useOpenTokReducer(),
_useOpenTokReducer2 = _slicedToArray__default['default'](_useOpenTokReducer, 2),
state = _useOpenTokReducer2[0],
action = _useOpenTokReducer2[1];
var isSessionConnected = state.isSessionConnected,
session = state.session,
subscribers = state.subscribers,
publisher = state.publisher,
streams = state.streams;
var handleConnectionCreated = react.useCallback(function (event) {
action.addConnection(event.connection);
}, [action]);
var handleConnectionDestroyed = react.useCallback(function (event) {
action.removeConnection(event.connection);
}, [action]);
var handleStreamCreated = react.useCallback(function (event) {
action.addStream(event.stream);
}, [action]);
var handleStreamDestroyed = react.useCallback(function (event) {
action.removeStream(event.stream);
}, [action]);
var initSession = react.useCallback(function (_ref) {
var apiKey = _ref.apiKey,
sessionId = _ref.sessionId,
sessionOptions = _ref.sessionOptions;
return new Promise(function (resolve) {
var session = OT__default['default'].initSession(apiKey, sessionId, sessionOptions);
action.update({
session: session,
isSessionInitialized: true
});
resolve(session);
});
}, [action]);
var connectSession = react.useCallback(function (token, sessionToConnect) {
return new Promise(function (resolve, reject) {
if (!token) {
return reject('[ReactUseOpenTok] token does not exist.');
}
if (!sessionToConnect) {
return reject('[ReactUseOpenTok] session does not exist.');
}
sessionToConnect.connect(token, function (error) {
if (error) {
reject(error);
} else {
var connectionId = sessionToConnect.connection.connectionId;
action.update({
connectionId: connectionId,
isSessionConnected: true
});
resolve(connectionId);
}
});
});
}, [action]);
var initSessionAndConnect = react.useCallback( /*#__PURE__*/function () {
var _ref3 = _asyncToGenerator__default['default']( /*#__PURE__*/_regeneratorRuntime__default['default'].mark(function _callee(_ref2) {
var apiKey, sessionId, token, sessionOptions, newSession;
return _regeneratorRuntime__default['default'].wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
apiKey = _ref2.apiKey, sessionId = _ref2.sessionId, token = _ref2.token, sessionOptions = _ref2.sessionOptions;
_context.next = 3;
return initSession({
apiKey: apiKey,
sessionId: sessionId,
sessionOptions: sessionOptions
});
case 3:
newSession = _context.sent;
_context.next = 6;
return connectSession(token, newSession);
case 6:
case "end":
return _context.stop();
}
}
}, _callee);
}));
return function (_x) {
return _ref3.apply(this, arguments);
};
}(), [connectSession, initSession]);
var disconnectSession = react.useCallback(function () {
session.disconnect();
action.update({
connectionId: null,
isSessionConnected: false
});
}, [action, session]);
var initPublisher = react.useCallback(function (_ref4) {
var name = _ref4.name,
element = _ref4.element,
options = _ref4.options;
if (publisher[name]) {
throw new Error("[ReactUseOpenTok] initPublisher: The publisher(".concat(name, ") is already existed"));
}
return new Promise(function (resolve, reject) {
var newPublisher = OT__default['default'].initPublisher(element, _objectSpread$1(_objectSpread$1({}, defaultOptions), options), function (error) {
if (error) {
reject(error);
}
});
action.setPublisher({
name: name,
publisher: newPublisher
});
resolve(newPublisher);
});
}, [action, session, publisher]);
var removePublisher = react.useCallback(function (_ref5) {
var name = _ref5.name;
if (!publisher[name]) {
throw new Error("[ReactUseOpenTok] removePublisher: The publisher(".concat(name, ") is not existed"));
}
var published = streams.some(function (stream) {
return stream.streamId === publisher[name].stream.streamId;
});
if (published) {
throw new Error("[ReactUseOpenTok] removePublisher: can NOT remove published publisher, please use unpublish instead.");
}
publisher[name].destroy();
action.removePublisher({
name: name
});
}, [action, streams, publisher]);
var publishPublisher = react.useCallback(function (_ref6) {
var name = _ref6.name;
if (!publisher[name]) {
throw new Error("[ReactUseOpenTok] publishPublisher: The publisher(".concat(name, ") is not existed"));
}
return new Promise(function (resolve, reject) {
session.publish(publisher[name], function (error) {
if (error) {
reject(error);
} else {
action.addStream(publisher[name].stream);
resolve(publisher[name].stream);
}
});
});
}, [action, session, publisher]);
var publish = react.useCallback(function (_ref7) {
var name = _ref7.name,
element = _ref7.element,
options = _ref7.options;
if (publisher[name]) {
throw new Error("[ReactUseOpenTok] publish: The publisher(".concat(name, ") is already existed"));
}
return new Promise(function (resolve, reject) {
var newPublisher = OT__default['default'].initPublisher(element, _objectSpread$1(_objectSpread$1({}, defaultOptions), options), function (error) {
if (error) {
reject(error);
}
});
resolve(newPublisher);
}).then(function (newPublisher) {
return new Promise(function (resolve, reject) {
session.publish(newPublisher, function (error) {
if (error) {
reject(error);
} else {
action.setPublisher({
name: name,
publisher: newPublisher
});
action.addStream(newPublisher.stream);
resolve(newPublisher.stream);
}
});
});
});
}, [action, publisher, session]);
var unpublish = react.useCallback(function (_ref8) {
var name = _ref8.name;
if (!(publisher && publisher[name])) {
throw new Error("[ReactUseOpenTok] unpublish: publisher[".concat(name, "] is undefined"));
}
var stream = publisher && publisher[name] && publisher[name].stream;
session.unpublish(publisher[name]);
action.removePublisher({
name: name
});
action.removeStream(stream);
}, [action, publisher, session]);
var subscribe = react.useCallback(function (_ref9) {
var stream = _ref9.stream,
element = _ref9.element,
options = _ref9.options;
var subscriber = session.subscribe(stream, element, _objectSpread$1(_objectSpread$1({}, defaultOptions), options));
action.addSubscriber(subscriber);
return subscriber;
}, [action, session]);
var unsubscribe = react.useCallback(function (_ref10) {
var stream = _ref10.stream;
var streamId = stream.streamId;
var subscriber = subscribers.find(function (subscriber) {
return subscriber.streamId === streamId;
});
session.unsubscribe(subscriber);
action.removeSubscriber(subscriber);
}, [action, session, subscribers]);
var sendSignal = react.useCallback(function (_ref11) {
var type = _ref11.type,
data = _ref11.data,
to = _ref11.to,
completionHandler = _ref11.completionHandler;
if (!isSessionConnected) {
throw new Error('[ReactUseOpenTok] sendSignal: Session is not connected');
}
var signal = _objectSpread$1(_objectSpread$1({
data: data
}, type && {
type: type
}), to && {
to: to
});
session.signal(signal, function (error) {
if (error) {
throw new Error('[ReactUseOpenTok] sendSignal error: ' + error.message);
} else if (typeof completionHandler === 'function') {
completionHandler();
}
});
}, [isSessionConnected, session]);
useSessionEventHandler('connectionCreated', handleConnectionCreated, session);
useSessionEventHandler('connectionDestroyed', handleConnectionDestroyed, session);
useSessionEventHandler('streamCreated', handleStreamCreated, session);
useSessionEventHandler('streamDestroyed', handleStreamDestroyed, session);
return [state, {
initSessionAndConnect: initSessionAndConnect,
initSession: initSession,
connectSession: connectSession,
disconnectSession: disconnectSession,
initPublisher: initPublisher,
removePublisher: removePublisher,
publishPublisher: publishPublisher,
publish: publish,
unpublish: unpublish,
subscribe: subscribe,
unsubscribe: unsubscribe,
sendSignal: sendSignal
}];
};
module.exports = useOpenTok;
//# sourceMappingURL=react-use-opentok.cjs.js.map
;