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 2884x 59x 160x 160x 160x 160x 160x 160x 59x 59x 2884x 2884x 1322x 2986x 2986x 2986x 2986x 2986x 2986x 1322x 14789x 14699x 14699x 11839x 14789x 84x 84x 84x 90x 14789x 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 }
}
}
|