react-native-xenon
Version:
A powerful in-app debugging tool for React Native.
97 lines (96 loc) • 4.55 kB
JavaScript
;
var _class, _class2;
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; }
import { NativeEventEmitter, TurboModuleRegistry } from 'react-native';
import { frozen, singleton } from "../core/utils.js";
import { NetworkInterceptor } from "./NetworkInterceptor.js";
const NativeWebSocketModule = TurboModuleRegistry.getEnforcing('WebSocketModule');
const originalWebSocketConnect = NativeWebSocketModule.connect;
const originalWebSocketSend = NativeWebSocketModule.send;
const originalWebSocketSendBinary = NativeWebSocketModule.sendBinary;
const originalWebSocketClose = NativeWebSocketModule.close;
let WebSocketInterceptor = singleton(_class = (_class2 = class WebSocketInterceptor extends NetworkInterceptor {
handlers = {
connect: null,
send: null,
close: null,
onOpen: null,
onMessage: null,
onError: null,
onClose: null
};
eventEmitter = null;
subscriptions = [];
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 => {
this.handlers.onOpen?.(ev.id, Date.now());
}), 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 NativeEventEmitter(NativeWebSocketModule);
this.registerEvents();
const {
connectCallback,
sendCallback,
closeCallback
} = this.getCallbacks();
NativeWebSocketModule.connect = function (...args) {
connectCallback?.(Date.now(), ...args);
originalWebSocketConnect.call(this, ...args);
};
NativeWebSocketModule.send = function (...args) {
sendCallback?.(...args);
originalWebSocketSend.call(this, ...args);
};
const arrayBufferToString = this.arrayBufferToString;
NativeWebSocketModule.sendBinary = function (base64String, socketId) {
sendCallback?.(arrayBufferToString(base64String), socketId);
originalWebSocketSendBinary.call(this, base64String, socketId);
};
NativeWebSocketModule.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.connect = originalWebSocketConnect;
NativeWebSocketModule.send = originalWebSocketSend;
NativeWebSocketModule.sendBinary = originalWebSocketSendBinary;
NativeWebSocketModule.close = originalWebSocketClose;
this.clearCallbacks();
this.unregisterEvents();
}
}, _applyDecoratedDescriptor(_class2.prototype, "enableInterception", [frozen], Object.getOwnPropertyDescriptor(_class2.prototype, "enableInterception"), _class2.prototype), _applyDecoratedDescriptor(_class2.prototype, "disableInterception", [frozen], Object.getOwnPropertyDescriptor(_class2.prototype, "disableInterception"), _class2.prototype), _class2)) || _class;
export { WebSocketInterceptor as default };
//# sourceMappingURL=WebSocketInterceptor.js.map