import "reflect-metadata"; import { Constructor, EventEmitter3, IsData, LoggersType, PathValueOf, Paths, ServerUpdateRequest, ExtractedData, MongoId, IAutoUpdatedClientObject, IAutoUpdatedClientObjectBase, IAutoUpdateManager, DEMCache, DEMErrorCode, DEMArray, DEMArrayMutationParams } from "./CommonTypes.js"; import { ObjectId } from "bson"; import { Socket } from "socket.io-client"; export type DEMClientCallbacks = { new: (obj: IAutoUpdatedClientObject) => Promise | void; update: (obj: IAutoUpdatedClientObject, key: string) => Promise | void; delete: (manager: IAutoUpdateManager) => Promise | void; progress: (percent: number) => void; }; export declare const DEM_RAW_ARRAY: unique symbol; /** * Wraps a resolved relation array in a Proxy that blocks external mutations * while allowing transparent read operations, iterations, and library unwrapping. * * @param rawArray - The internal mutable array of resolved entities. * @param propertyName - The name identifier of the relation property. * @returns Immutable proxy wrapping the underlying entity array. */ export declare function createReadOnlyArrayProxy(rawArray: T[], propertyName: string): T[]; /** * Constructs a reactive DEMArray Proxy wrapper around entity array properties. * Exposes synchronous queries on committed local state and asynchronous mutation Promises. * * @param parent - The entity object containing this array. * @param propertyName - The name identifier of the array property. * @param isRef - Whether this property holds cross-entity reference pointers. * @param getItems - Function returning the currently resolved array items. * @returns Reactive DEMArray proxy instance. */ export declare function createDEMArray(parent: AutoUpdatedClientObject, propertyName: string, isRef: boolean, getItems: () => any[]): DEMArray; type SocketType = Socket; export declare abstract class AutoUpdatedClientObject> = Record>> implements IAutoUpdatedClientObject { protected entry: unknown; _refArrayCache?: Map; protected readonly socket: SocketType; protected data: IsData; protected readonly isServer: boolean; abstract readonly _id: MongoId; protected readonly loggers: LoggersType; protected isLoading: boolean; isLazyStub: boolean; /** * Human-readable descriptor string supplied by the server manifest. */ descriptor?: string; loadError?: string; protected isLoadingReferences: boolean; protected checkedMissingProperties?: Record; protected readonly emitter: EventEmitter3; readonly properties: string[]; readonly classParam: Constructor; readonly className: string; parentManager: IAutoUpdateManager & { cache: DEMCache; managers: M; }; private static _emitterCounter; /** * Generates a human-readable descriptor from direct entity attributes. * Base implementation stringifies the available data payload. * * @param data - Direct entity property data. * @returns String descriptor representing the entity. */ static getDescriptor(data: Partial): string; protected readonly EmitterID: string; protected _preloadTimers: Set>; protected toChangeOnParents?: { key: string; value: unknown; }[]; callbacks: DEMClientCallbacks; protected _isUpdating: boolean; private readonly loadReferencesAsync; /** * Initializes an AutoUpdatedClientObject instance. * * @param classParam - Constructor of the client object entity. * @param socket - Socket.IO client socket connection. * @param data - Entity identifier string or initial data object. * @param loggers - Logging interfaces. * @param className - Managed entity class name. * @param parentManager - Host client manager. * @param callback - Event callbacks interface. * @param emitter - Shared event emitter. * @param isServer - Flag indicating whether running on server runtime. * @throws {DEMError} Throws DEMErrorCode.MISSING_ARGUMENT when required parameters are omitted. */ constructor(classParam?: Constructor, socket?: SocketType, data?: string | IsData, loggers?: LoggersType, className?: string, parentManager?: IAutoUpdateManager>, callback?: DEMClientCallbacks, emitter?: EventEmitter3, isServer?: boolean); /** * Normalizes reference fields in entity data into string IDs. * * @param data - Entity data payload. * @returns Cleaned entity data payload. */ protected handleDataCleanup(data: IsData): IsData; /** * Pauses execution until the object finishes asynchronous preloading. * * @param timeoutMs - Maximum milliseconds to wait before rejecting. * @throws {DEMError} Throws DEMErrorCode.PRELOAD_TIMEOUT on timeout or OBJECT_LOAD_FAILED on failure. */ waitForPreloaded(timeoutMs?: number): Promise; /** * Emits creation event to the server socket and awaits populated entity response. * * @param data - Initial data payload. */ protected handleNewObject(data: IsData): void; protected _cachedExtractedData: ExtractedData> | null; /** * Internal cached serialized data payload without deep cloning. * Safe for read-only serialization. * * @returns Raw extracted data representation of the entity. */ getRawExtractedData(): ExtractedData>; /** * Returns a deep clone of the entity's extracted data with reference objects converted to IDs. * * @returns Serialized entity representation. */ get extractedData(): ExtractedData>; /** * Indicates whether the entity has finished loading its data. * * @returns True if loaded. */ get isLoaded(): boolean; /** * Ensures that this entity is fully hydrated from the server. * If the entity is a lazy stub, triggers on-demand graph hydration up to the requested depth. * * @param options - Hydration options containing graph depth. * @returns Promise resolving to this hydrated entity instance. */ ensureLoaded(options?: { depth?: number; }): Promise; /** * Hydrates an unhydrated stub instance with full entity data received from the server. * * @param payload - Entity data payload. */ hydrateFromData(payload: IsData): void; /** * Asynchronously awaits preloading and loads all missing reference links. * * @returns Promise resolving to true when completed. */ isPreLoadedAsync(): Promise; /** * Identifies and connects missing cross-entity references on server startup. */ loadMissingReferences(): Promise; private _hasUpdateSocketListener; private openSockets; private handleUpdateRequest; private _gettersGenerated; /** * True after the post-construction pass removed all own properties that shadow prototype accessors. */ private _ownShadowsCleared; private writeQueue; get updateEventName(): string; /** * Extracts the raw string identifier or array of string identifiers from a reference property. * * @param key - Name of property to extract identifier from. * @returns Raw string ID, array of raw string IDs, or undefined if missing. */ getRawId(key: string): string | string[] | undefined; /** * Installs prototype accessors for the class and removes own properties that shadow them. * ES2022 class field declarations in derived classes create these own properties. * After the post-construction pass, the method returns immediately. * * @returns void */ generateSettersAndGetters(): void; /** * Retrieves a property value by dot-notated or shallow key path. * * @param key_ - Property key or dot-delimited path. * @returns Value at requested path or never if property does not exist. */ getValue>>(key_: K): PathValueOf; getValue(key_: string): never; /** * Resolves reference pointer ID to instantiated entity instance across caches and managers. * * @param id - Entity ID or ObjectId. * @param key - Property key referencing the entity. * @returns Resolved entity instance or undefined. */ findReference(id: string | ObjectId, key: string): IAutoUpdatedClientObject | undefined; /** * Mutates property value and synchronizes change to the server via socket. * * @param key - Property key to modify. * @param val - Value to assign. * @returns Promise resolving to modification result. */ setValue(key: K, val: PathValueOf, K>): Promise<{ success: boolean; msg: string; code?: DEMErrorCode; }>; /** * Internal setter with writeQueue serialization ensuring sequential updates. * * @param key - Property key. * @param val - Value to assign. * @param silent - Whether socket broadcast is bypassed. * @param noGet - Whether local update bypasses get. * @param noUpdate - Whether onUpdate hook is bypassed. * @param isParentUpdate - Whether mutation originated from parent. * @returns Promise resolving to operation outcome. */ protected setValue__(key: string, val: unknown, silent?: boolean, noGet?: boolean, noUpdate?: boolean, isParentUpdate?: boolean): Promise<{ success: boolean; msg: string; code?: DEMErrorCode; }>; private setValueQueueInternal; protected setValueInternal(key: string, value: unknown, silent?: boolean, noUpdate?: boolean): Promise<{ success: boolean; msg: string; code?: DEMErrorCode; }>; /** * Enqueues an array mutation in the entity write queue to ensure sequential execution. * * @param key - Target array property key. * @param req - Array mutation request payload. * @param isRef - Whether the target property is a relational reference array. * @returns Promise resolving to the mutation result. */ mutateArrayQueue(key: string, req: DEMArrayMutationParams, isRef: boolean): Promise; /** * Internal execution handler for array mutations following pessimistic convergence semantics. * Transmits mutation request to server, awaits acknowledgment, and updates local state. * * @param key - Target array property key. * @param req - Array mutation parameters payload. * @param isRef - Whether the target property holds relational entities. * @returns Promise resolving to the operator return value or updated array. * @throws {DEMError} Throws when server rejects mutation or write fails. */ private mutateArrayInternal; protected makeUpdate(key: string, value: unknown): ServerUpdateRequest; protected resolveReference(id: string): Promise | null>; private findAndLoadReferences; protected wipeSelf(): Promise; destroyImmediate(): void; private loadForceReferences; protected createdWithParent(pointer: string[], parent: Record): Promise; /** * Destroys the entity and notifies server socket of deletion. * * @param once - Internal flag preventing infinite recursion. * @param isRemote - Whether the deletion originates from a remote server broadcast or delta sync. * @returns Promise resolving to deletion outcome. */ destroy(once?: boolean, isRemote?: boolean): Promise<{ success: boolean; message: string; code?: DEMErrorCode; }>; /** * Resolves empty pointer properties (declared with refsTo) from owner entities. * * @returns Promise resolving when all pointer properties are examined. */ private checkForMissingRefs; /** * Finds the owner entity that lists this entity and writes the owner ID into a pointer property. * In an open reverse reference index scope, the lookup uses a cached reverse index. * Otherwise, the lookup scans all entities of the owner manager. * * @param prop - Pointer property on this entity. * @param pointer - Pointer parts: [owner class name, owner property name]. * @returns Promise resolving when the lookup completes. */ private findMissingObjectReference; /** * Triggers missing reference resolution on all child referenced entities. */ contactChildren(): Promise; protected onUpdate(noUpdate?: boolean, key?: string): Promise; protected onDeletion(): Promise; } /** * Traverses entity object and transforms referenced objects into string identifiers. * * @param instance - Raw entity data record. * @param target - Reflection prototype target. * @param prefix - Dot-notated property key prefix. * @param allProps - Accumulated array of discovered property paths. * @param newData - Output object receiving sanitized data. * @param loggers - Logging interfaces. * @returns Object containing all property paths and transformed newData. */ export declare function processIsRefProperties(instance: Record, target: object, prefix: string | null, allProps: string[], newData: Record, loggers: LoggersType): { allProps: string[]; newData: Record; }; /** * Determines whether a value is a valid BSON ObjectId input. * Returns the same result as ObjectId.isValid. * Does not construct (and catch) a throwing ObjectId for values that can never be valid. * * @param value - Value to examine. * @returns True if ObjectId.isValid returns true for the value. */ export declare function isValidObjectId(value: unknown): boolean; /** * Compiles V8 fast-shape property getters and setters on the class prototype. * * @param classParam - Constructor function of the target entity class. * @returns Cached metadata object with properties list, refProps set, and refsToMap. */ export declare function setupClassAccessors(classParam: Constructor): { properties: string[]; refProps: Set; refsToMap: Map; }; /** * Traverses prototype chain recursively to resolve metadata key. * * @param metaKey - Reflection metadata key. * @param proto - Prototype object. * @param prop - Property name on prototype. * @returns Metadata value or undefined. */ export declare function getMetadataRecursive(metaKey: string, proto: object | null, prop: string): unknown; /** * Opens a bulk reference resolution scope for a managers record. * In the scope, missing back-reference lookups use cached reverse indexes. * This replaces one full scan of the target manager for each entity (O(N*M)). * Use the scope only when no external writer changes reference data (for example, during startup). * * @param managers - Shared managers record of the factory. * @returns void */ export declare function beginReverseReferenceIndexScope(managers: object): void; /** * Closes a bulk reference resolution scope that beginReverseReferenceIndexScope opened. * The cached reverse indexes are discarded when the last open call closes. * * @param managers - Shared managers record of the factory. * @returns void */ export declare function endReverseReferenceIndexScope(managers: object): void; export {};