/** * Domma Models Module - TypeScript Declarations * Pub/Sub events and reactive data binding */ export type TypeValidator = (value: any) => boolean; export interface FieldDefinition { type?: 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date' | 'any'; default?: any; required?: boolean; min?: number; max?: number; minLength?: number; maxLength?: number; pattern?: RegExp; validate?: (value: any) => boolean | string; } export interface Schema { [field: string]: FieldDefinition; } export interface ValidationResult { valid: boolean; errors: Array<{ field: string; error: string }>; } export interface ModelOptions { persist?: string; autoSave?: boolean; } export interface ChangeEvent { field: string; newValue: any; oldValue: any; model: Model; } export type ChangeCallback = (event: ChangeEvent) => void; export type FieldChangeCallback = (newValue: any, oldValue: any, model: Model) => void; export type UnsubscribeFn = () => void; export interface BindingOptions { format?: (value: any) => any; parse?: (value: any) => any; twoWay?: boolean; } /** * A lazily-evaluated, dependency-tracked derived value. */ export interface ComputedRef { /** Current value, recomputing only if a dependency changed. */ get(): T; /** Current value without registering a dependency on the caller. */ peek(): T; /** Unlink from the dependency graph. */ dispose(): void; } export interface ComputedOptions { /** Debug label used in console warnings. */ label?: string; /** Called with the new value whenever it changes. */ onChange?: (value: T) => void; } export interface EffectOptions { /** Debug label used in console warnings. */ label?: string; } /** * Reactive Model class */ export declare class Model { constructor(schema: Schema, data?: Record, options?: ModelOptions); /** * Get field value or all data. * Reads inside a computed or effect are tracked as dependencies. */ get(): Record; get(field: string): any; /** * Read-tracked, write-through view of the model's data. * Property reads register a dependency; writes route through set(), * preserving validation, change notification and persistence. */ tracked(): Record; /** Set field value(s) */ set(field: string, value: any): Model; set(data: Record): Model; /** Validate all fields */ validate(): ValidationResult; /** Get model data as JSON */ toJSON(): Record; /** Subscribe to any change; callback receives {field, newValue, oldValue, model} */ onChange(callback: ChangeCallback): UnsubscribeFn; /** Subscribe to changes on a single field; callback receives the same change object */ onChange(field: string, callback: ChangeCallback): UnsubscribeFn; /** Subscribe to specific field change */ onFieldChange(field: string, callback: FieldChangeCallback): UnsubscribeFn; /** Reset model to initial data */ reset(clearStorage?: boolean): Model; /** Destroy model and cleanup */ destroy(clearStorage?: boolean): void; // Persistence Methods /** Manually save model to localStorage */ save(): boolean; /** Manually load model from localStorage */ load(): boolean; /** Clear persisted data from localStorage */ clearStorage(): boolean; /** Get the persistence key */ getPersistKey(): string | null; /** Check if model is persisted */ isPersisted(): boolean; } export interface Store { /** Get current state */ getState(): Record; /** Update state with partial updates */ setState(updates: Record): void; /** Subscribe to state changes */ subscribe(listener: (state: Record, oldState: Record) => void): UnsubscribeFn; /** Reset state to initial or new state */ reset(newState?: Record): void; } export interface TypeValidators { string: TypeValidator; number: TypeValidator; boolean: TypeValidator; array: TypeValidator; object: TypeValidator; date: TypeValidator; any: TypeValidator; } export interface Models { // ============================================ // Pub/Sub Event System // ============================================ /** Subscribe to an event */ subscribe(event: string, callback: (data: any) => void): UnsubscribeFn; /** Alias for subscribe */ on(event: string, callback: (data: any) => void): UnsubscribeFn; /** Unsubscribe from an event */ unsubscribe(event: string, callback: (data: any) => void): void; /** Alias for unsubscribe */ off(event: string, callback: (data: any) => void): void; /** Publish an event */ publish(event: string, data?: any): void; /** Alias for publish */ emit(event: string, data?: any): void; /** Subscribe to an event once */ once(event: string, callback: (data: any) => void): UnsubscribeFn; /** Clear event listeners */ clear(event?: string): void; // ============================================ // Model Creation // ============================================ /** Create a new reactive model */ create(schema: Schema, initialData?: Record, options?: ModelOptions): Model; /** Extend a blueprint with additional fields */ extend(...blueprints: Schema[]): Schema; /** Pick specific fields from a blueprint */ pick(blueprint: Schema, fields: string[]): Schema; /** Omit specific fields from a blueprint */ omit(blueprint: Schema, fields: string[]): Schema; // ============================================ // Dependency-Tracked Reactivity // ============================================ /** * Create a lazily-evaluated derived value that tracks whatever it reads. * The body must be synchronous - tracking stops at the first `await`. */ computed(fn: () => T, options?: ComputedOptions): ComputedRef; /** * Run a function now, and again whenever any field it read changes. * Re-runs are batched into a single microtask flush. * Returns a function that stops the effect. */ effect(fn: () => void, options?: EffectOptions): UnsubscribeFn; /** Read values without registering them as dependencies. */ untracked(fn: () => T): T; /** Settle pending reactive work immediately instead of on the microtask. */ flush(): void; // ============================================ // Type Validators // ============================================ types: TypeValidators; // ============================================ // DOM Binding // ============================================ /** Bind a model field to DOM element(s) */ bind(model: Model, field: string, selector: string | HTMLElement, options?: BindingOptions): UnsubscribeFn; // ============================================ // Store (Simple State Management) // ============================================ /** Get or create a named store */ store(name: string, initialState?: Record): Store; /** Get an existing store */ getStore(name: string): Store | undefined; /** Remove a store */ removeStore(name: string): void; } export declare const models: Models;