import { EventEmitter } from "eventemitter3"; import { ObjectId, ObjectIdLike } from "bson"; import "reflect-metadata"; import { DEMErrorCode } from "./DEMErrors.js"; export type MongoId = string | ObjectId; export type EventEmitter3 = EventEmitter; export interface IAutoUpdateManager { readonly className: string; readonly cache: DEMCache; readonly managers: Record>; getObject(_id?: MongoId): T | null | undefined; loadObject?(_id: MongoId, options?: { depth?: number; }): Promise; deleteObject(_id: MongoId, isRemote?: boolean): Promise<{ success: boolean; message: string; code?: DEMErrorCode; }>; readonly objectsAsArray: T[]; readonly isLoaded: boolean; readonly manifest?: EntityDescriptor[]; readonly callbacks?: any; } export type DEMCallbacks = { new: (obj: T) => Promise | void; update: (obj: T, key: string) => Promise | void; delete: (manager: IAutoUpdateManager) => Promise | void; progress: (percent: number) => void; }; export interface IAutoUpdatedClientObjectBase { readonly _id: MongoId; readonly properties: string[]; readonly className: string; readonly isLoaded: boolean; isLazyStub?: boolean; descriptor?: string; ensureLoaded?(options?: { depth?: number; }): Promise; hydrateFromData?(payload: any): void; loadMissingReferences(): Promise; waitForPreloaded(): Promise; destroy(once?: boolean): Promise<{ success: boolean; message: string; code?: DEMErrorCode; }>; isPreLoadedAsync(): Promise; contactChildren(): Promise; getRawId?(key: string): string | string[] | undefined; getValue(key: string): unknown; setValue(key: string, val: unknown): Promise<{ success: boolean; msg: string; code?: DEMErrorCode; }>; readonly parentManager: IAutoUpdateManager; readonly callbacks: any; readonly classParam: any; } export interface IAutoUpdatedClientObject extends IAutoUpdatedClientObjectBase { readonly extractedData: ExtractedData>; getValue>>(key: K): PathValueOf; getValue(key: string): never; setValue>>(key: K, val: PathValueOf, K>): Promise<{ success: boolean; msg: string; code?: DEMErrorCode; }>; } export interface IAutoUpdatedServerObject extends IAutoUpdatedClientObject { loadFromDB(): Promise; loadFromDocument(document: unknown): void; } export type AutoProps = { readonly [K in keyof T]: T[K]; }; export type Constructor = new (...args: any[]) => T; export type UnboxConstructor = T extends new (...args: any[]) => infer I ? I : T; export type LoggersType = { info: (s: string) => void; debug: (s: string) => void; error: (s: string) => void; warn: (s: string) => void; }; type IsAUCOBase = T extends { className: string; _id: any; } ? true : false; type AllowStringForRefs = NonNullable extends ReadonlyArray ? IsAUCOBase> extends true ? (U | string | ObjectIdLike)[] : U[] : IsAUCOBase> extends true ? V | string | ObjectIdLike : V; type OnlyStringForRefs = V extends any ? V extends ReadonlyArray ? OnlyStringForRefs[] : V extends IAutoUpdatedClientObjectBase ? string : V extends Date ? V : V extends ObjectId | ObjectIdLike ? string : V extends object ? { [K in keyof V as V[K] extends Function ? never : K]: K extends "_id" ? string : OnlyStringForRefs; } : V : never; export type DEMCache = { references: Record; }; export type Pure> = Omit; export type IsData = { [K in keyof Pure as T[K] extends Function ? never : K]: AllowStringForRefs; } & { _id: MongoId; }; export type ExtractedData> = { [K in keyof IsData as K extends "_id" ? never : K]: OnlyStringForRefs[K]>; } & { _id: string; }; export type SocketEvent = [ string, unknown, (res: ServerResponse) => void ]; export type ServerResponse = { data: T; message?: string; code?: DEMErrorCode; success: true; related?: Record; updatedArray?: unknown[]; newRevision?: number; newHash?: string; } | { message: string; code?: DEMErrorCode; details?: unknown; success: false; updatedArray?: unknown[]; newRevision?: number; newHash?: string; }; /** * Lightweight entity descriptor providing human-readable identification before hydration. */ export interface EntityDescriptor { /** * String representation of entity unique identifier. */ _id: string; /** * Human-readable summary string generated from direct entity properties. */ description: string; } /** * Configuration options governing smart lazy loading behavior. */ export interface LazyLoadingOptions { /** * Enables lazy loading mode for the target manager. */ enabled?: boolean; /** * Default graph traversal depth for on-demand entity hydration (default: 2). */ defaultDepth?: number; } export type ServerUpdateRequest = { _id: MongoId; key: string; value: unknown; }; /** * Property decorator that registers a property into the class reflection metadata. * * @param target - Prototype of the target class. * @param propertyKey - Property name to register. */ export declare function classProp(target: object, propertyKey: string): void; /** * Property decorator for populated references pointing to another managed entity class. * * @param where - The target managed class name this property references. * @returns Property decorator function. */ export declare function populatedRef(where: string): (target: object, propertyKey: string) => void; /** * Property decorator marking a property as an unresolved reference pointer. * * @returns Property decorator function. */ export declare function classRef(): (target: object, propertyKey: string) => void; export type Pretty = { [K in keyof T]: T[K]; }; export type StripPrototypePrefix

= P extends "prototype" ? never : P extends `prototype.${infer Rest}` ? Rest : P; export type Recurseable = T extends object ? T extends Array | Function ? never : T : never; export type OnlyClassKeys = { [K in keyof T]: K; }[keyof T] & string; export type Split = S extends `${infer L}.${infer R}` ? [L, ...Split] : [S]; export type NonOptional = Exclude; export type DeAutoUpdate = T extends IAutoUpdatedClientObject ? unknown : T; export type RecursiveDeAutoUpdate> = T extends IAutoUpdatedClientObject ? unknown : T; export type OnlyAddedKeys = Pick>>; export type Prev = [never, 0, 1, 2, 3]; export type Join = K extends string | number ? P extends string | number ? `${K}${"" extends P ? "" : "."}${P}` : never : never; export type Paths = 0 extends 1 & T ? string : [D] extends [never] ? never : NonNullable extends object ? { [K in keyof OnlyAddedKeys, Base> & string]-?: NonNullable[K]> extends Function ? never : NonNullable[K]> extends Array | Date | ObjectId ? K : NonNullable[K]> extends object ? K | Join[K]>, Base, Prev[D]>> : K; }[keyof OnlyAddedKeys, Base> & string] : never; export type PathValueOf = 0 extends 1 & T ? any : P extends `${infer K}.${infer Rest}` ? K extends keyof NonNullable ? PathValueOf[K]>, Rest> : never : P extends keyof NonNullable ? NonNullable[P] : never; export declare const EVENT_INTERNAL_PRE_LOADED = "pre-loaded"; export declare const EVENT_UPDATE = "update"; export declare const EVENT_DELETE = "delete"; export declare const EVENT_NEW = "new"; export declare const EVENT_GET = "get"; export declare const EVENT_STARTUP = "startup"; export declare const EVENT_VERSION = "dem_version"; export declare const EVENT_DEAUTHENTICATE = "deauthenticate"; export * from "./version.js"; /** * Configuration options for DEM client-server version verification. */ export interface DEMVersionOptions { /** * If true, requires exact or strict compatibility between client and server versions. * In strict mode, minor or major mismatches reject the connection. * Default: false (allows minor/patch differences, warning on differences). */ strictVersionMatch?: boolean; /** * Optional minimum server version required by the client. * e.g., "0.6.0" */ minServerVersion?: string; /** * Optional custom validator callback. * Return true for compatible, false or error message string if incompatible. */ validateVersion?: (clientVersion: string, serverVersion: string) => boolean | string; /** * Optional callback triggered when a version mismatch or notice is detected. */ onVersionMismatch?: (clientVersion: string, serverVersion: string, message: string) => void; } /** * Result of a DEM version verification check. */ export interface DEMVersionVerificationResult { compatible: boolean; clientVersion: string; serverVersion: string; status: "match" | "compatible_minor" | "compatible_patch" | "mismatch_major" | "mismatch_minor" | "below_min_version" | "custom_rejected" | "unknown"; message: string; } export interface ParsedSemVer { major: number; minor: number; patch: number; prerelease?: string; } /** * Parses a semantic version string (e.g. "0.6.5", "v1.2.3-alpha"). * * @param version - Semantic version string to parse. * @returns ParsedSemVer object containing major, minor, patch, and prerelease fields, or null if invalid. */ export declare function parseSemVer(version: string): ParsedSemVer | null; /** * Compares two semantic version strings. * * @param v1 - First version string. * @param v2 - Second version string. * @returns -1 if v1 < v2, 0 if v1 === v2, 1 if v1 > v2. */ export declare function compareSemVer(v1: string, v2: string): number; /** * Verifies compatibility between client and server DEM versions. * Evaluates SemVer rules, custom validators, and minimum required versions. * * @param clientVersion - DEM version of the client. * @param serverVersion - DEM version of the server. * @param options - Optional verification rules and callbacks. * @returns Object describing compatibility result and status code. */ export declare function verifyDEMVersion(clientVersion: string, serverVersion: string, options?: DEMVersionOptions): DEMVersionVerificationResult; /** * Safely stringifies a value to JSON, catching circular reference errors. * * @param obj - The value to stringify. * @returns JSON string or fallback warning message. */ export declare function safeStringify(obj: unknown): string; /** * Global cache storing object references across managers. */ export declare class DEMGlobalCache { objects: Record; /** * Clears all objects in the cache. */ clear(): void; /** * Retrieves the number of stored objects. * * @returns Total count of cached objects. */ get size(): number; } export type GlobalCache = DEMGlobalCache; export declare const globalCache: DEMGlobalCache; /** * Permitted operation types for DEMArray asynchronous mutations. */ export type DEMArrayMutationOp = "push" | "pop" | "shift" | "unshift" | "splice" | "set" | "reverse" | "sort" | "clear"; /** * Socket payload structure for an array mutation request. */ export type DEMArrayMutationParams = Omit; export interface DEMArrayMutationRequest { /** * The specific mutation operator to execute. */ op: DEMArrayMutationOp; /** * Target property key holding the array. */ key: string; /** * Optional items to insert or append (primitive values, entity instances, or string IDs). */ items?: unknown[]; /** * Optional anchor entity identifier for positional mutations (splice/set). */ targetId?: string; /** * Optional list of anchor identifiers for multi-item splices. */ targetIds?: string[]; /** * Optional zero-based target offset. */ index?: number; /** * Optional count of elements to delete. */ deleteCount?: number; /** * Monotonic revision counter of the client state prior to mutation. */ baseRevision?: number; /** * Content hash of the array prior to mutation for concurrency verification. */ baseHash?: string; /** * Synchronized client timestamp when mutation was initiated. */ clientTimestamp?: number; } /** * Server acknowledgment payload returned for an array mutation request. */ export interface DEMArrayMutationResponse { /** * Whether the mutation succeeded and was persisted. */ success: boolean; /** * Optional error code on failure. */ code?: DEMErrorCode; /** * Optional descriptive message. */ message?: string; /** * The authoritative updated array state resolved and persisted by the server. */ updatedArray?: unknown[]; /** * Incremented monotonic revision counter after applying the mutation. */ newRevision?: number; /** * Content hash of the updated array. */ newHash?: string; } /** * Reactive array wrapper for DEM entity array properties. * Exposes synchronous ReadonlyArray queries and asynchronous mutation Promises. */ export interface DEMArray extends ReadonlyArray { /** * Appends elements asynchronously and awaits server persistence. * * @param items - Elements to append (entity instances, string IDs, or primitive values). * @returns Promise resolving to the new length of the array. * @throws {DEMError} Throws on network failure, validation rejection, or database error. */ push(...items: (T | string | ObjectId)[]): Promise; /** * Removes the last element asynchronously and awaits server persistence. * * @returns Promise resolving to the removed element, or undefined if empty. * @throws {DEMError} Throws on server rejection. */ pop(): Promise; /** * Removes the first element asynchronously and awaits server persistence. * * @returns Promise resolving to the removed element, or undefined if empty. * @throws {DEMError} Throws on server rejection. */ shift(): Promise; /** * Inserts elements at the start asynchronously and awaits server persistence. * * @param items - Elements to prepend. * @returns Promise resolving to the new length of the array. * @throws {DEMError} Throws on server rejection. */ unshift(...items: (T | string | ObjectId)[]): Promise; /** * Removes and/or inserts elements at an index asynchronously and awaits server persistence. * Anchors mutations to target element identifiers to eliminate positional drift under concurrency. * * @param start - Zero-based index at which to start changing the array. * @param deleteCount - Number of elements to remove. * @param items - Elements to insert. * @returns Promise resolving to an array containing the removed elements. * @throws {DEMError} Throws on server rejection. */ splice(start: number, deleteCount?: number, ...items: (T | string | ObjectId)[]): Promise; /** * Replaces an element at a specific index asynchronously and awaits server persistence. * * @param index - Target index to replace. * @param item - New value or entity to assign. * @returns Promise resolving to the assigned item. * @throws {DEMError} Throws on server rejection. */ set(index: number, item: T | string | ObjectId): Promise; /** * Reverses array elements in place asynchronously and awaits server persistence. * * @returns Promise resolving to this DEMArray. * @throws {DEMError} Throws on server rejection. */ reverse(): Promise; /** * Sorts array elements in place asynchronously and awaits server persistence. * * @param compareFn - Optional comparison function determining order. * @returns Promise resolving to this DEMArray. * @throws {DEMError} Throws on server rejection. */ sort(compareFn?: (a: T, b: T) => number): Promise; /** * Synchronous fill is prohibited on reactive DEMArray. * Declared for Array structural type compatibility. * * @param value - Value to fill array with. * @param start - Start index. * @param end - End index. * @returns This DEMArray. * @throws {DEMError} Throws CANNOT_SET_REF_DIRECTLY when invoked synchronously. */ fill(value: T, start?: number, end?: number): this; /** * Synchronous copyWithin is prohibited on reactive DEMArray. * Declared for Array structural type compatibility. * * @param target - Target start index. * @param start - Source start index. * @param end - Source end index. * @returns This DEMArray. * @throws {DEMError} Throws CANNOT_SET_REF_DIRECTLY when invoked synchronously. */ copyWithin(target: number, start: number, end?: number): this; /** * Clears all elements from the array asynchronously and awaits server persistence. * * @returns Promise resolving once the array is cleared. * @throws {DEMError} Throws on server rejection. */ clear(): Promise; /** * Hydrates all referenced entities in the array up to designated reference depth. * * @param options - Hydration options containing graph depth. * @returns Promise resolving to this DEMArray once all entities are hydrated. */ ensureLoaded(options?: { depth?: number; }): Promise; } export * from "./sync/types.js"; export * from "./sync/storage/IClientStorageAdapter.js"; export * from "./sync/storage/MemoryStorageAdapter.js"; export * from "./sync/storage/LocalStorageAdapter.js"; export * from "./sync/storage/IndexedDbStorageAdapter.js"; export * from "./sync/ServerChangeTracker.js"; export * from "./sync/ClientStateReconciler.js"; export * from "./DEMErrors.js";