import { IDisposable, IKeyedInstanceFactory, IGuidFactory, IIndexValueAccessor, IValueMetadata, IDisposableOwner } from '@rs-x/core'; import { IIndexWatchRule, IStateManager, IWatchFactory } from '@rs-x/state-manager'; import { Observable } from 'rxjs'; interface IWatchRegistrationKey { readonly context: unknown; readonly index: unknown; readonly watchRule?: unknown; } interface IExpressionEvaluateChangeManager { isInitialized(): boolean; incrementChangeCycle(): void; decrementChangeCycle(): any; markDirty(evaluateUnit: IExpressionEvaluateUnit): void; } interface IExpressionEvaluateUnit extends IDisposable { readonly count: number; readonly index: unknown; readonly value: unknown; context: unknown; isCommitReady(): boolean; commitChange(): void; watch(changeManager: IExpressionEvaluateChangeManager): void; /** Called before commitChange() in a batch flush to increment ancestor pending counts. */ prepareForBatchEvaluate?(): void; /** * Called instead of watch() when this unit shares a (context, index) pair with a * primary unit in the same expression manager. Reads the initial value without * registering watch listeners — the manager fans out changes via applyChange(). */ watchAsReplica?(changeManager: IExpressionEvaluateChangeManager): void; /** * Pushes a new value onto this replica unit so it can commit without a watch callback. * Called by the manager immediately after the primary unit's markDirty fires. */ applyChange?(newValue: unknown): void; } interface IEvaluateManagerForExpression extends IDisposable { register(evaluateUnit: IExpressionEvaluateUnit): void; initialize(): void; } type CommitHandler = (initialized: boolean) => void; interface IExpressionEvaluateManager extends IKeyedInstanceFactory { } interface IIdentifierOwnerResolver { resolve(index: unknown, context?: unknown): object | null; } interface IIdentifierWatchRuleData { index: unknown; indexWatchRule: IIndexWatchRule | undefined; isLeaf: boolean; isMemberExpressionSegment: boolean; } interface IIdentifierWatchRuleFactory { create(context: unknown, data: IIdentifierWatchRuleData): IIndexWatchRule; } type ChangeHook = (expression: IExpressionTree, oldValue: unknown) => void; interface IExpression extends IDisposable { readonly id: string; readonly changed: Observable; readonly type: ExpressionType; readonly expressionString: string; readonly value: T | undefined; readonly isRoot: boolean; readonly isAsync: boolean | undefined; readonly isDisposed: boolean; changeHook?: ChangeHook; toString(): string; clone(): this; bind(settings: IExpressionBindConfiguration): IExpression; } interface IExpressionTree extends IExpression { readonly parent: IExpressionTree | undefined; readonly childExpressions: readonly IExpressionTree[]; readonly hidden: boolean; } interface IPropertyPath { object: IPropertyPath; name: string; } interface IChangePathValue { readonly path: string; readonly value: T; } declare enum ExpressionType { Addition = "addition", And = "and", Array = "array", BigInt = "big int", BitwiseAnd = "bitwise and", BitwiseLeftShift = "bitwise left shift", BitwiseNot = "bitwise not", BitwiseOr = "bitwise or", BitwiseRightShift = "bitwise right shift", BitwiseUnsignedRightShift = "bitwise unsigned right shift", BitwiseXor = "bitwise xor", Boolean = "boolean", Conditional = "conditional", Division = "division", Equality = "equality", Exponentiation = "exponentiation", Function = "function", GreaterThan = "greater than", GreaterThanOrEqual = "Greater than or equal", Identifier = "identifier", In = "in", ComputedIndex = "Computed index", Inequality = "inequality", Instanceof = "instanceof", LessThan = "less than", LessThanOrEqual = "less than or equal", Member = "member", Multiplication = "multiplication", New = "new", Not = "not", Null = "null", NullishCoalescing = "nullish coalescing", Number = "number", Object = "object", Or = "or", Property = "property", RegExp = "regular expression", Remainder = "remain", Sequence = "sequence", Spread = "spread", StrictEquality = "strict equality", StrictInequality = "strict inequality", String = "string", Subtraction = "subtraction", TemplateLiteral = "template literal", Typeof = "typeof", UnaryNegation = "unary negation", UnaryPlus = "unary plus" } interface IExpressionParser { parse(expression: string): AbstractExpression; } declare abstract class AbstractExpression implements IExpressionTree { readonly type: ExpressionType; readonly expressionString: string; private _changed; private _lastChangedValue; private _parent; private _id; private _isDisposed; private _owner; private _services; private _leafIndexWatchRule?; private _changeHook?; private _evaluateManagerForExpression?; private _hidden; protected readonly _childExpressions: AbstractExpression[]; private _value; private _oldValue; private _isDirty; private _pendingDirtyCount; private static readonly _EMPTY_CHILDREN; protected constructor(type: ExpressionType, expressionString: string, children?: AbstractExpression[]); get hidden(): boolean; get id(): string; get isAsync(): boolean | undefined; get isDisposed(): boolean; get changeHook(): ChangeHook | undefined; set changeHook(value: ChangeHook | undefined); get value(): T | undefined; protected set value(value: T | undefined); get isRoot(): boolean; get changed(): Observable; get childExpressions(): readonly IExpressionTree[]; get parent(): AbstractExpression | undefined; abstract clone(): this; bind(settings: IExpressionBindConfiguration): AbstractExpression; dispose(): void; toString(): string; protected get root(): AbstractExpression; protected get services(): IExpressionServices; protected get guidFactory(): IGuidFactory; protected get leafIndexWatchRule(): IIndexWatchRule | undefined; protected get stateManager(): IStateManager; protected get indexValueAccessor(): IIndexValueAccessor; protected get identifierOwnerResolver(): IIdentifierOwnerResolver; protected get expressionEvaluateManager(): IExpressionEvaluateManager; protected get identifierWatchRuleFactory(): IIdentifierWatchRuleFactory; protected get watchFactory(): IWatchFactory; protected get valueMetadata(): IValueMetadata; protected get absoluteRoot(): AbstractExpression; protected get isEvaluationBoundary(): boolean; protected get evaluateManagerForExpression(): IEvaluateManagerForExpression; protected get expressionEvaluateUnit(): IExpressionEvaluateUnit | undefined; protected bindChildren(settings: IExpressionBindConfiguration): void; protected onBind(_: IExpressionBindConfiguration): void; protected createEvaluateManagerForExpression(): IEvaluateManagerForExpression; private onCommit; protected static getExpressionEvaluateUnit(expression: AbstractExpression): IExpressionEvaluateUnit | undefined; protected static evaluateExpression(expression: AbstractExpression): unknown; protected static setHidden(target: T): T; protected static setValue(expression: AbstractExpression, evaluate: () => unknown): void; protected static setParent(expression: AbstractExpression, parent: AbstractExpression): void; protected static clearValue(expression: AbstractExpression): void; protected abstract evaluate(): T | undefined; protected internalDispose(): void; protected canEvaluate(): boolean; protected reevaluated: () => boolean; /** * Walk from this node up to the root, incrementing each ancestor's * `_pendingDirtyCount` by 1. If an ancestor's count was already > 0 * its parent is already registered — stop early to avoid double-counting. * Used by batch-aware evaluate units before committing so that shared * ancestor nodes wait for all dirty children before re-evaluating. */ protected incrementAncestorPendingCounts(): void; protected evaluateBottomToTop(): boolean; protected evalateTopToBottom(): void; protected shouldAbortTopDownEvaluation(_childExpression: AbstractExpression, value: unknown): boolean; protected markRootDirty(): void; private tryEmitChanged; } interface IExpressionIdProvider { getId(node: IExpressionTree): string; } interface IExpressionServices { readonly expressionEvaluateManager: IExpressionEvaluateManager; readonly stateManager: IStateManager; readonly indexValueAccessor: IIndexValueAccessor; readonly identifierOwnerResolver: IIdentifierOwnerResolver; readonly guidFactory: IGuidFactory; readonly valueMetadata: IValueMetadata; readonly expressionIdProvider: IExpressionIdProvider; readonly watchFactory: IWatchFactory; readonly identifierWatchRuleFactory: IIdentifierWatchRuleFactory; } interface IBindConfigurationBase { readonly services: IExpressionServices; readonly owner?: IDisposableOwner; readonly leafIndexWatchRule?: IIndexWatchRule; readonly skipEvaluateUnitRegistration?: boolean; } type IExpressionBindConfigurationExtra = { readonly currentValue?: unknown; readonly isRoot?: boolean; }; type IExpressionBindConfiguration = (IBindConfigurationBase & IExpressionBindConfigurationExtra & { context?: never; }) | (IBindConfigurationBase & IExpressionBindConfigurationExtra & { context: unknown; }); export { AbstractExpression as A, type CommitHandler as C, ExpressionType as E, type IExpressionEvaluateUnit as I, type IExpressionEvaluateChangeManager as a, type IEvaluateManagerForExpression as b, type IExpressionEvaluateManager as c, type IIdentifierOwnerResolver as d, type IExpressionTree as e, type IExpression as f, type ChangeHook as g, type IExpressionBindConfiguration as h, type IExpressionParser as i, type IExpressionServices as j, type IExpressionIdProvider as k, type IIdentifierWatchRuleFactory as l, type IIdentifierWatchRuleData as m, type IBindConfigurationBase as n, type IChangePathValue as o, type IExpressionBindConfigurationExtra as p, type IPropertyPath as q, type IWatchRegistrationKey as r };