import type { VersionContext, VersionedObjectOptions, VersionRule } from './types.ts'; /** * A small utility to produce a "versioned" object by applying a set of rules * to a base object under a given context. * * Rules are evaluated in descending `priority` order, and every matched rule's * `value` is shallow-merged into the result (later merges override earlier keys). * * Supports: * - **Sync resolve**: predicates and values must be sync * - **Async resolve**: predicates and/or values may be async * - **Caching** with TTL and LFU-ish eviction (hits, then timestamp) * - **Freeze** final result (optional) * * @author dafengzhen */ export declare class VersionedObject { /** Cache for async resolutions. */ private readonly asyncCache; /** Base object (never mutated). */ private readonly base; /** Normalized options with defaults. */ private readonly options; /** Version rules sorted by priority (desc). */ private readonly rules; /** Cache for sync resolutions. */ private readonly syncCache; /** * Create a VersionedObject. * * @param base - The base object to start from (will be shallow-copied when resolving). * @param rules - Rules to apply. They will be sorted by `priority` (desc). * @param options - Behavior options (cache, TTL, key, freeze, etc.). */ constructor(base: T, rules?: readonly VersionRule[], options?: VersionedObjectOptions); /** * Return a new VersionedObject with a rule appended. * * @param rule - The rule to add. */ addRule(rule: VersionRule): VersionedObject; /** * Return a new VersionedObject with rules appended. * * @param rules - Rules to add. */ addRules(rules: VersionRule[]): VersionedObject; /** * Return a new VersionedObject with empty caches (rules/options unchanged). */ clearCache(): VersionedObject; /** * Clone the current VersionedObject (rules/options copied). */ clone(): VersionedObject; /** * Explain how a context is resolved (async). * * This will: * 1) Validate and normalize context * 2) Collect matched rules (async predicates allowed) * 3) Apply rule values (async values allowed) * * @param ctx - Context for rule matching. If omitted, uses `defaultContext`. * @returns Object containing base, matched rules, and final result. */ explain(ctx?: VersionContext): Promise<{ base: T; matched: VersionRule[]; result: T; }>; /** * Get cache statistics (hits/size) for sync + async caches. */ getCacheStats(): { async: { hits: number; size: number; }; sync: { hits: number; size: number; }; }; /** * Get total number of rules. */ getRuleCount(): number; /** * Resolve synchronously. * * Requirements: * - `rule.when(ctx)` must be **sync** (boolean) * - `rule.value` must be **non-Promise** * * If caching is enabled, uses `cacheKey(ctx)` and returns cached result * when valid (within TTL). * * @param ctx - Context for rule matching. If omitted, uses `defaultContext`. * @throws {Error} If a predicate returns a Promise. * @throws {Error} If a matched rule's value is a Promise. */ resolve(ctx?: VersionContext): T; /** * Resolve asynchronously. * * Allows: * - async predicates: `await rule.when(ctx)` * - async values: `await rule.value` * * If caching is enabled, in-flight promises are cached too, so concurrent * requests for the same key share the same work. * * @param ctx - Context for rule matching. If omitted, uses `defaultContext`. */ resolveAsync(ctx?: VersionContext): Promise; /** * Return a new VersionedObject with merged options. * * @param options - Partial options to override. */ withOptions(options: Partial>): VersionedObject; /** * Apply rule values asynchronously (shallow merge). * * @param rules - Matched rules. */ private applyRulesAsync; /** * Apply rule values synchronously (shallow merge). * * @param rules - Matched rules. * @throws {Error} If any rule value is a Promise. */ private applyRulesSync; /** * Default cache key generator: stable JSON stringification of context. * * @param ctx - Context. */ private defaultCacheKey; /** * Normalize context: uses provided ctx or `defaultContext`. * * @param ctx - Optional context. * @throws {Error} If neither ctx nor defaultContext is provided. */ private getContext; /** * Read a valid (non-expired) entry from async cache. */ private getFromAsyncCache; /** * Read a valid (non-expired) entry from sync cache. */ private getFromSyncCache; /** * Get rule priority (defaults to 0). */ private getPriority; /** * Match rules asynchronously. * * @param ctx - Context. */ private matchRulesAsync; /** * Match rules synchronously. * * @param ctx - Context. * @throws {Error} If any predicate returns a Promise. */ private matchRulesSync; /** * Sort rules by descending priority. */ private ruleSort; /** * Save a sync result to cache and enforce max size. */ private saveSyncCache; /** * Trim cache to `maxCacheSize`. * * Eviction order: * 1) lower hits first * 2) older timestamp first */ private trimCache; /** * Validate context structure. * * Required: * - ctx must be an object * - ctx must contain a truthy `version` field * * In `strictMode`, keys starting with `$` are treated as reserved (warning). * * @throws {TypeError|Error} If context is invalid. */ private validateContext; /** * Validate a rule object. * * Required: * - rule must be an object * - rule.when must be a function * - rule.value must be provided (can be sync or async depending on resolve method) * - rule.priority (if provided) must be an integer * * @throws {TypeError|Error} If rule is invalid. */ private validateRule; }