agora-react-native-rtm
Version:
React Native around the Agora RTM SDKs for Android and iOS agora
311 lines (299 loc) • 9.13 kB
JavaScript
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.RequestQueue = exports.EVENT_TYPE = exports.EVENT_PROCESSORS = exports.DeviceEventEmitter = void 0;
exports.callIrisApi = callIrisApi;
exports.emitEvent = emitEvent;
exports.handleError = handleError;
exports.isDebuggable = isDebuggable;
exports.setDebuggable = setDebuggable;
exports.wrapRtmResult = wrapRtmResult;
var _buffer = require("buffer");
var _base64Js = _interopRequireDefault(require("base64-js"));
var _eventemitter = _interopRequireDefault(require("eventemitter3"));
var _reactNative = require("react-native");
var _RTMEvents = require("../api/RTMEvents");
var _specs = _interopRequireDefault(require("../specs"));
var _RtmClientInternal = require("./RtmClientInternal");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// Request queue for handling async operations
class RequestQueue {
_requestMap = new Map();
constructor() {}
static get instance() {
if (!RequestQueue._instance) {
RequestQueue._instance = new RequestQueue();
}
return RequestQueue._instance;
}
addRequest(callbackName, timeoutMs, externalRequestId) {
const requestId = externalRequestId;
let promiseResolve;
let promiseReject;
const promise = new Promise((resolve, reject) => {
promiseResolve = resolve;
promiseReject = reject;
});
promise.requestId = requestId;
let timeout;
if (timeoutMs > 0) {
timeout = setTimeout(() => {
const item = this._requestMap.get(requestId);
if (item) {
this._requestMap.delete(requestId);
console.log(`Request timeout: ${requestId}`);
item.reject(new Error(`Request ${requestId} timed out after ${timeoutMs}ms`));
}
}, timeoutMs);
}
this._requestMap.set(requestId, {
resolve: promiseResolve,
reject: promiseReject,
callbackName,
timeout
});
return promise;
}
resolveRequest(requestId, errorCode, callbackName, ...args) {
const request = this._requestMap.get(requestId);
if (!request) {
console.log(`Request not found: ${requestId}`);
return false;
}
// Check if callback name matches
if (request.callbackName !== callbackName) {
console.log(`Callback name mismatch: expected ${request.callbackName}, actual ${callbackName}`);
return false;
}
console.log(`Resolving request: ${requestId}, callback: ${callbackName}, error code: ${errorCode}`);
if (request.timeout) {
clearTimeout(request.timeout);
}
this._requestMap.delete(requestId);
if (errorCode === 0) {
request.resolve(...args);
} else {
request.reject(...args);
}
return true;
}
}
exports.RequestQueue = RequestQueue;
// @ts-ignore
const DeviceEventEmitter = exports.DeviceEventEmitter = new _eventemitter.default();
const AgoraEventEmitter = new _reactNative.NativeEventEmitter(_specs.default);
AgoraEventEmitter.addListener('AgoraRtmNg:onEvent', handleEvent);
let debuggable = false;
/**
* @internal
*/
function setDebuggable(flag) {
debuggable = flag;
}
/**
* @internal
*/
function isDebuggable() {
return debuggable && __DEV__;
}
/**
* @internal
*/
let EVENT_TYPE = exports.EVENT_TYPE = /*#__PURE__*/function (EVENT_TYPE) {
EVENT_TYPE[EVENT_TYPE["RTMEvent"] = 0] = "RTMEvent";
return EVENT_TYPE;
}({});
/**
* @internal
*/
const EVENT_PROCESSORS = exports.EVENT_PROCESSORS = {
RTMClientEventMap: {
suffix: 'RtmEventHandler_',
type: () => EVENT_TYPE.RTMEvent,
func: [_RTMEvents.processRTMClientEventMap],
handlers: () => _RtmClientInternal.RtmClientInternal._event_handlers,
preprocess: (event, data, buffers) => {
var _buffers$;
switch (event) {
case 'onMessageEvent':
console.log('onMessageEvent', data.event.message, buffers);
data.event.message = (_buffers$ = buffers[0]) === null || _buffers$ === void 0 ? void 0 : _buffers$.toString();
break;
}
return {
event,
data,
buffers
};
}
}
};
function handleEvent({
event,
data,
buffers
}) {
if (debuggable) {
console.info('onEvent', event, data, buffers);
}
let _data;
try {
_data = JSON.parse(data) ?? {};
} catch (e) {
_data = {};
}
let _event = event;
let processor = EVENT_PROCESSORS.RTMClientEventMap;
Object.values(EVENT_PROCESSORS).some(it => {
const p = it;
if (_event.startsWith(p.suffix) && processor.handlers(_data) !== undefined) {
processor = p;
const reg = new RegExp(`^${processor.suffix}`, 'g');
_event = _event.replace(reg, '');
return true;
}
return false;
});
// for new IrisType, but this is temporary
if (_event.includes('_')) {
_event = _event.substring(0, _event.indexOf('_'));
}
const _buffers = buffers === null || buffers === void 0 ? void 0 : buffers.map(value => {
return _buffer.Buffer.from(value, 'base64');
});
if (processor.preprocess) {
processor.preprocess(_event, _data, _buffers);
}
if (processor.handlers) {
var _processor$handlers;
(_processor$handlers = processor.handlers(_data)) === null || _processor$handlers === void 0 || _processor$handlers.map(value => {
if (value) {
processor.func.map(it => {
it(value, _event, _data);
});
}
});
}
const requestId = _data.requestId;
if (requestId !== undefined && _data.errorCode !== undefined) {
const requestQueue = RequestQueue.instance;
requestQueue.resolveRequest(requestId, _data.errorCode, _event, _data);
}
emitEvent(_event, processor, _data);
}
/**
* @internal
*/
function callIrisApi(funcName, params) {
try {
const buffers = [];
if (funcName.startsWith('StreamChannel_')) {
var _params$toJSON;
params.channelName = this.channelName;
const json = (_params$toJSON = params.toJSON) === null || _params$toJSON === void 0 ? void 0 : _params$toJSON.call();
params.toJSON = function () {
return {
...json,
channelName: params.channelName
};
};
}
if (funcName === 'RtmClient_publish_2d36e93' || funcName === 'StreamChannel_publishTopicMessage_a31773e') {
var _params$toJSON2;
if (typeof params.message === 'string') {
let uint8Array = new Uint8Array(_buffer.Buffer.from(params.message));
let buffer = _base64Js.default.fromByteArray(uint8Array);
console.log(uint8Array, buffer);
buffers.push(buffer);
params.length = _base64Js.default.byteLength(buffer);
} else {
let buffer = _base64Js.default.fromByteArray(params.message);
console.log(params.message, buffer);
buffers.push(buffer);
params.length = _base64Js.default.byteLength(buffer);
}
delete params.message;
const json = (_params$toJSON2 = params.toJSON) === null || _params$toJSON2 === void 0 ? void 0 : _params$toJSON2.call();
delete json.message;
params.toJSON = function () {
return {
...json,
length: params.length
};
};
}
// RTM_ERROR_DUPLICATE_OPERATION
if (funcName === 'RtmClient_create') {
_specs.default.newIrisRtmEngine();
}
let ret = _specs.default.callApi({
funcName,
params: JSON.stringify(params),
buffers
});
if (funcName === 'RtmClient_release') {
_specs.default.destroyIrisRtmEngine();
}
if (ret !== undefined && ret !== null && ret !== '' && ret !== 'null') {
const retObj = JSON.parse(ret);
if (isDebuggable()) {
if (typeof retObj.result === 'number' && retObj.result < 0) {
console.error('callApi', funcName, JSON.stringify(params), ret);
} else {
console.log('callApi', funcName, JSON.stringify(params), ret);
}
}
return retObj;
}
} catch (e) {
if (isDebuggable()) {
console.error('callApi', funcName, JSON.stringify(params), e);
} else {
console.warn('callApi', funcName, JSON.stringify(params), e);
}
}
return {};
}
/**
* @internal
*/
function emitEvent(eventType, eventProcessor, data) {
DeviceEventEmitter.emit(eventType, eventProcessor, data);
}
/**
* @internal
*/
async function wrapRtmResult(data, operation, callbackName, withCallbackResult = false) {
if (data.result < 0) {
throw {
error: true,
reason: 'iris call failed',
operation,
errorCode: data.result
};
} else {
let result = await RequestQueue.instance.addRequest(callbackName, 60000, data.requestId);
if (withCallbackResult) {
result = (0, _RTMEvents.cleanIrisExtraData)(result);
}
return {
timestamp: 0,
...(withCallbackResult ? {
callBackResult: result
} : {})
};
}
}
/**
* @internal
*/
function handleError(data, operation) {
return {
error: true,
reason: data,
operation: operation,
errorCode: data === null || data === void 0 ? void 0 : data.errorCode
};
}
//# sourceMappingURL=IrisRtmEngine.js.map
;