{"version":3,"file":"useModuleState.mjs","sources":["../../../../src/lib/vdom/hooks/useModuleState.ts"],"sourcesContent":["/**\n * @file useModuleState Hook\n * @module vdom/hooks/useModuleState\n * @description Hook for managing isolated module state with type safety,\n * persistence support, and state synchronization capabilities.\n *\n * @author Agent 5 - PhD Virtual DOM Expert\n * @version 1.0.0\n */\n\nimport { useState, useCallback, useMemo, useEffect, useRef } from 'react';\nimport { type UseModuleStateReturn } from '../types';\nimport { useModuleContext } from '../ModuleBoundary';\n\n/**\n * Options for useModuleState hook.\n */\nexport interface UseModuleStateOptions<T> {\n  /** Initial state value */\n  initialValue: T;\n  /** Storage key for persistence */\n  storageKey?: string;\n  /** Whether to persist to sessionStorage instead of localStorage */\n  useSessionStorage?: boolean;\n  /** Custom serializer */\n  serialize?: (value: T) => string;\n  /** Custom deserializer */\n  deserialize?: (value: string) => T;\n  /** Validation function */\n  validate?: (value: unknown) => value is T;\n  /** Callback when state changes */\n  onChange?: (value: T, previousValue: T) => void;\n}\n\n/**\n * Hook for managing isolated module state.\n * Provides state isolation within module boundaries with optional persistence.\n *\n * @param key - State key (unique within module)\n * @param options - State options\n * @returns State value and setter utilities\n * @throws Error if used outside a ModuleBoundary\n *\n * @example\n * ```tsx\n * function Counter() {\n *   const { state, setState } = useModuleState('count', {\n *     initialValue: 0,\n *     storageKey: 'counter-value',\n *   });\n *\n *   return (\n *     <div>\n *       <p>Count: {state}</p>\n *       <button onClick={() => setState(state + 1)}>Increment</button>\n *       <button onClick={() => setState(prev => prev - 1)}>Decrement</button>\n *     </div>\n *   );\n * }\n * ```\n */\nexport function useModuleState<T>(\n  key: string,\n  options: UseModuleStateOptions<T>\n): UseModuleStateReturn<T> {\n  const context = useModuleContext();\n  const {\n    initialValue,\n    storageKey,\n    useSessionStorage = false,\n    serialize = JSON.stringify,\n    deserialize = JSON.parse,\n    validate,\n    onChange,\n  } = options;\n\n  // Track previous value for onChange callback\n  const previousValueRef = useRef<T>(initialValue);\n\n  // Initialize state from context or storage\n  const [localState, setLocalState] = useState<T>(() => {\n    // Check module context first\n    const contextValue = context.state.moduleState.get(key);\n    if (contextValue !== undefined) {\n      return contextValue as T;\n    }\n\n    // Check storage if persistence is enabled\n    if (storageKey !== null && storageKey !== undefined && storageKey !== '') {\n      try {\n        const storage = useSessionStorage ? sessionStorage : localStorage;\n        const stored = storage.getItem(storageKey);\n        if (stored !== null && stored !== undefined && stored !== '') {\n          const parsed: unknown = deserialize(stored);\n          if (!validate || validate(parsed as T)) {\n            return parsed as T;\n          }\n        }\n      } catch (error) {\n        console.warn(`Failed to load state from storage: ${storageKey}`, error);\n      }\n    }\n\n    return initialValue;\n  });\n\n  const [error, setError] = useState<Error | null>(null);\n  const isLoading = false; // State is loaded synchronously\n\n  // Sync with module context\n  useEffect(() => {\n    context.dispatch({\n      type: 'SET_STATE',\n      key,\n      value: localState,\n    });\n  }, [context, key, localState]);\n\n  // Persist to storage when state changes\n  useEffect(() => {\n    if (storageKey === null || storageKey === undefined || storageKey === '') {\n      return;\n    }\n\n    try {\n      const storage = useSessionStorage ? sessionStorage : localStorage;\n      storage.setItem(storageKey, serialize(localState));\n    } catch (error) {\n      console.warn(`Failed to persist state to storage: ${storageKey}`, error);\n    }\n  }, [localState, storageKey, serialize, useSessionStorage]);\n\n  // Call onChange when state changes\n  useEffect(() => {\n    if (localState !== previousValueRef.current) {\n      onChange?.(localState, previousValueRef.current);\n      previousValueRef.current = localState;\n    }\n  }, [localState, onChange]);\n\n  // Set state with validation\n  const setState = useCallback(\n    (valueOrUpdater: T | ((prev: T) => T)) => {\n      setLocalState((prev) => {\n        const newValue =\n          typeof valueOrUpdater === 'function'\n            ? (valueOrUpdater as (prev: T) => T)(prev)\n            : valueOrUpdater;\n\n        if (validate && !validate(newValue)) {\n          setError(new Error(`Invalid state value for key: ${key}`));\n          return prev;\n        }\n\n        setError(null);\n        return newValue;\n      });\n    },\n    [key, validate]\n  );\n\n  // Merge partial state (for object states)\n  const mergeState = useCallback(\n    (partial: Partial<T>) => {\n      setLocalState((prev) => {\n        if (typeof prev !== 'object' || prev === null) {\n          console.warn('mergeState called on non-object state');\n          return prev;\n        }\n\n        const newValue = { ...prev, ...partial } as T;\n\n        if (validate && !validate(newValue)) {\n          setError(new Error(`Invalid merged state for key: ${key}`));\n          return prev;\n        }\n\n        setError(null);\n        return newValue;\n      });\n    },\n    [key, validate]\n  );\n\n  // Reset to initial value\n  const resetState = useCallback(() => {\n    setLocalState(initialValue);\n    setError(null);\n\n    // Clear from storage\n    if (storageKey !== null && storageKey !== undefined && storageKey !== '') {\n      try {\n        const storage = useSessionStorage ? sessionStorage : localStorage;\n        storage.removeItem(storageKey);\n      } catch {\n        // Ignore storage errors\n      }\n    }\n  }, [initialValue, storageKey, useSessionStorage]);\n\n  // Return memoized object\n  return useMemo<UseModuleStateReturn<T>>(\n    () => ({\n      state: localState,\n      setState,\n      mergeState,\n      resetState,\n      isLoading,\n      error,\n    }),\n    [localState, setState, mergeState, resetState, isLoading, error]\n  );\n}\n\n/**\n * Simplified hook for module state without persistence.\n * @param key - State key\n * @param initialValue - Initial value\n * @returns State and setter\n *\n * @example\n * ```tsx\n * const [name, setName] = useSimpleModuleState('userName', '');\n * ```\n */\nexport function useSimpleModuleState<T>(\n  key: string,\n  initialValue: T\n): [T, (value: T | ((prev: T) => T)) => void] {\n  const { state, setState } = useModuleState(key, { initialValue });\n  return [state, setState];\n}\n\n/**\n * Hook for boolean module state with toggle functionality.\n * @param key - State key\n * @param initialValue - Initial boolean value\n * @returns Boolean state with utilities\n *\n * @example\n * ```tsx\n * const { value, toggle, setTrue, setFalse } = useBooleanModuleState('isOpen', false);\n * ```\n */\nexport function useBooleanModuleState(\n  key: string,\n  initialValue: boolean = false\n): {\n  value: boolean;\n  toggle: () => void;\n  setTrue: () => void;\n  setFalse: () => void;\n  setValue: (value: boolean) => void;\n} {\n  const { state, setState } = useModuleState(key, { initialValue });\n\n  const toggle = useCallback(() => {\n    setState((prev) => !prev);\n  }, [setState]);\n\n  const setTrue = useCallback(() => {\n    setState(true);\n  }, [setState]);\n\n  const setFalse = useCallback(() => {\n    setState(false);\n  }, [setState]);\n\n  return useMemo(\n    () => ({\n      value: state,\n      toggle,\n      setTrue,\n      setFalse,\n      setValue: setState,\n    }),\n    [state, toggle, setTrue, setFalse, setState]\n  );\n}\n\n/**\n * Hook for array module state with common array operations.\n * @param key - State key\n * @param initialValue - Initial array value\n * @returns Array state with utilities\n *\n * @example\n * ```tsx\n * const { items, add, remove, update, clear } = useArrayModuleState('todos', []);\n *\n * // Add item\n * add({ id: '1', text: 'New todo' });\n *\n * // Remove item\n * remove((item) => item.id === '1');\n * ```\n */\nexport function useArrayModuleState<T>(\n  key: string,\n  initialValue: T[] = []\n): {\n  items: T[];\n  add: (item: T) => void;\n  addMany: (items: T[]) => void;\n  remove: (predicate: (item: T) => boolean) => void;\n  update: (predicate: (item: T) => boolean, updater: (item: T) => T) => void;\n  clear: () => void;\n  setItems: (items: T[] | ((prev: T[]) => T[])) => void;\n} {\n  const { state, setState, resetState } = useModuleState(key, { initialValue });\n\n  const add = useCallback(\n    (item: T) => {\n      setState((prev) => [...prev, item]);\n    },\n    [setState]\n  );\n\n  const addMany = useCallback(\n    (items: T[]) => {\n      setState((prev) => [...prev, ...items]);\n    },\n    [setState]\n  );\n\n  const remove = useCallback(\n    (predicate: (item: T) => boolean) => {\n      setState((prev) => prev.filter((item) => !predicate(item)));\n    },\n    [setState]\n  );\n\n  const update = useCallback(\n    (predicate: (item: T) => boolean, updater: (item: T) => T) => {\n      setState((prev) => prev.map((item) => (predicate(item) ? updater(item) : item)));\n    },\n    [setState]\n  );\n\n  return useMemo(\n    () => ({\n      items: state,\n      add,\n      addMany,\n      remove,\n      update,\n      clear: resetState,\n      setItems: setState,\n    }),\n    [state, add, addMany, remove, update, resetState, setState]\n  );\n}\n\n/**\n * Hook for map/record module state.\n * @param key - State key\n * @param initialValue - Initial record value\n * @returns Record state with utilities\n */\nexport function useRecordModuleState<K extends string, V>(\n  key: string,\n  initialValue: Record<K, V> = {} as Record<K, V>\n): {\n  record: Record<K, V>;\n  get: (key: K) => V | undefined;\n  set: (key: K, value: V) => void;\n  remove: (key: K) => void;\n  has: (key: K) => boolean;\n  clear: () => void;\n  setRecord: (record: Record<K, V>) => void;\n} {\n  const { state, setState, resetState } = useModuleState(key, { initialValue });\n\n  const get = useCallback((recordKey: K): V | undefined => state[recordKey], [state]);\n\n  const set = useCallback(\n    (recordKey: K, value: V) => {\n      setState((prev) => ({ ...prev, [recordKey]: value }));\n    },\n    [setState]\n  );\n\n  const remove = useCallback(\n    (recordKey: K) => {\n      setState((prev) => {\n        const next = { ...prev };\n        delete next[recordKey];\n        return next;\n      });\n    },\n    [setState]\n  );\n\n  const has = useCallback((recordKey: K): boolean => recordKey in state, [state]);\n\n  return useMemo(\n    () => ({\n      record: state,\n      get,\n      set,\n      remove,\n      has,\n      clear: resetState,\n      setRecord: setState,\n    }),\n    [state, get, set, remove, has, resetState, setState]\n  );\n}\n"],"names":["useModuleState","key","options","context","useModuleContext","initialValue","storageKey","useSessionStorage","serialize","deserialize","validate","onChange","previousValueRef","useRef","localState","setLocalState","useState","contextValue","stored","parsed","error","setError","isLoading","useEffect","setState","useCallback","valueOrUpdater","prev","newValue","mergeState","partial","resetState","useMemo","useSimpleModuleState","state","useBooleanModuleState","toggle","setTrue","setFalse","useArrayModuleState","add","item","addMany","items","remove","predicate","update","updater","useRecordModuleState","get","recordKey","set","value","next","has"],"mappings":"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"}