import { T as Transport, S as SavePayload, a as SaveResult, F as FormSubset, V as ValidationStrategy } from './types-AVkW6yHf.js'; export { A as AutosaveConfig, b as SaveContext, c as Timer } from './types-AVkW6yHf.js'; import { FieldValues } from 'react-hook-form'; declare class AutosaveError extends Error { code: string; originalError?: Error | undefined; metadata?: Record | undefined; constructor(message: string, code: string, originalError?: Error | undefined, metadata?: Record | undefined); static fromUnknown(error: unknown, code?: string): AutosaveError; } declare class TransportError extends AutosaveError { constructor(message: string, originalError?: Error); } declare class ValidationError extends AutosaveError { failedFields?: string[] | undefined; constructor(message: string, failedFields?: string[] | undefined); } declare class DiffError extends AutosaveError { field?: string | undefined; constructor(message: string, field?: string | undefined, originalError?: Error); } interface Logger { debug(message: string, meta?: any): void; info(message: string, meta?: any): void; warn(message: string, meta?: any): void; error(message: string, error?: Error, meta?: any): void; } declare function createLogger(namespace: string, enabled?: boolean): Logger; declare class AutosaveManager { private transport; private readonly debounceMs; private readonly logger?; private readonly timer; private pending; private isInflight; private shouldRerun; private abortController; private retryCount; private readonly maxRetries; constructor(transport: Transport, debounceMs?: number, // Keep for backward compatibility but won't use internal debouncing logger?: Logger | undefined, timer?: { setTimeout: typeof setTimeout; clearTimeout: typeof clearTimeout; }); /** Update the transport after construction. Used by useRhfAutosave to inject the composed transport. */ setTransport(transport: Transport): void; queueChange(delta: SavePayload): void; flush(): Promise; abort(): void; isEmpty(): boolean; getPendingChanges(): Readonly; private takePendingPayload; private handleFailure; } type KeyMap = Record any]>; declare function mapKeys(payload: Record, keyMap: KeyMap): Record; declare function createKeyMapper(keyMap: KeyMap): (payload: Record) => Record; type ConflictResolution = "client" | "server" | "merge"; interface AutosaveConfig { debug: boolean; debounceMs: number; maxRetries: number; enableMetrics: boolean; enableCache: boolean; cacheSize: number; cacheTtlMs: number; maxPayloadSize?: number; rateLimitMs: number; offlineSupport: boolean; conflictResolution: ConflictResolution; } interface DiffHandler { idOf: (item: any) => string | number; onAdd: (item: any) => Promise | void; onRemove: (item: any) => Promise | void; } interface UndoOptions { enabled?: boolean; /** Skip autosave after undo/redo; call forceSave() manually if you enable this. */ ignoreHistoryOps?: boolean; /** Enable keyboard shortcuts (Cmd/Ctrl+Z, Shift+Cmd/Ctrl+Z). Default: true */ hotkeys?: boolean; /** * If false, do NOT intercept when focus is in inputs/textareas/contentEditable. * If true, intercept everywhere. Default: false (safer). */ captureInInputs?: boolean; /** Where to attach the listener. Default: document */ target?: Document | HTMLElement; } type AutosaveStatus = { state: 'idle'; } | { state: 'saving'; } | { state: 'saved'; } | { state: 'error'; error: Error; }; interface RhfAutosaveOptions { form: FormSubset; transport: Transport; config?: Partial; hasPendingChanges?: boolean; selectPayload?: (values: T, dirtyFields: any) => Partial; shouldSave?: (ctx: { values: T; isValid: boolean; isDirty: boolean; dirtyFields: any; }) => boolean; onSaved?: (result: any, payload: SavePayload) => void; onStatusChange?: (status: AutosaveStatus) => void; keyMap?: KeyMap; mapPayload?: (payload: Record) => Record; validateBeforeSave?: ValidationMode$1; diffMap?: Record; undo?: UndoOptions; autoHydrate?: boolean; } type ValidationMode$1 = "none" | "payload" | "all"; interface AutosaveReturn { isSaving: boolean; lastError: Error | null; metrics: any; hasPendingChanges: boolean; flush: () => Promise; abort: () => void; forceSave: () => Promise; forceBaselineUpdate: () => void; getBaseline: () => Record | null; isBaselineInitialized: () => boolean; getMetrics: () => any; getCacheStats: () => any; getPendingChanges: () => any; isEmpty: () => boolean; undo: (() => void) | undefined; redo: (() => void) | undefined; undoLastSave: (() => void) | undefined; canUndo: boolean; canRedo: boolean; hydrateFromServer: (data: any) => void; } declare function useRhfAutosave(options: RhfAutosaveOptions): AutosaveReturn; /** * Wrap a tRPC mutation as an autosave `Transport`. * * This lets you pass a tRPC mutation directly into `useRhfAutosave` or `useAutosaveEngine`. * * @example * ```ts * const mutation = api.regulation.update.useMutation(); * const transport = trpcTransport(mutation); * * useRhfAutosave({ * form, * transport, * }); * ``` * * @typeParam TInput - Input shape expected by the tRPC mutation. */ declare function trpcTransport(mutation: { mutateAsync: (input: TInput, opts?: any) => Promise; }): Transport; declare class NoValidationStrategy implements ValidationStrategy { validate(): Promise; } declare class PayloadValidationStrategy implements ValidationStrategy { validate(form: FormSubset, payload: SavePayload): Promise; } declare class AllFieldsValidationStrategy implements ValidationStrategy { validate(form: FormSubset): Promise; } type ValidationMode = "none" | "payload" | "all"; declare function createValidationStrategy(mode?: ValidationMode): ValidationStrategy; interface RetryConfig { maxRetries: number; baseDelayMs: number; maxDelayMs: number; backoffFactor: number; } declare function withRetry(transport: Transport, config?: Partial, logger?: Logger): Transport; declare function composeTransports(...transports: Transport[]): Transport; declare function parallelTransports(...transports: Transport[]): Transport; interface FetchTransportOptions { /** HTTP method. Default: 'POST' */ method?: string; /** Extra headers, merged with Content-Type: application/json */ headers?: Record; /** Fetch credentials mode. Default: 'same-origin' */ credentials?: RequestCredentials; /** Transform payload before JSON.stringify */ mapBody?: (payload: SavePayload) => unknown; } declare function fetchTransport(url: string, options?: FetchTransportOptions): Transport; interface ServerActionTransportOptions { /** Transform payload before calling the action */ mapPayload?: (payload: SavePayload) => unknown; /** Interpret the action's return value as a SaveResult */ mapResult?: (result: unknown) => SaveResult; } declare function serverActionTransport(action: (data: unknown) => Promise, options?: ServerActionTransportOptions): Transport; interface AutosaveState { isSaving: boolean; lastError: Error | null; baseline: Record | null; isBaselineInitialized: boolean; config: object; metrics: { totalSaves: number; successfulSaves: number; failedSaves: number; averageSaveTime: number; }; } type AutosaveAction = { type: "SAVE_START"; } | { type: "SAVE_SUCCESS"; duration: number; } | { type: "SAVE_ERROR"; error: Error; duration: number; } | { type: "UPDATE_BASELINE"; baseline: Record; } | { type: "INITIALIZE_BASELINE"; baseline: Record; } | { type: "RESET_BASELINE"; } | { type: "ABORT"; }; declare const initialAutosaveState: AutosaveState; declare function autosaveReducer(state: AutosaveState, action: AutosaveAction): AutosaveState; /** * Extracts only the "dirty" (changed) values from a form state. * Supports both flat and nested objects. */ declare function pickChanged>(values: T, dirty: any): Partial; interface DebouncedFunction any> { (...args: Parameters): void; cancel(): void; flush(): ReturnType | undefined; pending(): boolean; } declare function debounce any>(func: T, waitMs: number, timer?: { setTimeout: typeof setTimeout; clearTimeout: typeof clearTimeout; }): DebouncedFunction; /** * Field Path Utilities * Utilities for working with nested field paths in forms * Supports both dot notation (user.profile.name) and bracket notation (user[0].name) */ type FieldPath$1 = string; type PathSegment = string | number; /** * Parse a field path string into an array of segments * Supports: 'user.name', 'user[0]', 'user[0].name', 'user.items[0].value' * * @example * parsePath('user.profile.name') // ['user', 'profile', 'name'] * parsePath('users[0].name') // ['users', 0, 'name'] * parsePath('items[0][1]') // ['items', 0, 1] */ declare function parsePath(path: string): PathSegment[]; /** * Convert path segments back to a string path * * @example * joinPath(['user', 'profile', 'name']) // 'user.profile.name' * joinPath(['users', 0, 'name']) // 'users[0].name' */ declare function joinPath(segments: PathSegment[]): string; /** * Get a value from an object using a path * * @example * getByPath({ user: { name: 'John' } }, 'user.name') // 'John' * getByPath({ users: [{ name: 'John' }] }, 'users[0].name') // 'John' */ declare function getByPath(obj: any, path: string | PathSegment[]): T | undefined; /** * Set a value in an object using a path * Creates intermediate objects/arrays as needed * * @example * const obj = {}; * setByPath(obj, 'user.name', 'John'); * // obj = { user: { name: 'John' } } * * setByPath(obj, 'users[0].name', 'Jane'); * // obj = { users: [{ name: 'Jane' }] } */ declare function setByPath(obj: any, path: string | PathSegment[], value: any): void; /** * Delete a value from an object using a path * * @example * const obj = { user: { name: 'John', age: 30 } }; * deleteByPath(obj, 'user.age'); * // obj = { user: { name: 'John' } } */ declare function deleteByPath(obj: any, path: string | PathSegment[]): boolean; /** * Check if a path exists in an object * * @example * hasPath({ user: { name: 'John' } }, 'user.name') // true * hasPath({ user: { name: 'John' } }, 'user.age') // false */ declare function hasPath(obj: any, path: string | PathSegment[]): boolean; /** * Get the parent path of a field path * * @example * getParentPath('user.profile.name') // 'user.profile' * getParentPath('users[0].name') // 'users[0]' * getParentPath('name') // '' */ declare function getParentPath(path: string): string; /** * Get the last segment of a field path * * @example * getFieldName('user.profile.name') // 'name' * getFieldName('users[0]') // 0 * getFieldName('name') // 'name' */ declare function getFieldName(path: string): PathSegment; /** * Check if a path is a parent of another path * * @example * isParentPath('user', 'user.name') // true * isParentPath('user.profile', 'user.profile.name') // true * isParentPath('user.name', 'user.email') // false */ declare function isParentPath(parentPath: string, childPath: string): boolean; /** * Check if a path is a child of another path * * @example * isChildPath('user.name', 'user') // true * isChildPath('user.profile.name', 'user') // true * isChildPath('user.email', 'user.profile') // false */ declare function isChildPath(childPath: string, parentPath: string): boolean; /** * Get all paths in an object (flattened) * * @example * getAllPaths({ user: { name: 'John', age: 30 } }) * // ['user', 'user.name', 'user.age'] * * getAllPaths({ users: [{ name: 'John' }] }) * // ['users', 'users[0]', 'users[0].name'] */ declare function getAllPaths(obj: any, prefix?: string, includeArrays?: boolean): string[]; /** * Convert bracket notation to dot notation where possible * * @example * normalizePath('user.profile.name') // 'user.profile.name' * normalizePath('users[0].name') // 'users.0.name' */ declare function normalizePath(path: string): string; /** * Deep clone an object following a specific path * Only clones objects along the path, other references remain shallow * * @example * const obj = { user: { name: 'John', settings: { theme: 'dark' } } }; * const cloned = cloneAlongPath(obj, 'user.name'); * cloned.user.name = 'Jane'; // obj.user.name is still 'John' * cloned.user.settings === obj.user.settings // true (shallow copy) */ declare function cloneAlongPath(obj: any, path: string | PathSegment[]): any; /** * Nested Key Mapping Utilities * Extension of mapKeys to support nested field paths * Allows transforming nested form fields to match API structure */ type NestedKeyMap = Record any] | { to: string; transform?: (v: any) => any; flatten?: boolean; }>; interface NestedMapKeysOptions { /** * If true, unmapped fields are preserved * If false, only mapped fields are included */ preserveUnmapped?: boolean; /** * If true, automatically flatten single-value nested objects * e.g., { user: { name: "John" } } -> { user_name: "John" } */ autoFlatten?: boolean; /** * Separator to use when flattening nested keys * Default: "_" */ flattenSeparator?: string; } /** * Map nested keys in a payload according to a nested key map * Supports path-based transformations and restructuring * * @example * const payload = { * user: { * firstName: "John", * lastName: "Doe", * profile: { * email: "john@example.com" * } * } * }; * * const keyMap = { * "user.firstName": "user.first_name", * "user.profile.email": { * to: "contact_email", * flatten: true * } * }; * * mapNestedKeys(payload, keyMap); * // Result: * // { * // user: { * // first_name: "John", * // lastName: "Doe" * // }, * // contact_email: "john@example.com" * // } */ declare function mapNestedKeys(payload: Record, keyMap: NestedKeyMap, options?: NestedMapKeysOptions): Record; /** * Create a reusable mapper function for nested keys * * @example * const mapper = createNestedKeyMapper({ * "user.firstName": "user.first_name", * "user.lastName": "user.last_name" * }); * * const result = mapper(formData); */ declare function createNestedKeyMapper(keyMap: NestedKeyMap, options?: NestedMapKeysOptions): (payload: Record) => Record; /** * Reverse a nested key map (swap source and target paths) * Useful for mapping API responses back to form structure * * @example * const formToApi = { * "user.firstName": "user.first_name" * }; * const apiToForm = reverseNestedKeyMap(formToApi); * // { "user.first_name": "user.firstName" } */ declare function reverseNestedKeyMap(keyMap: NestedKeyMap): NestedKeyMap; /** * Flatten a nested object to dot notation keys * * @example * flattenObject({ user: { name: "John", age: 30 } }) * // { "user.name": "John", "user.age": 30 } */ declare function flattenObject(obj: Record, separator?: string, prefix?: string): Record; /** * Unflatten an object with dot notation keys to nested structure * * @example * unflattenObject({ "user.name": "John", "user.age": 30 }) * // { user: { name: "John", age: 30 } } */ declare function unflattenObject(obj: Record, separator?: string): Record; /** * Merge nested key maps together * Later maps override earlier ones * * @example * const base = { "user.name": "user.full_name" }; * const override = { "user.email": "contact.email" }; * mergeNestedKeyMaps(base, override); * // { "user.name": "user.full_name", "user.email": "contact.email" } */ declare function mergeNestedKeyMaps(...keyMaps: NestedKeyMap[]): NestedKeyMap; /** * Validate that a nested key map doesn't have conflicting mappings * Returns array of conflicts or empty array if valid * * @example * const keyMap = { * "user.name": "userName", * "user": "userName" // Conflict! * }; * validateNestedKeyMap(keyMap); * // ["user -> userName conflicts with user.name -> userName"] */ declare function validateNestedKeyMap(keyMap: NestedKeyMap): string[]; /** * Nested Array Diffing Utilities * Utilities for tracking and computing changes in arrays of objects * Supports detecting additions, removals, modifications, and reordering */ interface ArrayDiffOptions { /** * Key field to use for identifying items (default: 'id') */ identityKey?: string; /** * If true, track field-level changes within items * If false, treat modified items as entirely changed */ trackFieldChanges?: boolean; /** * If true, detect and report reordering */ trackOrder?: boolean; /** * Custom equality function for comparing values */ equalityFn?: (a: any, b: any) => boolean; } interface ArrayDiffResult { /** * Items that were added */ added: T[]; /** * Items that were removed */ removed: T[]; /** * Items that were modified (with before/after state) */ modified: Array<{ before: T; after: T; changes?: Record; }>; /** * Items that were reordered (only if trackOrder is true) */ reordered?: Array<{ item: T; oldIndex: number; newIndex: number; }>; /** * True if there are any changes */ hasChanges: boolean; } /** * Compute the difference between two arrays of objects * Identifies additions, removals, modifications, and optionally reordering * * @example * const oldArray = [ * { id: 1, name: 'Alice', age: 25 }, * { id: 2, name: 'Bob', age: 30 } * ]; * const newArray = [ * { id: 1, name: 'Alice', age: 26 }, // Modified * { id: 3, name: 'Charlie', age: 35 } // Added * ]; * * const diff = diffArrays(oldArray, newArray); * // { * // added: [{ id: 3, name: 'Charlie', age: 35 }], * // removed: [{ id: 2, name: 'Bob', age: 30 }], * // modified: [{ * // before: { id: 1, name: 'Alice', age: 25 }, * // after: { id: 1, name: 'Alice', age: 26 }, * // changes: { age: { before: 25, after: 26 } } * // }] * // } */ declare function diffArrays>(oldArray: T[], newArray: T[], options?: ArrayDiffOptions): ArrayDiffResult; /** * Apply an array diff to get the new array * Useful for applying changes from a diff result * * @example * const oldArray = [{ id: 1, name: 'Alice' }]; * const diff = { added: [{ id: 2, name: 'Bob' }], removed: [], modified: [] }; * const newArray = applyArrayDiff(oldArray, diff); * // [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }] */ declare function applyArrayDiff>(array: T[], diff: ArrayDiffResult, identityKey?: string): T[]; /** * Detect changes in nested array fields within objects * Compares arrays at specified paths and returns diffs * * @example * const oldObj = { * users: [ * { id: 1, name: 'Alice' }, * { id: 2, name: 'Bob' } * ] * }; * const newObj = { * users: [ * { id: 1, name: 'Alice' }, * { id: 3, name: 'Charlie' } * ] * }; * * const diffs = detectNestedArrayChanges(oldObj, newObj, ['users']); * // { 'users': { added: [{ id: 3, ...}], removed: [{ id: 2, ... }], ... } } */ declare function detectNestedArrayChanges(oldObj: Record, newObj: Record, arrayPaths: string[], options?: ArrayDiffOptions): Record; /** * Find all array fields in an object * Returns paths to all array fields * * @example * const obj = { * users: [{ id: 1 }], * settings: { items: [1, 2, 3] } * }; * findArrayFields(obj); * // ['users', 'settings.items'] */ declare function findArrayFields(obj: Record): string[]; /** * Create a summary of array changes suitable for logging or display * * @example * const diff = diffArrays(oldArray, newArray); * const summary = summarizeArrayDiff(diff); * // "+1 added, -1 removed, 2 modified" */ declare function summarizeArrayDiff(diff: ArrayDiffResult): string; /** * Merge multiple array diffs together * Useful when combining diffs from different sources */ declare function mergeArrayDiffs>(...diffs: ArrayDiffResult[]): ArrayDiffResult; /** * Deep Merge and Update Utilities * Utilities for merging and updating nested objects safely * Supports arrays, custom merge strategies, and immutable updates */ interface DeepMergeOptions { /** * How to handle array merging * - 'replace': Replace entire array (default) * - 'concat': Concatenate arrays * - 'merge': Merge arrays by identity key */ arrayMergeStrategy?: 'replace' | 'concat' | 'merge'; /** * Identity key for array merging (when using 'merge' strategy) */ arrayIdentityKey?: string; /** * If true, create a new object instead of mutating */ immutable?: boolean; /** * Custom merge function for specific keys */ customMergers?: Record any>; /** * Maximum depth to merge (prevents infinite recursion) */ maxDepth?: number; } /** * Deep merge two objects * Recursively merges nested objects and handles arrays according to strategy * * @example * const target = { user: { name: 'John', age: 30 } }; * const source = { user: { age: 31, email: 'john@example.com' } }; * * deepMerge(target, source); * // { user: { name: 'John', age: 31, email: 'john@example.com' } } */ declare function deepMerge>(target: T, source: Record, options?: DeepMergeOptions): T; /** * Update nested fields in an object immutably * Returns a new object with updates applied * * @example * const obj = { user: { name: 'John', age: 30 } }; * const updated = deepUpdate(obj, { * 'user.age': 31, * 'user.email': 'john@example.com' * }); * // { user: { name: 'John', age: 31, email: 'john@example.com' } } */ declare function deepUpdate>(obj: T, updates: Record): T; /** * Deep clone an object * Handles nested objects, arrays, dates, and other special types * * @example * const obj = { user: { name: 'John', tags: ['a', 'b'] } }; * const cloned = cloneDeep(obj); * cloned.user.name = 'Jane'; * // obj.user.name is still 'John' */ declare function cloneDeep(obj: T): T; /** * Safely merge objects at a specific path * Only merges the object at the given path, keeping everything else intact * * @example * const obj = { * user: { name: 'John', age: 30 }, * settings: { theme: 'dark' } * }; * * mergeAtPath(obj, 'user', { email: 'john@example.com' }); * // { * // user: { name: 'John', age: 30, email: 'john@example.com' }, * // settings: { theme: 'dark' } * // } */ declare function mergeAtPath>(obj: T, path: string, updates: any, options?: DeepMergeOptions): T; /** * Check if two values are deeply equal * Handles nested objects, arrays, dates, etc. * * @example * isDeepEqual({ a: { b: 1 } }, { a: { b: 1 } }) // true * isDeepEqual({ a: [1, 2] }, { a: [1, 2] }) // true */ declare function isDeepEqual(a: any, b: any): boolean; /** * Get the difference between two objects as a set of paths and values * Returns only the fields that changed * * @example * const old = { user: { name: 'John', age: 30 } }; * const new = { user: { name: 'John', age: 31 } }; * * getDiff(old, new); * // { 'user.age': { old: 30, new: 31 } } */ declare function getDiff(oldObj: Record, newObj: Record, prefix?: string): Record; /** * Apply a set of path-based updates to an object * Similar to deepUpdate but takes old/new value pairs * * @example * const obj = { user: { name: 'John', age: 30 } }; * const diff = { 'user.age': { old: 30, new: 31 } }; * * applyDiff(obj, diff); * // { user: { name: 'John', age: 31 } } */ declare function applyDiff>(obj: T, diff: Record): T; interface CacheEntry { result: SaveResult; timestamp: number; hits: number; } declare class PayloadCache { private readonly maxSize; private readonly ttlMs; private cache; constructor(maxSize?: number, ttlMs?: number); get(key: string): SaveResult | null; set(key: string, result: SaveResult): void; clear(): void; size(): number; has(key: string): boolean; delete(key: string): boolean; keys(): string[]; entries(): Array<[string, CacheEntry]>; getStats(): { size: number; totalHits: number; averageHits: number; oldestEntry: number; newestEntry: number; }; private isExpired; private cleanup; } declare class ValidationCache { private readonly maxSize; private cache; constructor(maxSize?: number); get(key: string): boolean | undefined; set(key: string, valid: boolean): void; clear(): void; size(): number; has(key: string): boolean; delete(key: string): boolean; keys(): string[]; entries(): Array<[string, boolean]>; private cleanup; } interface AutosaveMetrics { totalSaves: number; successfulSaves: number; failedSaves: number; averageDebounceTime: number; averageSaveTime: number; cacheHits: number; cacheMisses: number; retryCount: number; } declare class MetricsCollector { private enabled; constructor(enabled?: boolean); private metrics; recordSave(duration: number, success: boolean): void; recordCacheHit(): void; recordCacheMiss(): void; recordRetry(): void; recordDebounce(duration: number): void; getMetrics(): Readonly; getSuccessRate(): number; getCacheHitRate(): number; reset(): void; private updateAverageSaveTime; private updateAverageDebounceTime; } /** * Shows a browser confirmation dialog when the user tries to close/reload the tab * while there are unsaved changes. */ declare function useBeforeUnload(shouldBlock: boolean): void; type FieldPath = string; type PendingChanges = Set; type DeepEqualFn = (a: any, b: any) => boolean; type GetterFn = (obj: any, path: FieldPath) => any; type UndoRedoOptions = { initialValuesRef: { current: any; }; deepEqual: DeepEqualFn; get: GetterFn; }; declare function isPending(name: FieldPath, currentValue: unknown, opts: UndoRedoOptions): boolean; declare function reconcilePendingField(name: FieldPath, currentValue: unknown, pending: PendingChanges, opts: UndoRedoOptions): void; export { AllFieldsValidationStrategy, type ArrayDiffOptions, type ArrayDiffResult, type AutosaveAction, AutosaveError, AutosaveManager, type AutosaveMetrics, type AutosaveReturn, type AutosaveState, type AutosaveStatus, type DebouncedFunction, type DeepMergeOptions, DiffError, type DiffHandler, type FetchTransportOptions, type FieldPath$1 as FieldPath, FormSubset, type KeyMap, type Logger, MetricsCollector, type NestedKeyMap, type NestedMapKeysOptions, NoValidationStrategy, type PathSegment, PayloadCache, PayloadValidationStrategy, type RetryConfig, type RhfAutosaveOptions, SavePayload, SaveResult, type ServerActionTransportOptions, Transport, TransportError, type UndoOptions, ValidationCache, ValidationError, type ValidationMode, ValidationStrategy, applyArrayDiff, applyDiff, autosaveReducer, cloneAlongPath, cloneDeep, composeTransports, createKeyMapper, createLogger, createNestedKeyMapper, createValidationStrategy, debounce, deepMerge, deepUpdate, deleteByPath, detectNestedArrayChanges, diffArrays, fetchTransport, findArrayFields, flattenObject, getAllPaths, getByPath, getDiff, getFieldName, getParentPath, hasPath, initialAutosaveState, isChildPath, isDeepEqual, isParentPath, isPending, joinPath, mapKeys, mapNestedKeys, mergeArrayDiffs, mergeAtPath, mergeNestedKeyMaps, normalizePath, parallelTransports, parsePath, pickChanged, reconcilePendingField, reverseNestedKeyMap, serverActionTransport, setByPath, summarizeArrayDiff, trpcTransport, unflattenObject, useBeforeUnload, useRhfAutosave, validateNestedKeyMap, withRetry };