Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | 2x 2x 2x 2x 1322x 1322x 1322x 1322x 1322x 1322x 1322x 330x 171x 330x 1x 1x 1x 168x 168x 164x 330x 4x 4x 1322x 1322x 333x 163x 163x 329x 2x 329x 159x 159x 161x 1322x 1322x 1322x 2914x 59x 160x 160x 160x 160x 160x 160x 59x 59x 2914x 2914x 1322x 3016x 3016x 3016x 3016x 3016x 3016x 1322x 14881x 14791x 14791x 11911x 14881x 84x 84x 84x 90x 14881x 1322x | import { transformSendDeserializeType, transformSendRecursive } from './utils/changeType.js';
import { v4 as uuid } from 'uuid';
import { NetworkEventListener } from '../../utils/NetworkEventListener.js';
import { PerfectWSError } from '../../PerfectWSError.js';
export class TransformCallbacks {
private _functions: [string, any][] = [];
private _activeRequests = new Map<string, { resolve: (data: any) => void, reject: (error: any) => void; }>();
constructor(private _events: NetworkEventListener, private _maxDepth: number = 100) {
this._registerEvents();
}
private _registerEvents() {
this._events.on('___callback.request', async (source, { args, funcId, requestId }) => {
if (source === 'local') return;
const func = this._functions.find(([localFuncId]) => localFuncId === funcId)?.[1];
if (!func) {
this._events.emit('___callback.response', { error: 'Method not found', requestId });
return;
}
try {
const response = await func(...args);
this._events.emit('___callback.response', { data: response, requestId });
} catch (error: any) {
this._events.emit('___callback.response', { error: error.message || error, requestId });
}
});
this._events.on('___callback.response', (source, { data, error, requestId }) => {
if (source === 'local') return;
const request = this._activeRequests.get(requestId);
if (!request) return;
if (error) {
request.reject(new PerfectWSError(error, 'callbackError'));
} else {
request.resolve(data);
}
this._activeRequests.delete(requestId);
});
}
deserialize(data: any) {
return transformSendDeserializeType(data, 'callback', found => {
const func = (...args: any[]) => {
const requestId = uuid();
this._events.emit('___callback.request', { args, funcId: found.funcId, requestId });
return new Promise((resolve, reject) => {
this._activeRequests.set(requestId, { resolve, reject });
});
};
Object.defineProperty(func, 'name', { value: found.funcName });
return func;
}, this._maxDepth);
}
serialize(obj: any) {
return transformSendRecursive(obj, {
maxDepth: this._maxDepth,
processingDataType: (data) => typeof data === 'object' && data !== null || typeof data === 'function',
transformData: (data) => this._serializeFunction(data)
});
}
private _serializeFunction(func: any) {
if(typeof func !== 'function') {
return null;
}
let hasFunc = this._functions.find(([_, fn]) => fn === func)?.[0];
if (!hasFunc) {
hasFunc = uuid();
this._functions.push([hasFunc, func]);
}
return { ___type: 'callback', funcId: hasFunc, funcName: func.name }
}
}
|