{"version":3,"file":"index.mjs","names":[],"sources":["../../../src/hooks/useSessionStorage/index.ts"],"sourcesContent":["import { isFunction } from '@modern-kit/utils';\nimport {\n  Dispatch,\n  SetStateAction,\n  useCallback,\n  useMemo,\n  useSyncExternalStore,\n} from 'react';\nimport {\n  getServerSnapshot,\n  getSnapshot,\n  sessionStorageEventHandler,\n  subscribe,\n  getParsedState,\n} from './useSessionStorage.utils';\n\nimport { StorageManager } from '@modern-kit/utils';\n\nconst storageManager = new StorageManager('sessionStorage');\n\ninterface UseSessionStorageWithoutInitialValueOptions {\n  key: string;\n}\n\ninterface UseSessionStorageWithInitialValueOptions<T> {\n  key: string;\n  initialValue: T | (() => T);\n}\n\ntype UseSessionStorageOptions<T> =\n  | UseSessionStorageWithoutInitialValueOptions\n  | UseSessionStorageWithInitialValueOptions<T>;\n\n/**\n * @description `useSessionStorage` 훅은 지정된 `key`를 사용하여 `sessionStorage`에 데이터를 저장하고 불러오는 기능을 제공합니다.\n *\n * @template T - `state`의 데이터 타입입니다.\n *\n * @param {UseSessionStorageWithInitialValueOptions<T>} options - initialValue를 포함한 useSessionStorage 훅의 속성입니다.\n * @param {string} options.key - `sessionStorage`에서 데이터를 저장하고 가져올 때 사용하는 키입니다. 필수 속성입니다.\n * @param {T | (() => T)} options.initialValue - `state`의 초기 값을 설정합니다. 함수로 전달할 경우 함수의 반환값이 초기 값으로 사용됩니다.\n *\n * @returns {{\n *  state: T;\n *  setState: Dispatch<SetStateAction<T>>;\n *  removeState: () => void;\n * }}\n * - `state`: 현재 `sessionStorage`에 저장된 값입니다. 값이 없을 경우 initialValue로 초기화됩니다.\n * - `setState`: `sessionStorage`에 저장된 값을 업데이트합니다. 새로운 값 또는 이전 상태를 인자로 받는 함수를 전달할 수 있습니다.\n * - `removeState`: `sessionStorage`에서 해당 `key`의 값을 삭제합니다.\n *\n * @example\n * const { state, setState, removeState } = useSessionStorage<string>({\n *   key: 'username',\n *   initialValue: 'Guest',\n * });\n *\n * state; // string\n */\nexport function useSessionStorage<T>({\n  key,\n  initialValue,\n}: UseSessionStorageWithInitialValueOptions<T>): {\n  state: T;\n  setState: Dispatch<SetStateAction<T>>;\n  removeState: () => void;\n};\n\n/**\n * @description `useSessionStorage` 훅은 지정된 `key`를 사용하여 `sessionStorage`에 데이터를 저장하고 불러오는 기능을 제공합니다.\n *\n * @template T - `state`의 데이터 타입입니다.\n *\n * @param {UseSessionStorageWithoutInitialValueOptions} options - initialValue가 없는 useSessionStorage 훅의 속성입니다.\n * @param {string} options.key - `sessionStorage`에서 데이터를 저장하고 가져올 때 사용하는 키입니다. 필수 속성입니다.\n *\n * @returns {{\n *  state: T | null;\n *  setState: Dispatch<SetStateAction<T | null>>;\n *  removeState: () => void;\n * }}\n * - `state`: 현재 `sessionStorage`에 저장된 값입니다. 값이 없을 경우 `null`을 반환합니다.\n * - `setState`: `sessionStorage`에 저장된 값을 업데이트합니다. 새로운 값 또는 이전 상태를 인자로 받는 함수를 전달할 수 있습니다.\n * - `removeState`: `sessionStorage`에서 해당 `key`의 값을 삭제합니다.\n *\n * @example\n * const { state, setState, removeState } = useSessionStorage<string>({\n *   key: 'username',\n * });\n *\n * state; // string | null\n */\nexport function useSessionStorage<T = unknown>({\n  key,\n}: UseSessionStorageWithoutInitialValueOptions): {\n  state: T | null;\n  setState: Dispatch<SetStateAction<T | null>>;\n  removeState: () => void;\n};\n\nexport function useSessionStorage<T>(options: UseSessionStorageOptions<T>) {\n  const { key } = options;\n  const initialValue = 'initialValue' in options ? options.initialValue : null;\n\n  const initialValueToUse = useMemo(() => {\n    return isFunction(initialValue) ? initialValue() : initialValue;\n  }, [initialValue]);\n\n  const externalStoreState = useSyncExternalStore(\n    subscribe,\n    () => getSnapshot(key),\n    () => getServerSnapshot(initialValueToUse)\n  );\n\n  const state = useMemo(() => {\n    return getParsedState<T>(externalStoreState, initialValueToUse);\n  }, [externalStoreState, initialValueToUse]);\n\n  const setState = useCallback(\n    (value: SetStateAction<T | null>) => {\n      try {\n        const prevStateString = getSnapshot(key);\n        const prevState = getParsedState<T>(prevStateString, initialValueToUse);\n        const valueToUse = isFunction(value) ? value(prevState) : value;\n\n        storageManager.setItem(key, valueToUse);\n        sessionStorageEventHandler.dispatchEvent();\n      } catch (err) {\n        throw new Error(\n          `세션 스토리지 \"${key}\" key에 데이터를 저장하는데 실패했습니다\"`, {\n          cause: err,\n        });\n      }\n    },\n    [key, initialValueToUse]\n  );\n\n  const removeState = useCallback(() => {\n    try {\n      storageManager.removeItem(key);\n      sessionStorageEventHandler.dispatchEvent();\n    } catch (err) {\n      throw new Error(\n        `세션 스토리지 \"${key}\" key의 데이터를 삭제하는데 실패했습니다\"`, {\n        cause: err,\n      });\n    }\n  }, [key]);\n\n  return { state, setState, removeState };\n}\n"],"mappings":";;;;AAkBA,MAAM,iBAAiB,IAAI,eAAe,iBAAiB;AAkF3D,SAAgB,kBAAqB,SAAsC;CACzE,MAAM,EAAE,QAAQ;CAChB,MAAM,eAAe,kBAAkB,UAAU,QAAQ,eAAe;CAExE,MAAM,oBAAoB,cAAc;EACtC,OAAO,WAAW,aAAa,GAAG,cAAc,GAAG;IAClD,CAAC,aAAa,CAAC;CAElB,MAAM,qBAAqB,qBACzB,iBACM,YAAY,IAAI,QAChB,kBAAkB,kBAAkB,CAC3C;CAqCD,OAAO;EAAE,OAnCK,cAAc;GAC1B,OAAO,eAAkB,oBAAoB,kBAAkB;KAC9D,CAAC,oBAAoB,kBAAkB,CAiC5B;EAAE,UA/BC,aACd,UAAoC;GACnC,IAAI;IAEF,MAAM,YAAY,eADM,YAAY,IACe,EAAE,kBAAkB;IACvE,MAAM,aAAa,WAAW,MAAM,GAAG,MAAM,UAAU,GAAG;IAE1D,eAAe,QAAQ,KAAK,WAAW;IACvC,2BAA2B,eAAe;YACnC,KAAK;IACZ,MAAM,IAAI,MACR,YAAY,IAAI,4BAA4B,EAC5C,OAAO,KACR,CAAC;;KAGN,CAAC,KAAK,kBAAkB,CAeF;EAAE,aAZN,kBAAkB;GACpC,IAAI;IACF,eAAe,WAAW,IAAI;IAC9B,2BAA2B,eAAe;YACnC,KAAK;IACZ,MAAM,IAAI,MACR,YAAY,IAAI,4BAA4B,EAC5C,OAAO,KACR,CAAC;;KAEH,CAAC,IAAI,CAE6B;EAAE"}