Skip to content

Instantly share code, notes, and snippets.

@nikolaskhodov
Last active October 16, 2025 23:09
Show Gist options
  • Select an option

  • Save nikolaskhodov/b5f2c9a0019065e4abe4acd04effa51d to your computer and use it in GitHub Desktop.

Select an option

Save nikolaskhodov/b5f2c9a0019065e4abe4acd04effa51d to your computer and use it in GitHub Desktop.
Instrument a pre-call function hook in JS
export function instrumentPreObjectFunctionCallHook(obj, methodName, hookFn) {
const originalMethod = obj[methodName];
obj[methodName] = (...args) => {
const result = hookFn({ args, obj, methodName });
return result instanceof Promise
? result.then(() => originalMethod.call(obj, args))
: originalMethod.call(obj, args);
};
return obj[methodName].__deinstrument = () => {
obj[methodName] = originalMethod;
};
}
export function instrumentPostObjectFunctionCallHook(obj, methodName, hookFn) {
const originalMethod = obj[methodName];
obj[methodName] = (...args) => {
const result = originalMethod.call(obj, args);
return result instanceof Promise
? result.then((_result) => hookFn({ args, obj, methodName, result: _result }))
: hookFn({ args, obj, methodName, result });
};
return obj[methodName].__deinstrument = () => {
obj[methodName] = originalMethod;
};
}
export function instrumentPreMethodCallHook(func, hookFn) {
return (...args) => {
const result = hookFn({ args, func });
return result instanceof Promise
? result.then(() => func(...args))
: func(...args);
};
}
export function instrumentPostMethodCallHook(func, hookFn) {
return (...args) => {
const result = func(...args);
return result instanceof Promise
? result.then((_result) => hookFn({ args, func, result: _result }))
: hookFn({ args, func, result });
};
}
export function instrumentPreObjectFunctionCallHook(
obj: any,
methodName: string,
hookFn: (props: { args: any[]; obj: any; methodName: string }) => any
) {
const originalMethod = obj[methodName];
obj[methodName] = (...args: any[]): any => {
const result = hookFn({ args, obj, methodName });
return result instanceof Promise
? result.then(() => originalMethod.call(obj, args))
: originalMethod.call(obj, args);
};
return obj[methodName].__deinstrument = () => {
obj[methodName] = originalMethod;
};
}
export function instrumentPostObjectFunctionCallHook(
obj: any,
methodName: string,
hookFn: (props: {
args: any[];
obj: any;
methodName: string;
result: any;
}) => any
) {
const originalMethod = obj[methodName];
obj[methodName] = (...args: any[]): any => {
const result = originalMethod.call(obj, args);
return result instanceof Promise
? result.then((_result) =>
hookFn({ args, obj, methodName, result: _result })
)
: hookFn({ args, obj, methodName, result });
};
return obj[methodName].__deinstrument = () => {
obj[methodName] = originalMethod;
};
}
export function instrumentPreMethodCallHook(
func: (...args: any[]) => any,
hookFn: (props: { args: any[]; func: Function }) => any
) {
return (...args: any[]): any => {
const result = hookFn({ args, func });
return result instanceof Promise
? result.then(() => func(...args))
: func(...args);
};
}
export function instrumentPostMethodCallHook(
func: (...args: any[]) => any,
hookFn: (props: { args: any[]; func: Function; result: any }) => any
) {
return (...args: any[]): any => {
const result = func(...args);
return result instanceof Promise
? result.then((_result) => hookFn({ args, func, result: _result }))
: hookFn({ args, func, result });
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment