Sylvain Filoni
update gradio client
9ada4bc
import { findPropertySource } from './findPropertySource'
export interface ProxyOptions<Target extends Record<string, any>> {
constructorCall?(args: Array<unknown>, next: NextFunction<Target>): Target
methodCall?<F extends keyof Target>(
this: Target,
data: [methodName: F, args: Array<unknown>],
next: NextFunction<void>
): void
setProperty?(
data: [propertyName: string | symbol, nextValue: unknown],
next: NextFunction<boolean>
): boolean
getProperty?(
data: [propertyName: string | symbol, receiver: Target],
next: NextFunction<void>
): void
}
export type NextFunction<ReturnType> = () => ReturnType
export function createProxy<Target extends object>(
target: Target,
options: ProxyOptions<Target>
): Target {
const proxy = new Proxy(target, optionsToProxyHandler(options))
return proxy
}
function optionsToProxyHandler<T extends Record<string, any>>(
options: ProxyOptions<T>
): ProxyHandler<T> {
const { constructorCall, methodCall, getProperty, setProperty } = options
const handler: ProxyHandler<T> = {}
if (typeof constructorCall !== 'undefined') {
handler.construct = function (target, args, newTarget) {
const next = Reflect.construct.bind(null, target as any, args, newTarget)
return constructorCall.call(newTarget, args, next)
}
}
handler.set = function (target, propertyName, nextValue) {
const next = () => {
const propertySource = findPropertySource(target, propertyName) || target
const ownDescriptors = Reflect.getOwnPropertyDescriptor(
propertySource,
propertyName
)
// Respect any custom setters present for this property.
if (typeof ownDescriptors?.set !== 'undefined') {
ownDescriptors.set.apply(target, [nextValue])
return true
}
// Otherwise, set the property on the source.
return Reflect.defineProperty(propertySource, propertyName, {
writable: true,
enumerable: true,
configurable: true,
value: nextValue,
})
}
if (typeof setProperty !== 'undefined') {
return setProperty.call(target, [propertyName, nextValue], next)
}
return next()
}
handler.get = function (target, propertyName, receiver) {
/**
* @note Using `Reflect.get()` here causes "TypeError: Illegal invocation".
*/
const next = () => target[propertyName as any]
const value =
typeof getProperty !== 'undefined'
? getProperty.call(target, [propertyName, receiver], next)
: next()
if (typeof value === 'function') {
return (...args: Array<any>) => {
const next = value.bind(target, ...args)
if (typeof methodCall !== 'undefined') {
return methodCall.call(target, [propertyName as any, args], next)
}
return next()
}
}
return value
}
return handler
}