proxy-vir
Version:
An easier Proxy.
109 lines (108 loc) • 4.33 kB
TypeScript
import { type AnyFunction, type AnyObject, type PartialWithUndefined } from '@augment-vir/common';
import { type RequireExactlyOne } from 'type-fest';
/**
* Options for creating a new proxy wrapper.
*
* @category Internal
*/
export type CreateProxyOptions<ProxyType> = {
/**
* Indicates if this proxy is meant to be callable, or, in other words, if this proxy is meant
* to proxy a function rather than just an object.
*/
isCallable: boolean;
/**
* Indicates if the proxy should not be extensible. By default they are extensible, so set this
* to true to change that behavior. Read JavaScript docs for "Object.isExtensible()" to
* understand what being extensible means:
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible
*/
isNotExtensible: boolean;
} & RequireExactlyOne<{
/** Initial Target to wrap */
initialTarget: Partial<ProxyType>;
/** Initial Targets to wrap, in priority order */
initialTargets: ReadonlyArray<Partial<ProxyType>>;
}>;
/**
* Base type for a proxy target.
*
* @category Internal
*/
export type ProxyTypeBase = AnyObject | AnyFunction;
/**
* An interface for modifying a proxy after the fact.
*
* @category Main
*/
export type MultiTargetProxyModifier<ProxyType extends ProxyTypeBase> = {
/**
* Add a target to the internal list of prioritized targets. Since this will be a fallback
* target, a property from this target will only be used if no previously added target already
* has the property.
*/
addFallbackTarget(target: Partial<ProxyType>): void;
/**
* Add a target to the internal list of prioritized targets. Since this will be an override
* target, a property from this target will always be used unless a new override target with the
* same property is added or if the properties are modified on the proxy itself.
*/
addOverrideTarget(target: Partial<ProxyType>): void;
/** Remove the given target from the internal list of prioritized targets. */
removeTarget(target: Partial<ProxyType>): boolean;
/**
* Get a list of all internal targets, in priority order. This is mostly only useful for
* debugging purposes.
*/
getAllTargets(): ReadonlyArray<Partial<ProxyType>>;
/**
* Add a new proxy handler. Since this will be an override handler, a method from this handler
* will always be used unless a new override handler with the same method is added or if the
* methods are modified on the handler object itself.
*/
addProxyHandlerOverride(handlerOverride: ProxyHandler<ProxyType>): void;
/**
* Add a new proxy handler. Since this will be a fallback handler, a method from this handler
* will only be used if no previously added override already has the method.
*/
addProxyHandlerFallback(handlerOverride: ProxyHandler<ProxyType>): void;
/** Remove the given proxy handler override from the internal list of proxy handler overrides. */
removeProxyOverride(handlerOverride: ProxyHandler<ProxyType>): boolean;
};
/**
* A proxy wrapper which allows performing multiple operations on the proxy to modify it after the
* fact (with `.proxyModifier`), such as merging multiple proxies together or adding new proxy
* handler methods.
*
* @category Main
*/
export type WrappedMultiTargetProxy<ProxyType extends ProxyTypeBase> = {
proxy: ProxyType;
proxyModifier: MultiTargetProxyModifier<ProxyType>;
};
/**
* Create an instance of {@link WrappedMultiTargetProxy} which can be used to merge multiple targets
* together or override proxy handler methods.
*
* @category Main
* @example
*
* ```ts
* import {createWrappedMultiTargetProxy} from 'proxy-vir';
*
* // something you imported from a 3rd party library that you want to wrap
* const importedThing = {
* doThingA() {},
* };
*
* const thingWrapper = createWrappedMultiTargetProxy({
* initialTarget: importedThing,
* });
*
* // add a new override
* thingWrapper.proxyModifier.addOverrideTarget({
* doThingA() {},
* });
* ```
*/
export declare function createWrappedMultiTargetProxy<ProxyType extends ProxyTypeBase>(options?: PartialWithUndefined<CreateProxyOptions<ProxyType>> | undefined): WrappedMultiTargetProxy<ProxyType>;