@akala/core
Version:
363 lines (362 loc) • 14.9 kB
TypeScript
import { EventEmitter } from "../events/event-emitter.js";
import { Event, type IEvent } from "../events/shared.js";
import { BinaryExpression } from "../parser/expressions/binary-expression.js";
import { CallExpression } from "../parser/expressions/call-expression.js";
import { ConstantExpression } from "../parser/expressions/constant-expression.js";
import { ExpressionVisitor } from "../parser/expressions/visitors/expression-visitor.js";
import type { Expressions, StrictExpressions } from "../parser/expressions/expression.js";
import { MemberExpression } from "../parser/expressions/member-expression.js";
import { NewExpression } from "../parser/expressions/new-expression.js";
import { ParameterExpression } from "../parser/expressions/parameter-expression.js";
import { TernaryExpression } from "../parser/expressions/ternary-expression.js";
import { type Subscription } from "../teardown-manager.js";
import { watcher, type Watcher, WatcherFormatter } from './shared.js';
import { AssignmentExpression } from "../parser/expressions/assignment-expression.js";
import { ObservableArray } from "./array.js";
import { FormatExpression } from "../parser/parser.js";
import { AllEventKeys } from "../events/index.js";
export interface ObjectEvent<T, TKey extends keyof T> {
readonly property: TKey;
readonly value: T[TKey];
readonly oldValue: T[TKey];
}
export declare class AsyncFormatter extends WatcherFormatter {
private promise;
private value;
/**
* Formats the value.
* @param {unknown} value - The value to format.
* @returns {unknown} The formatted value.
*/
format(value: unknown): unknown;
/**
* Creates an instance of AsyncFormatter.
* @param {Watcher} [watcher] - The watcher instance.
*/
constructor(watcher?: Watcher);
}
export declare class EventFormatter<T extends unknown[]> extends WatcherFormatter {
private event;
private value;
private sub?;
/**
* Formats the value.
* @param {unknown} value - The value to format.
* @returns {T} The formatted value.
*/
format(value: unknown): T;
/**
* Creates an instance of EventFormatter.
* @param {Watcher} watcher - The watcher instance.
*/
constructor(watcher: Watcher);
}
export default class Watch<T extends object> extends WatcherFormatter {
private value;
/**
* Formats the value.
* @param {T} value - The value to format.
* @returns {T} The formatted value.
*/
format(value: T): T;
}
export declare class BindingFormatter extends WatcherFormatter {
private binding;
private sub;
private value;
/**
* Formats the value.
* @param {unknown} value - The value to format.
* @returns {unknown} The formatted value.
*/
format(value: unknown): unknown;
/**
* Creates an instance of BindingFormatter.
* @param {Watcher} watcher - The watcher instance.
*/
constructor(watcher: Watcher);
}
export type IWatched<T extends object> = T & {
[watcher]: ObservableObject<T> | ObservableArray<T>;
};
export type Getter<TSource, TResult> = (target: TSource) => TResult;
export type WatchGetter<TSource, TResult> = (target: TSource, watcher: Watcher) => TResult;
export type Setter<TSource, TValue> = (target: TSource, value: TValue) => void;
export type IWatchable<T extends object> = {
[watcher]?: ObservableObject<T>;
};
export declare class BuildWatcherAndSetter<T> extends ExpressionVisitor {
target: ParameterExpression<T>;
value: ParameterExpression<unknown>;
private static memberWatcher;
private static formatWatcher;
/**
* Evaluates the expression.
* @param {Expressions} expression - The expression to evaluate.
* @returns {{ watcher: WatchGetter<T, TValue>, setter?: Setter<T, TValue> }} The watcher and setter.
*/
eval<TValue>(expression: Expressions): {
watcher: WatchGetter<T, TValue>;
setter?: Setter<T, TValue>;
};
private boundObservables;
private getter;
/**
* Visits a constant expression.
* @param {ConstantExpression<unknown>} arg0 - The constant expression.
* @returns {StrictExpressions} The visited expression.
*/
visitConstant(arg0: ConstantExpression<unknown>): StrictExpressions;
/**
* Visits a format expression.
* @param {FormatExpression<TOutput>} expression - The format expression.
* @returns {FormatExpression<TOutput>} The visited expression.
*/
visitFormat<TOutput>(expression: FormatExpression<TOutput>): FormatExpression<TOutput>;
/**
* Visits a member expression.
* @param {MemberExpression<T1, TMember, T1[TMember]>} arg0 - The member expression.
* @returns {StrictExpressions} The visited expression.
*/
visitMember<T1, TMember extends keyof T1>(arg0: MemberExpression<T1, TMember, T1[TMember]>): StrictExpressions;
/**
* Visits a ternary expression.
* @param {TernaryExpression<T>} expression - The ternary expression.
* @returns {TernaryExpression<Expressions>} The visited expression.
*/
visitTernary<T extends Expressions = StrictExpressions>(expression: TernaryExpression<T>): TernaryExpression<Expressions>;
/**
* Visits a call expression.
* @param {CallExpression<T, TMethod>} arg0 - The call expression.
* @returns {StrictExpressions} The visited expression.
*/
visitCall<T, TMethod extends keyof T>(arg0: CallExpression<T, TMethod>): StrictExpressions;
/**
* Visits a new expression.
* @param {NewExpression<T>} expression - The new expression.
* @returns {StrictExpressions} The visited expression.
*/
visitNew<T>(expression: NewExpression<T>): StrictExpressions;
/**
* Visits a binary expression.
* @param {BinaryExpression<T>} expression - The binary expression.
* @returns {BinaryExpression<Expressions>} The visited expression.
*/
visitAssign<T extends Expressions = StrictExpressions>(expression: AssignmentExpression<T>): AssignmentExpression<Expressions>;
/**
* Visits a binary expression.
* @param {BinaryExpression<T>} expression - The binary expression.
* @returns {BinaryExpression<Expressions>} The visited expression.
*/
visitBinary<T extends Expressions = StrictExpressions>(expression: BinaryExpression<T>): BinaryExpression<Expressions>;
}
type ObservableType<T extends object> = {
[key in Exclude<keyof T, typeof allProperties>]: IEvent<[ObjectEvent<T, key>], void>;
} & {
[allProperties]: IEvent<[ObjectEvent<T, keyof T>], void>;
};
export type BindingChangedEvent<T> = {
value: T;
oldValue: T;
};
export declare const BindingsProperty: unique symbol;
type Unbound<T> = T extends Binding<infer X> ? X : T;
type UnboundObject<T extends object> = {
[K in keyof T]?: Unbound<T[K]>;
};
export declare class Binding<T> extends EventEmitter<{
change: Event<[BindingChangedEvent<T>]>;
}> {
target: unknown;
readonly expression: Expressions;
/**
* Combines named bindings.
* @param {T} obj - The object with named bindings.
* @returns {Binding<UnboundObject<T>>} The combined binding.
*/
static combineNamed<T extends {
[K in keyof T]?: T[K] | Binding<T[K]>;
}>(obj: T): Binding<UnboundObject<T>>;
/**
* Combines multiple bindings.
* @param {...(T[K] | Binding<T[K]>)[]} bindings - The bindings to combine.
* @returns {Binding<T>} The combined binding.
*/
static combine<T extends unknown[]>(...bindings: {
[K in keyof T]?: T[K] | Binding<T[K]>;
}): Binding<T>;
/**
* Checks if a target has a bound property.
* @param {T} target - The target object.
* @param {PropertyKey} property - The property key.
* @returns {boolean} True if the target has a bound property, false otherwise.
*/
static hasBoundProperty<T extends {}>(target: T, property: PropertyKey): boolean;
/**
* Defines a property on the target object.
* @param {object} target - The target object.
* @param {PropertyKey} property - The property key.
* @param {T} [value] - The initial value.
* @returns {Binding<T>} The defined binding.
*/
static defineProperty<T = unknown>(target: object, property: PropertyKey, value?: T): Binding<T>;
/**
* Pipes the binding to another expression.
* @param {TKey | string | Expressions | ((ev: BindingChangedEvent<T>) => U)} expression - The expression to pipe to.
* @returns {Binding<U>} The piped binding.
*/
pipe<const TKey extends keyof T>(expression: TKey): Binding<T[TKey]>;
pipe<U>(expression: string | keyof T | Expressions | ((ev: BindingChangedEvent<T>) => U)): Binding<U>;
watcher: Watcher;
[Symbol.dispose](): void;
/**
* Creates an instance of Binding.
* @param {unknown} target - The target object.
* @param {Expressions} expression - The expression.
*/
constructor(target: unknown, expression: Expressions);
/**
* Simplifies the binding.
* @param {Binding<any>} target - The target binding.
* @param {Expressions} expression - The expression.
* @returns {Binding<T> | null} The simplified binding.
*/
static simplify<T>(target: Binding<any>, expression: Expressions): Binding<T> | null;
private readonly attachWatcher;
/**
* Unwraps the element.
* @param {T} element - The element to unwrap.
* @returns {Partial<T>} The unwrapped element.
*/
static unwrap<T>(element: T): Partial<T>;
private _setter?;
/**
* Registers a handler for the change event.
* @param {(ev: { value: T, oldValue: T }) => void} handler - The event handler.
* @param {boolean} [triggerOnRegister] - Whether to trigger the handler on registration.
* @returns {Subscription} The subscription.
*/
onChanged(handler: (ev: {
value: T;
oldValue: T;
}) => void, triggerOnRegister?: boolean): Subscription;
/**
* Sets the value.
* @param {T} value - The value to set.
*/
setValue(value: T): void;
get canSet(): boolean;
/**
* Gets the value.
* @returns {T} The value.
*/
getValue(): T;
}
export declare class EmptyBinding<T> extends Binding<T> {
/**
* Creates an instance of EmptyBinding.
* @param {T} [initialValue] - The initial value.
*/
constructor(initialValue?: T);
get canSet(): boolean;
/**
* Gets the value.
* @returns {T} The value.
*/
getValue(): T;
/**
* Sets the value.
* @param {T} newValue - The value to set.
*/
setValue(newValue: T): void;
}
export declare const allProperties: unique symbol;
/**
* Observable object implementation.
* @param {Object} initialObject - The initial object.
*/
export declare class ObservableObject<T extends object> extends EventEmitter<ObservableType<T>> {
/**
* Unwraps the target object.
* @param {T} arg0 - The target object.
* @returns {T extends ObservableObject<infer X> ? X : T} The unwrapped object.
*/
static unwrap<T>(arg0: T): T extends ObservableObject<infer X> ? X : T;
/**
* Generates a dynamic proxy that gets and sets values from target, but triggers notifications on set.
*/
static wrap<T extends object>(target: T): IWatched<T>;
readonly target: T & IWatchable<T>;
/**
* Creates an instance of ObservableObject.
* @param {T & { [watcher]?: ObservableObject<T> } | ObservableObject<T>} target - The target object.
*/
constructor(target: (T & IWatchable<T>) | ObservableObject<T>);
/**
* Watches all properties of the object.
* @param {T} obj - The object to watch.
* @param {Watcher} watcher - The watcher instance.
* @returns {Subscription} The subscription.
*/
static watchAll<T extends object>(obj: T, watcher: Watcher): Subscription;
/**
* Watches a property of the object.
* @param {Watcher} watcher - The watcher instance.
* @param {TKey} property - The property to watch.
* @returns {Subscription} The subscription.
*/
watch<const TKey extends AllEventKeys<ObservableType<T>>>(watcher: Watcher, property: TKey): Subscription;
/**
* Checks if an object is watched.
* @param {T} x - The object to check.
* @returns {boolean} True if the object is watched, false otherwise.
*/
static isWatched<T>(x: T): x is IWatched<T & object>;
/**
* Sets the value of a property.
* @param {Binding<T> | T} target - The target object or binding.
* @param {Expressions | PropertyKey} expression - The expression or property key.
* @param {any} value - The value to set.
*/
static setValue<T extends object, const TKey extends keyof T>(target: Binding<T>, expression: TKey, value: T[TKey]): any;
static setValue<T extends object>(target: Binding<T>, expression: string, value: any): any;
static setValue<T extends object>(target: Binding<T>, expression: Expressions, value: any): any;
static setValue<T extends object, const TKey extends keyof T>(target: T, expression: TKey, value: T[TKey]): any;
static setValue<T extends object>(target: T, expression: string, value: any): any;
static setValue<T extends object>(target: T, expression: Expressions, value: any): any;
/**
* Sets the value of a property.
* @param {TKey} property - The property key.
* @param {T[TKey]} value - The value to set.
* @returns {boolean} True if the value was set, false otherwise.
*/
setValue<const TKey extends keyof T>(property: TKey, value: T[TKey]): boolean;
/**
* Gets the value of a property.
* @param {TKey} property - The property key.
* @returns {T[TKey]} The value of the property.
*/
getValue<const TKey extends keyof T>(property: TKey): T[TKey];
/**
* Gets the value of a property.
* @param {Binding<T> | T} target - The target object or binding.
* @param {TKey} property - The property key.
* @returns {T[TKey]} The value of the property.
*/
static getValue<T, const TKey extends keyof T>(target: Binding<T>, property: TKey): T[TKey];
static getValue<T, const TKey extends keyof T>(target: T, property: TKey): T[TKey];
/**
* Gets the observable object for a property.
* @param {TKey} property - The property key.
* @returns {ObservableObject<T[TKey]> | null} The observable object or null.
*/
getObservable<const TKey extends keyof T>(property: TKey): T[TKey] extends object ? ObservableObject<T[TKey]> : null;
/**
* Gets the value of a property.
* @param {T} target - The target object.
* @param {keyof T} property - The property key.
* @returns {T[keyof T]} The value of the property.
*/
static get<T>(target: T, property: keyof T): T[keyof T];
}
export {};