We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
const callerMap = {}; function getCaller(error) { if (error && error.stack) { const lines = error.stack.split('\n'); if (lines.length > 2) { let match = lines[2].match(/at ([a-zA-Z\-_$.]+) (.*)/); if (match) { return { name: match[1].replace(/^Proxy\./, ''), file: match[2], }; } else { match = lines[2].match(/at (.*)/); if (match) { return { name: 'unknown', file: match[1], }; } } } } return { name: 'unknown', file: '', }; } function getFunctionName(fn, context) { let contextName = ''; if (typeof context === 'function') { contextName = `{context.name}.`; } else if (context && context.constructor && context.constructor.name !== 'Object') { contextName = `${context.constructor.name}.`; } return `${contextName}${fn.name}`; } function trackFunctionCall(options = {}) { return function(target, thisArg, argumentsList) { const { trackTime, trackCaller, trackCount, stdout, filter } = options; const error = trackCaller && new Error(); const caller = getCaller(error); const name = getFunctionName(target, thisArg); if (trackCount) { if (!callerMap[name]) { callerMap[name] = 1; } else { callerMap[name]++; } } let start, end; if (trackTime) { start = Date.now(); } const retVal = target.apply(thisArg, argumentsList); if (trackTime) { end = Date.now(); } let output = `${name} was called`; if (trackCaller) { output += ` by ${caller.name}`; } if (trackCount) { output += ` for the ${callerMap[name]} time`; } if (trackTime) { output += ` and took ${end-start} mils.`; } let canReport = true; if (filter) { canReport = filter({ type: 'function', name, caller, count: callerMap[name], time: end - start, }); } if (canReport) { if (stdout) { stdout(output); } else { console.log(output); } } return retVal; }; } function trackPropertySet(options = {}) { return function set(target, prop, value, receiver) { const { trackCaller, trackCount, stdout, filter } = options; const error = trackCaller && new Error(); const caller = getCaller(error); const contextName = target.constructor.name === 'Object' ? '' : `${target.constructor.name}.`; const name = `${contextName}${prop}`; const hashKey = `set_${name}`; if (trackCount) { if (!callerMap[hashKey]) { callerMap[hashKey] = 1; } else { callerMap[hashKey]++; } } let output = `${name} is being set`; if (trackCaller) { output += ` by ${caller.name}`; } if (trackCount) { output += ` for the ${callerMap[hashKey]} time`; } let canReport = true; if (filter) { canReport = filter({ type: 'get', prop, name, caller, count: callerMap[hashKey], value, }); } if (canReport) { if (stdout) { stdout(output); } else { console.log(output); } } return Reflect.set(target, prop, value, receiver); }; } function trackPropertyGet(options = {}) { return function get(target, prop, receiver) { const { trackCaller, trackCount, stdout, filter } = options; if (typeof target[prop] === 'function' || prop === 'prototype') { return target[prop]; } const error = trackCaller && new Error(); const caller = getCaller(error); const contextName = target.constructor.name === 'Object' ? '' : `${target.constructor.name}.`; const name = `${contextName}${prop}`; const hashKey = `get_${name}`; if (trackCount) { if (!callerMap[hashKey]) { callerMap[hashKey] = 1; } else { callerMap[hashKey]++; } } let output = `${name} is being get`; if (trackCaller) { output += ` by ${caller.name}`; } if (trackCount) { output += ` for the ${callerMap[hashKey]} time`; } let canReport = true; if (filter) { canReport = filter({ type: 'get', prop, name, caller, count: callerMap[hashKey], }); } if (canReport) { if (stdout) { stdout(output); } else { console.log(output); } } return target[prop]; }; } function proxyFunctions(trackedEntity, options) { if (typeof trackedEntity === 'function') return; Object.getOwnPropertyNames(trackedEntity).forEach((name) => { if (typeof trackedEntity[name] === 'function') { trackedEntity[name] = new Proxy(trackedEntity[name], { apply: trackFunctionCall(options), }); } }); } function trackObject(obj, options = {}) { const { trackFunctions, trackProps } = options; let resultObj = obj; if (trackFunctions) { proxyFunctions(resultObj, options); } if (trackProps) { resultObj = new Proxy(resultObj, { get: trackPropertyGet(options), set: trackPropertySet(options), }); } return resultObj; } const defaultOptions = { trackFunctions: true, trackProps: true, trackTime: true, trackCaller: true, trackCount: true, filter: null, }; function trackClass(cls, options = {}) { cls.prototype = trackObject(cls.prototype, options); cls.prototype.constructor = cls; return new Proxy(cls, { construct(target, args) { const obj = new target(...args); return new Proxy(obj, { get: trackPropertyGet(options), set: trackPropertySet(options), }); }, apply: trackFunctionCall(options), }); } function proxyTrack(entity, options = defaultOptions) { if (typeof entity === 'function') return trackClass(entity, options); return trackObject(entity, options); } module.exports = proxyTrack; class A { constructor(name) { this.name = name; } getMyName() { return this.name; } setMyName(newName) { this.name = newName; } } const ProxyedA = proxyTrack(A); const aInstance = new ProxyedA('wangning.frontend'); const name = aInstance.getMyName(); console.log(name); aInstance.setMyName('wangning'); const newName = aInstance.getMyName(); console.log(newName);
The text was updated successfully, but these errors were encountered:
No branches or pull requests
The text was updated successfully, but these errors were encountered: