@politie/sherlock-proxy
Version:
A proxy extension to Sherlock.
146 lines (145 loc) • 6.77 kB
TypeScript
import { Derivable, ReactorOptions } from '@politie/sherlock';
/**
* The base interface for DerivableProxies. Defines only the $-properties and $-methods. Any property accessed with a number or
* that doesn't start with a $-sign returns a new DerivableProxy.
*/
export interface DerivableProxy<V> {
/** The current value that this Proxy represents. Can be expensive to calculate and is often writable. */
$value: V;
/** A string representation of this proxy's path from the root ProxyDescriptor. */
$expression?: string;
/**
* An array representation of this proxy's path from the root ProxyDescriptor. Useful for programatically walking down the root
* Descriptor's object tree to reacquire a target proxy.
*/
$path?: Array<string | number>;
/** {@see Derivable#and} */
$and<W>(other: MaybePacked<W>): Derivable<V | W>;
/** {@see Derivable#or} */
$or<W>(other: MaybePacked<W>): Derivable<V | W>;
/** {@see Derivable#not} */
$not(): Derivable<boolean>;
/** {@see Derivable#is} */
$is(other: MaybePacked<any>): Derivable<boolean>;
/** {@see Derivable#derive} */
$derive<R>(f: (v: V) => R): Derivable<R>;
$derive<R, P1>(f: (v: V, p1: P1) => R, p1: MaybePacked<P1>): Derivable<R>;
$derive<R, P1, P2>(f: (v: V, p1: P1, p2: P2) => R, p1: MaybePacked<P1>, p2: MaybePacked<P2>): Derivable<R>;
$derive<R, P>(f: (v: V, ...ps: P[]) => R, ...ps: Array<MaybePacked<P>>): Derivable<R>;
/** {@see Derivable#react} */
$react(reaction: (value: V, stop: () => void) => void, options?: Partial<ReactorOptions<V>>): () => void;
}
/**
* Returns whether obj is a DerivableProxy.
*
* @param obj the object to test
*/
export declare function isDerivableProxy(obj: any): obj is DerivableProxy<any>;
/**
* A ProxyDescriptor must be used to create DerivableProxies. It can be used in two ways, either create a new descriptor and
* change any implementation details (if needed) or create a subclass to extend the behavior. Use the {@link #$create} method
* to create a DerivableProxy.
*
* Note that `this` in methods points to the created proxy, so only methods and properties that start with a $-sign can be accessed
* without trouble.
*
* Note also that properties that start with two $-signs are cleared on $create.
*/
export declare class ProxyDescriptor<V = any, T = V> {
/**
* The target derivable (the input to the proxy and the {@link #$create} method). The actual values that can be seen by methods
* on the Proxy can be influenced by providing a {@link #$lens}.
*/
$target: Derivable<T>;
/**
* The expression that represents the path to the current Proxy.
*/
$expression?: string;
/**
* The path to the current Proxy.
*/
$path?: Array<string | number>;
/**
* The derivable that is the input to all default methods on the Proxy and the {@link #$value} property.
*/
get $derivable(): Derivable<V>;
private $$derivable?;
/**
* The current value of the DerivableProxy. Can be expensive to calculate. When the target is settable (is an Atom) then $value
* is writable.
*/
get $value(): V;
set $value(newValue: V);
/**
* The current value of the target Derivable that was used to create the DerivableProxy.
*/
get $targetValue(): T;
set $targetValue(newValue: T);
/**
* In methods of a ProxyDescriptor, `this` is bound to the Proxy Object. Therefore, only $-properties and $-methods can be
* accessed safely. Use $proxyDescriptor to get access to the ProxyDescriptor Object to prevent the ProxyHandler from messing
* with your logic.
*/
protected get $proxyDescriptor(): this;
/**
* An optional method that can return an optional lens to this proxy. Is used to transform the values before accessed by the
* consumer of the Proxy (either through $value or one of the other methods).
*/
$lens?(): DerivableProxyLens<T, V> | undefined;
/**
* Wrap a Derivable as DerivableProxy using this ProxyDescriptor.
*
* @param obj the object to wrap
* @param expression the new expression to the created DerivableProxy
* @param path the new path to the created DerivableProxy
*/
$create(obj: Derivable<T>, expression?: string, path?: Array<string | number>): DerivableProxy<V>;
/**
* The $pluck method is the implementation of the pluck mechanism of DerivableProxy. Replace this method to change the
* pluck behavior. It should return a DerivableProxy.
*
* @param prop the property to pluck of the wrapped derivable
*/
$pluck(prop: string | number): DerivableProxy<V>;
/**
* The $pluckableKeys returns a list of properties that can be plucked from this object. Returned keys are guaranteed to
* result in a usable DerivableProxy when used with $pluck. Is used for `for ... in` and `Object.keys(...)` logic.
*/
$pluckableKeys(): (string | symbol)[];
/**
* Method that determines whether the current object is iterable and if so, how many elements it contains. During iteration
* {@link #pluck} is called with indices up to but not including the result of `$length()`.
*/
$length(): number | undefined;
$and(other: MaybePacked<any>): Derivable<any>;
$or(other: MaybePacked<any>): Derivable<any>;
$not(): Derivable<boolean>;
$is(other: MaybePacked<any>): Derivable<boolean>;
$derive(): Derivable<unknown>;
$react(reaction: (value: V, stop: () => void) => void, options?: Partial<ReactorOptions<any>>): () => void;
toJSON(): V;
get [Symbol.toStringTag](): string;
[Symbol.iterator](): IterableIterator<DerivableProxy<V>>;
get length(): number | undefined;
}
export interface DerivableProxyLens<T, V> {
get: (targetValue: T) => V;
set?: (newValue: V, targetValue: T | undefined) => T;
}
export type MaybePacked<T> = T | Derivable<T> | DerivableProxy<T>;
export declare function unwrapProxy<W>(obj: MaybePacked<W>): W | Derivable<W>;
/**
* Extends an expression with a property access. Automatically uses bracket notation where appropriate and escapes
* strings in brackets to give a realistic combined expression.
*
* @param expression the (optional) expression to extend
* @param property the property that should be appended to the expression
*/
export declare function extendExpression(expression: string | undefined, property: string | number): string;
/**
* Extends a path with a property access.
*
* @param path the (optional) path to extend
* @param property the property that should be appended to the path
*/
export declare function extendPath(path: Array<string | number> | undefined, property: string | number): (string | number)[];