react-native-xenon
Version:
A powerful in-app debugging tool for React Native.
108 lines (107 loc) • 5.13 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _reactNative = require("react-native");
var _NativeWebSocketModule = _interopRequireDefault(require("react-native/Libraries/WebSocket/NativeWebSocketModule"));
var _utils = require("../core/utils");
var _NetworkInterceptor = require("./NetworkInterceptor");
var _class, _class2;
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _applyDecoratedDescriptor(i, e, r, n, l) { var a = {}; return Object.keys(n).forEach(function (i) { a[i] = n[i]; }), a.enumerable = !!a.enumerable, a.configurable = !!a.configurable, ("value" in a || a.initializer) && (a.writable = !0), a = r.slice().reverse().reduce(function (r, n) { return n(i, e, r) || r; }, a), l && void 0 !== a.initializer && (a.value = a.initializer ? a.initializer.call(l) : void 0, a.initializer = void 0), void 0 === a.initializer ? (Object.defineProperty(i, e, a), null) : a; }
const originalWebSocketConnect = _NativeWebSocketModule.default.connect;
const originalWebSocketSend = _NativeWebSocketModule.default.send;
const originalWebSocketSendBinary = _NativeWebSocketModule.default.sendBinary;
const originalWebSocketClose = _NativeWebSocketModule.default.close;
let WebSocketInterceptor = exports.default = (0, _utils.singleton)(_class = (_class2 = class WebSocketInterceptor extends _NetworkInterceptor.NetworkInterceptor {
handlers = {
connect: null,
send: null,
close: null,
onOpen: null,
onMessage: null,
onError: null,
onClose: null
};
eventEmitter = null;
subscriptions = [];
startTimes = new Map();
arrayBufferToString(data) {
try {
if (!data) return '(no input)';
const byteArray = Buffer.from(data, 'base64');
if (byteArray.length === 0) return '(empty array)';
return `ArrayBuffer { length: ${byteArray.length}, values: [${byteArray.join(', ')}] }`;
} catch (error) {
return `(invalid data: ${error instanceof Error ? error.message : error})`;
}
}
registerEvents() {
if (!this.eventEmitter) return;
this.subscriptions = [this.eventEmitter.addListener('websocketOpen', ev => {
const startTime = this.startTimes.get(ev.id);
const endTime = Date.now();
const duration = endTime - (startTime ?? 0);
this.startTimes.delete(ev.id);
this.handlers.onOpen?.(ev.id, duration);
}), this.eventEmitter.addListener('websocketMessage', ev => {
this.handlers.onMessage?.(ev.id, ev.type === 'binary' ? this.arrayBufferToString(ev.data) : ev.data);
}), this.eventEmitter.addListener('websocketClosed', ev => {
this.handlers.onClose?.(ev.id, {
code: ev.code,
reason: ev.reason
});
}), this.eventEmitter.addListener('websocketFailed', ev => {
this.handlers.onError?.(ev.id, {
message: ev.message
});
})];
}
unregisterEvents() {
this.subscriptions.forEach(e => e.remove());
this.subscriptions = [];
this.eventEmitter = null;
}
enableInterception() {
if (this.isInterceptorEnabled) return;
this.eventEmitter = new _reactNative.NativeEventEmitter(_NativeWebSocketModule.default);
this.registerEvents();
const {
connectCallback,
sendCallback,
closeCallback
} = this.getCallbacks();
const startTimes = this.startTimes;
_NativeWebSocketModule.default.connect = function (...args) {
connectCallback?.(...args);
startTimes.set(args[3], Date.now());
originalWebSocketConnect.call(this, ...args);
};
_NativeWebSocketModule.default.send = function (...args) {
sendCallback?.(...args);
originalWebSocketSend.call(this, ...args);
};
const arrayBufferToString = this.arrayBufferToString;
_NativeWebSocketModule.default.sendBinary = function (base64String, socketId) {
sendCallback?.(arrayBufferToString(base64String), socketId);
originalWebSocketSendBinary.call(this, base64String, socketId);
};
_NativeWebSocketModule.default.close = function (code, reason, socketId) {
closeCallback?.(code, reason, socketId);
originalWebSocketClose.call(this, code, reason, socketId);
};
this.isInterceptorEnabled = true;
}
disableInterception() {
if (!this.isInterceptorEnabled) return;
this.isInterceptorEnabled = false;
_NativeWebSocketModule.default.connect = originalWebSocketConnect;
_NativeWebSocketModule.default.send = originalWebSocketSend;
_NativeWebSocketModule.default.sendBinary = originalWebSocketSendBinary;
_NativeWebSocketModule.default.close = originalWebSocketClose;
this.clearCallbacks();
this.unregisterEvents();
}
}, _applyDecoratedDescriptor(_class2.prototype, "enableInterception", [_utils.frozen], Object.getOwnPropertyDescriptor(_class2.prototype, "enableInterception"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "disableInterception", [_utils.frozen], Object.getOwnPropertyDescriptor(_class2.prototype, "disableInterception"), _class2.prototype), _class2)) || _class;
//# sourceMappingURL=WebSocketInterceptor.js.map