UNPKG

next-unified-query

Version:

React hooks and components for next-unified-query-core

1 lines 38.1 kB
{"version":3,"sources":["../src/query-client-provider.tsx","../src/hooks/use-query.ts","../src/hooks/use-mutation.ts"],"names":["useRef","useCallback","fetcher","isFunction"],"mappings":"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","file":"react.mjs","sourcesContent":["import React, { createContext, useContext, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { QueryClient, QueryState, QueryClientOptionsWithInterceptors } from \"next-unified-query-core\";\nimport { getQueryClient } from \"next-unified-query-core\";\n\nconst QueryClientContext = createContext<QueryClient | null>(null);\n\nexport function HydrationBoundary({\n\tstate,\n\tchildren,\n}: {\n\tstate?: Record<string, QueryState>;\n\tchildren: ReactNode;\n}) {\n\tconst client = useQueryClient();\n\tconst hydratedRef = useRef(false);\n\n\t// 한 번만 hydration 수행\n\tif (state && !hydratedRef.current) {\n\t\tclient.hydrate(state);\n\t\thydratedRef.current = true;\n\t}\n\n\treturn <>{children}</>;\n}\n\nexport interface QueryClientProviderProps {\n\t/**\n\t * QueryClient 인스턴스 (선택사항)\n\t * 제공하지 않으면 자동으로 환경에 맞는 인스턴스를 생성합니다.\n\t */\n\tclient?: QueryClient;\n\t/**\n\t * QueryClient 옵션 (client가 제공되지 않은 경우에만 사용)\n\t */\n\toptions?: QueryClientOptionsWithInterceptors;\n\tchildren: ReactNode;\n}\n\nexport function QueryClientProvider({ client, options, children }: QueryClientProviderProps) {\n\t// client가 제공되지 않으면 자동으로 생성\n\tconst queryClient = client || getQueryClient(options);\n\n\treturn <QueryClientContext.Provider value={queryClient}>{children}</QueryClientContext.Provider>;\n}\n\nexport function useQueryClient(): QueryClient {\n\tconst ctx = useContext(QueryClientContext);\n\tif (!ctx) throw new Error(\"You must wrap your component tree with <QueryClientProvider>.\");\n\treturn ctx;\n}\n","import { useEffect, useRef, useSyncExternalStore, useCallback } from \"react\";\nimport type { ZodType, FetchConfig, FetchError } from \"next-unified-query-core\";\nimport { isObject, has, isFunction } from \"es-toolkit/compat\";\nimport { useQueryClient } from \"../query-client-provider\";\nimport type { QueryConfig, ExtractParams, ExtractQueryData } from \"next-unified-query-core\";\nimport { validateQueryConfig } from \"next-unified-query-core\";\nimport { QueryObserver, type QueryObserverOptions, type QueryObserverResult } from \"next-unified-query-core\";\n\n/**\n * 기본 UseQuery 옵션 (공통 속성)\n */\ninterface BaseUseQueryOptions<T = any> {\n\tcacheKey: readonly unknown[];\n\tparams?: Record<string, any>;\n\tschema?: ZodType;\n\tfetchConfig?: Omit<FetchConfig, \"url\" | \"method\" | \"params\" | \"data\">;\n\tenabled?: boolean;\n\tstaleTime?: number;\n\tselect?: (data: T) => any;\n\tselectDeps?: any[];\n\t/**\n\t * placeholderData: fetch 전 임시 데이터 또는 이전 데이터 유지\n\t * 값 또는 함수(prevData, prevQuery) 모두 지원\n\t * ReactNode(JSX)도 허용\n\t */\n\tplaceholderData?:\n\t\t| T\n\t\t| React.ReactNode\n\t\t| ((prevData: T | React.ReactNode | undefined, prevQuery?: any) => T | React.ReactNode);\n\t/**\n\t * gcTime: 쿼리 데이터가 사용되지 않을 때(구독자가 0이 될 때) 가비지 컬렉션까지의 시간(ms)\n\t * 이는 생명주기 관리 전략으로, maxQueries(메모리 보호)와는 별개로 동작합니다.\n\t * @default 300000 (5분)\n\t */\n\tgcTime?: number;\n}\n\n/**\n * URL 기반 UseQuery 옵션\n */\ninterface UrlBasedUseQueryOptions<T = any> extends BaseUseQueryOptions<T> {\n\t/**\n\t * API 요청 URL\n\t */\n\turl: string;\n\n\t/**\n\t * queryFn이 있으면 안됨 (상호 배제)\n\t */\n\tqueryFn?: never;\n}\n\n/**\n * Custom Function 기반 UseQuery 옵션\n */\ninterface FunctionBasedUseQueryOptions<T = any> extends BaseUseQueryOptions<T> {\n\t/**\n\t * 복잡한 요청을 위한 커스텀 쿼리 함수\n\t * Options 방식에서는 QueryFetcher만 전달 (GET/HEAD 메서드만 허용)\n\t * 인자: fetcher (QueryFetcher 인스턴스)\n\t */\n\tqueryFn: (fetcher: import(\"next-unified-query-core\").QueryFetcher) => Promise<T>;\n\n\t/**\n\t * url이 있으면 안됨 (상호 배제)\n\t */\n\turl?: never;\n}\n\n/**\n * UseQuery 옵션\n * URL 방식 또는 Custom Function 방식 중 하나를 선택할 수 있음\n */\nexport type UseQueryOptions<T = any> = UrlBasedUseQueryOptions<T> | FunctionBasedUseQueryOptions<T>;\n\n/**\n * Schema에서 타입을 추출하는 도우미 타입\n */\ntype InferSchemaType<T> = T extends { schema: infer S }\n\t? S extends ZodType\n\t\t? import(\"next-unified-query-core\").z.infer<S>\n\t\t: any\n\t: any;\n\ntype UseQueryFactoryOptions<P, T> = Omit<\n\tUseQueryOptions<T>,\n\t\"cacheKey\" | \"url\" | \"queryFn\" | \"params\" | \"schema\" | \"fetchConfig\"\n> &\n\t(P extends void ? { params?: P } : keyof P extends never ? { params?: P } : { params: P });\n\n/**\n * 캐싱과 상태 관리를 제공하는 데이터 페칭 React 훅입니다.\n *\n * **환경 호환성:**\n * - ❌ 서버사이드: 서버 컴포넌트와 호환되지 않음 (React context 사용)\n * - ✅ 클라이언트사이드: React context가 있는 React 컴포넌트에서 사용\n * - ⚠️ SSR: \"use client\" 지시어가 있는 클라이언트 컴포넌트에서만 사용\n *\n * @example\n * ```typescript\n * // 클라이언트 컴포넌트에서만 사용\n * \"use client\";\n * import { useQuery } from 'next-unified-query/react';\n *\n * function UserProfile({ userId }: { userId: number }) {\n * const { data, isLoading, error } = useQuery(api.getUser, { params: userId });\n *\n * if (isLoading) return <div>Loading...</div>;\n * if (error) return <div>Error: {error.message}</div>;\n * return <div>Hello {data.name}</div>;\n * }\n * ```\n */\n// 1. 명시적 타입을 가진 Factory 기반 (최고 우선순위): useQuery<T>(query, options)\nexport function useQuery<T, E = FetchError>(\n\tquery: QueryConfig<any, any>,\n\toptions: UseQueryFactoryOptions<ExtractParams<typeof query>, T>,\n): QueryObserverResult<T, E>;\n\n// 2. 스키마 추론을 가진 Factory 기반 (높은 우선순위): useQuery(query, options)\nexport function useQuery<Q extends QueryConfig<any, any>, E = FetchError>(\n\tquery: Q,\n\toptions: UseQueryFactoryOptions<ExtractParams<Q>, ExtractQueryData<Q>>,\n): QueryObserverResult<ExtractQueryData<Q>, E>;\n\n// 3. Options-based with schema inference (MEDIUM-HIGH priority): useQuery(options) - schema 있는 경우\nexport function useQuery<O extends UseQueryOptions<any> & { schema: ZodType }, E = FetchError>(\n\toptions: O,\n): QueryObserverResult<InferSchemaType<O>, E>;\n\n// 4. Options-based with explicit type (MEDIUM priority): useQuery<T>(options) - 모든 옵션 허용\nexport function useQuery<T, E = FetchError>(options: UseQueryOptions<T>): QueryObserverResult<T, E>;\n\n// 구현부\nexport function useQuery(arg1: any, arg2?: any): any {\n\t// QueryConfig 기반\n\tif (isObject(arg1) && has(arg1, \"cacheKey\") && isFunction((arg1 as QueryConfig<any, any>).cacheKey)) {\n\t\tconst query = arg1 as QueryConfig<any, any>;\n\n\t\t// QueryConfig 런타임 검증\n\t\tvalidateQueryConfig(query);\n\n\t\tconst options = arg2 ?? {};\n\t\tconst params = options.params;\n\t\tconst cacheKey = query.cacheKey?.(params);\n\t\tconst url = query.url?.(params);\n\t\tconst queryFn = query.queryFn;\n\t\tconst schema = query.schema;\n\t\tconst placeholderData = options.placeholderData ?? query.placeholderData;\n\t\tconst fetchConfig = options.fetchConfig ?? query.fetchConfig;\n\t\tconst select = options.select ?? query.select;\n\t\tconst selectDeps = options.selectDeps ?? query.selectDeps;\n\t\tconst enabled = has(options, \"enabled\")\n\t\t\t? options.enabled // 명시적으로 전달된 경우 해당 값 사용\n\t\t\t: isFunction(query.enabled)\n\t\t\t\t? query.enabled(params) // Factory의 enabled 함수 호출\n\t\t\t\t: query.enabled; // Factory의 enabled 불린 값 사용\n\n\t\treturn _useQueryObserver({\n\t\t\t...query,\n\t\t\t...options,\n\t\t\tenabled,\n\t\t\tcacheKey,\n\t\t\turl,\n\t\t\tqueryFn,\n\t\t\tparams,\n\t\t\tschema,\n\t\t\tplaceholderData,\n\t\t\tfetchConfig,\n\t\t\tselect,\n\t\t\tselectDeps,\n\t\t});\n\t}\n\t// 명시적 타입 지정 방식\n\treturn _useQueryObserver({\n\t\t...arg1,\n\t});\n}\n\nfunction _useQueryObserver<T = unknown, E = FetchError>(options: UseQueryOptions<T>): QueryObserverResult<T, E> {\n\t// UseQueryOptions 런타임 검증 (factory의 validateQueryConfig 사용)\n\tvalidateQueryConfig(options);\n\n\tconst queryClient = useQueryClient();\n\tconst observerRef = useRef<QueryObserver<T, E> | undefined>(undefined);\n\n\t// 기본 결과 객체를 캐싱하여 안정적인 참조 제공\n\tconst defaultResultRef = useRef<QueryObserverResult<T, E>>({\n\t\tdata: undefined,\n\t\terror: undefined,\n\t\tisLoading: true,\n\t\tisFetching: true,\n\t\tisError: false,\n\t\tisSuccess: false,\n\t\tisStale: true,\n\t\tisPlaceholderData: false,\n\t\trefetch: () => {},\n\t});\n\n\t// Observer 생성 또는 옵션 업데이트 (렌더링 중 직접 처리)\n\tif (!observerRef.current) {\n\t\tobserverRef.current = new QueryObserver<T, E>(queryClient, {\n\t\t\t...options,\n\t\t\tkey: options.cacheKey,\n\t\t} as QueryObserverOptions<T>);\n\t} else {\n\t\t// setOptions가 내부적으로 변경 여부를 체크하므로 항상 호출\n\t\tobserverRef.current.setOptions({\n\t\t\t...options,\n\t\t\tkey: options.cacheKey,\n\t\t} as QueryObserverOptions<T>);\n\t}\n\n\t// 안정적인 subscribe 함수\n\tconst subscribe = useCallback((callback: () => void) => {\n\t\treturn observerRef.current!.subscribe(callback);\n\t}, []);\n\n\t// 최적화된 getSnapshot 함수\n\tconst getSnapshot = useCallback(() => {\n\t\tif (!observerRef.current) {\n\t\t\t// Observer가 없는 경우 캐시된 기본 결과 반환\n\t\t\treturn defaultResultRef.current;\n\t\t}\n\n\t\t// QueryObserver에서 이미 Tracked Properties와 Structural Sharing이 처리됨\n\t\t// 추가적인 비교 없이 결과를 그대로 반환\n\t\treturn observerRef.current.getCurrentResult();\n\t}, []);\n\n\t// useSyncExternalStore로 Observer 구독\n\tconst result = useSyncExternalStore(\n\t\tsubscribe,\n\t\tgetSnapshot,\n\t\tgetSnapshot, // getServerSnapshot도 동일하게\n\t);\n\n\t// Observer 시작 (컴포넌트 마운트 후)\n\tuseEffect(() => {\n\t\tobserverRef.current?.start();\n\t}, []);\n\n\t// 컴포넌트 언마운트 시 Observer 정리\n\tuseEffect(() => {\n\t\treturn () => {\n\t\t\tobserverRef.current?.destroy();\n\t\t};\n\t}, []);\n\n\treturn result;\n}\n","import { useReducer, useCallback, useRef } from \"react\";\nimport {\n\tFetchError,\n\ttype ApiErrorResponse,\n\ttype HttpMethod,\n\ttype RequestConfig,\n\ttype NextTypeFetch,\n} from \"next-unified-query-core\";\nimport { validateMutationConfig, type MutationConfig, type InferIfZodSchema } from \"next-unified-query-core\";\nimport { useQueryClient } from \"../query-client-provider\";\nimport { z, type ZodType } from \"next-unified-query-core\";\nimport { merge, isArray, isFunction } from \"es-toolkit/compat\";\n\n/**\n * Mutation 상태 인터페이스\n */\nexport interface MutationState<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = void> {\n\tdata: TData | undefined;\n\terror: TError | null;\n\tisPending: boolean;\n\tisSuccess: boolean;\n\tisError: boolean;\n}\n\n/**\n * 기본 UseMutation 옵션 (공통 속성)\n */\ninterface BaseUseMutationOptions<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = void,\n\tTContext = unknown,\n\tRequestSchema extends ZodType = ZodType,\n\tResponseSchema extends ZodType = ZodType,\n> {\n\tonMutate?: (variables: TVariables) => Promise<TContext | void> | TContext | void;\n\tonSuccess?: (\n\t\tdata: InferIfZodSchema<ResponseSchema, TData>,\n\t\tvariables: TVariables,\n\t\tcontext: TContext | undefined,\n\t) => Promise<void> | void;\n\tonError?: (error: TError, variables: TVariables, context: TContext | undefined) => Promise<void> | void;\n\tonSettled?: (\n\t\tdata: InferIfZodSchema<ResponseSchema, TData> | undefined,\n\t\terror: TError | null,\n\t\tvariables: TVariables,\n\t\tcontext: TContext | undefined,\n\t) => Promise<void> | void;\n\tinvalidateQueries?:\n\t\t| string[][]\n\t\t| ((\n\t\t\t\tdata: InferIfZodSchema<ResponseSchema, TData>,\n\t\t\t\tvariables: TVariables,\n\t\t\t\tcontext: TContext | undefined,\n\t\t ) => string[][]);\n\tfetchConfig?: Omit<RequestConfig, \"url\" | \"method\" | \"params\" | \"data\" | \"schema\">;\n\trequestSchema?: RequestSchema;\n\tresponseSchema?: ResponseSchema;\n}\n\n/**\n * URL 기반 UseMutation 옵션\n */\ninterface UrlBasedUseMutationOptions<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = void,\n\tTContext = unknown,\n\tRequestSchema extends ZodType = ZodType,\n\tResponseSchema extends ZodType = ZodType,\n> extends BaseUseMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema> {\n\t/**\n\t * API 요청 URL\n\t */\n\turl: string | ((variables: TVariables) => string);\n\n\t/**\n\t * HTTP 메서드\n\t */\n\tmethod: HttpMethod;\n\n\t/**\n\t * mutationFn이 있으면 안됨 (상호 배제)\n\t */\n\tmutationFn?: never;\n}\n\n/**\n * Function 기반 UseMutation 옵션 (통일된 시그니처)\n */\ninterface UnifiedMutationOptions<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = any,\n\tTContext = unknown,\n\tRequestSchema extends ZodType = ZodType,\n\tResponseSchema extends ZodType = ZodType,\n> extends BaseUseMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema> {\n\t/**\n\t * Unified mutation function - 모든 경우에 (variables, fetcher) 패턴 사용\n\t * void mutation인 경우 variables를 _ 또는 무시하고 사용\n\t */\n\tmutationFn: (variables: TVariables, fetcher: NextTypeFetch) => Promise<InferIfZodSchema<ResponseSchema, TData>>;\n\n\t/**\n\t * url/method가 있으면 안됨 (상호 배제)\n\t */\n\turl?: never;\n\tmethod?: never;\n}\n\n/**\n * UseMutation 옵션\n * URL 방식 또는 Custom Function 방식 중 하나를 선택할 수 있음\n */\nexport type UseMutationOptions<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = any,\n\tTContext = unknown,\n\tRequestSchema extends ZodType = ZodType,\n\tResponseSchema extends ZodType = ZodType,\n> =\n\t| UrlBasedUseMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema>\n\t| UnifiedMutationOptions<TData, TError, TVariables, TContext, RequestSchema, ResponseSchema>;\n\n/**\n * UseMutation 결과 인터페이스 (단순화된 시그니처)\n */\nexport interface UseMutationResult<TData = unknown, TError = FetchError<ApiErrorResponse>, TVariables = any>\n\textends MutationState<TData, TError, TVariables> {\n\tmutate: (\n\t\tvariables: TVariables,\n\t\toptions?: {\n\t\t\tonSuccess?: (data: TData, variables: TVariables, context: any) => void;\n\t\t\tonError?: (error: TError, variables: TVariables, context: any) => void;\n\t\t\tonSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: any) => void;\n\t\t},\n\t) => void;\n\tmutateAsync: (\n\t\tvariables?: TVariables,\n\t\toptions?: {\n\t\t\tonSuccess?: (data: TData, variables: TVariables, context: any) => void;\n\t\t\tonError?: (error: TError, variables: TVariables, context: any) => void;\n\t\t\tonSettled?: (data: TData | undefined, error: TError | null, variables: TVariables, context: any) => void;\n\t\t},\n\t) => Promise<TData>;\n\treset: () => void;\n}\n\ntype MutationAction<TData, TError, TVariables> =\n\t| { type: \"MUTATE\"; variables: TVariables }\n\t| { type: \"SUCCESS\"; data: TData }\n\t| { type: \"ERROR\"; error: TError }\n\t| { type: \"RESET\" };\n\nconst getInitialState = <TData, TError, TVariables>(): MutationState<TData, TError, TVariables> => ({\n\tdata: undefined,\n\terror: null,\n\tisPending: false,\n\tisSuccess: false,\n\tisError: false,\n});\n\n/**\n * useMutation 오버로드 선언\n */\n// 스키마가 제공될 때 타입 추론\nexport function useMutation<\n\tTVariables = any,\n\tTError = FetchError<ApiErrorResponse>,\n\tTContext = unknown,\n\tRequestSchema extends ZodType = ZodType,\n\tResponseSchema extends ZodType = ZodType,\n>(\n\toptions: UseMutationOptions<unknown, TError, TVariables, TContext, RequestSchema, ResponseSchema> & {\n\t\tresponseSchema: ResponseSchema;\n\t},\n): UseMutationResult<z.infer<ResponseSchema>, TError, TVariables>;\n\n// Factory 기반\nexport function useMutation<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = any,\n\tTContext = unknown,\n>(\n\tfactoryConfig: MutationConfig<TVariables, TData, TError, TContext>,\n\toverrideOptions?: Partial<BaseUseMutationOptions<TData, TError, TVariables, TContext>>,\n): UseMutationResult<TData, TError, TVariables>;\n\n// 일반 옵션 기반\nexport function useMutation<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = any,\n\tTContext = unknown,\n>(options: UseMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables>;\n\n// 구현\nexport function useMutation<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = any,\n\tTContext = unknown,\n>(\n\tconfigOrOptions:\n\t\t| MutationConfig<TVariables, TData, TError, TContext>\n\t\t| UseMutationOptions<TData, TError, TVariables, TContext>,\n\toverrideOptions?: Partial<BaseUseMutationOptions<TData, TError, TVariables, TContext>>,\n): UseMutationResult<TData, TError, TVariables> {\n\t// Factory 기반인지 확인 (cacheKey 등 factory 특성이 있는지 확인)\n\tconst isFactoryConfig = \"url\" in configOrOptions || \"mutationFn\" in configOrOptions;\n\n\tif (isFactoryConfig && overrideOptions) {\n\t\t// Factory 기반 + override options\n\t\tconst factoryConfig = configOrOptions as MutationConfig<TVariables, TData, TError, TContext>;\n\t\tconst mergedOptions = mergeMutationOptions(factoryConfig, overrideOptions);\n\t\treturn _useMutationInternal(mergedOptions);\n\t} else {\n\t\t// Options 기반 또는 Factory 기반 (override 없음)\n\t\treturn _useMutationInternal(configOrOptions as any);\n\t}\n}\n\n/**\n * Factory 옵션과 useMutation 옵션을 병합하는 함수\n */\nfunction mergeMutationOptions<TData, TError, TVariables, TContext>(\n\tfactoryConfig: MutationConfig<TVariables, TData, TError, TContext>,\n\toverrideOptions: Partial<BaseUseMutationOptions<TData, TError, TVariables, TContext>>,\n): UseMutationOptions<TData, TError, TVariables, TContext> {\n\t// Factory 콜백들\n\tconst factoryOnMutate = factoryConfig.onMutate;\n\tconst factoryOnSuccess = factoryConfig.onSuccess;\n\tconst factoryOnError = factoryConfig.onError;\n\tconst factoryOnSettled = factoryConfig.onSettled;\n\n\t// Override 콜백들\n\tconst overrideOnMutate = overrideOptions.onMutate;\n\tconst overrideOnSuccess = overrideOptions.onSuccess;\n\tconst overrideOnError = overrideOptions.onError;\n\tconst overrideOnSettled = overrideOptions.onSettled;\n\n\treturn {\n\t\t// Factory 기본 속성들\n\t\t...factoryConfig,\n\n\t\t// Override 옵션들로 덮어쓰기 (콜백 제외)\n\t\t...overrideOptions,\n\n\t\t// 콜백들은 양쪽 모두 실행하도록 병합\n\t\tonMutate: combinedCallback(factoryOnMutate, overrideOnMutate),\n\t\tonSuccess: combinedCallback(factoryOnSuccess, overrideOnSuccess),\n\t\tonError: combinedCallback(factoryOnError, overrideOnError),\n\t\tonSettled: combinedCallback(factoryOnSettled, overrideOnSettled),\n\t} as UseMutationOptions<TData, TError, TVariables, TContext>;\n}\n\n/**\n * 두 콜백을 결합하여 순서대로 실행하는 함수 생성\n */\nfunction combinedCallback<T extends (...args: any[]) => any>(first?: T, second?: T): T | undefined {\n\tif (!first && !second) return undefined;\n\tif (!first) return second;\n\tif (!second) return first;\n\n\treturn ((...args: Parameters<T>) => {\n\t\t// Factory 콜백 먼저 실행\n\t\tconst firstResult = first(...args);\n\t\t// Override 콜백 실행\n\t\tconst secondResult = second(...args);\n\n\t\t// Promise인 경우 체인으로 연결\n\t\tif (firstResult && typeof firstResult.then === \"function\") {\n\t\t\treturn firstResult.then(() => secondResult);\n\t\t}\n\n\t\treturn secondResult;\n\t}) as T;\n}\n\n/**\n * 내부 구현 함수\n */\nfunction _useMutationInternal<\n\tTData = unknown,\n\tTError = FetchError<ApiErrorResponse>,\n\tTVariables = any,\n\tTContext = unknown,\n>(options: UseMutationOptions<TData, TError, TVariables, TContext>): UseMutationResult<TData, TError, TVariables> {\n\tconst queryClient = useQueryClient();\n\tconst fetcher = queryClient.getFetcher();\n\n\t// 런타임 검증 (개발 환경에서만)\n\tif (process.env.NODE_ENV !== \"production\") {\n\t\ttry {\n\t\t\tvalidateMutationConfig(options as any);\n\t\t} catch (error) {\n\t\t\tthrow error; // 검증 실패 시 에러를 그대로 던짐\n\t\t}\n\t}\n\n\t// 통일된 시그니처 사용: 모든 mutation이 (variables, fetcher) 패턴 사용\n\n\tconst [state, dispatch] = useReducer(\n\t\t(\n\t\t\tprevState: MutationState<TData, TError, TVariables>,\n\t\t\taction: MutationAction<TData, TError, TVariables>,\n\t\t): MutationState<TData, TError, TVariables> => {\n\t\t\tswitch (action.type) {\n\t\t\t\tcase \"MUTATE\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prevState,\n\t\t\t\t\t\tisPending: true,\n\t\t\t\t\t\tisSuccess: false,\n\t\t\t\t\t\tisError: false,\n\t\t\t\t\t\terror: null,\n\t\t\t\t\t};\n\t\t\t\tcase \"SUCCESS\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prevState,\n\t\t\t\t\t\tisPending: false,\n\t\t\t\t\t\tisSuccess: true,\n\t\t\t\t\t\tisError: false,\n\t\t\t\t\t\tdata: action.data,\n\t\t\t\t\t\terror: null,\n\t\t\t\t\t};\n\t\t\t\tcase \"ERROR\":\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...prevState,\n\t\t\t\t\t\tisPending: false,\n\t\t\t\t\t\tisSuccess: false,\n\t\t\t\t\t\tisError: true,\n\t\t\t\t\t\terror: action.error,\n\t\t\t\t\t};\n\t\t\t\tcase \"RESET\":\n\t\t\t\t\treturn getInitialState();\n\t\t\t\tdefault:\n\t\t\t\t\treturn prevState;\n\t\t\t}\n\t\t},\n\t\tgetInitialState<TData, TError, TVariables>(),\n\t);\n\n\tconst latestOptions = useRef(options);\n\tlatestOptions.current = options;\n\n\t// Mutation 함수 생성\n\tconst getMutationFn = useCallback(() => {\n\t\tif (\"mutationFn\" in options && options.mutationFn) {\n\t\t\t// 통일된 시그니처: 모든 mutationFn은 (variables, fetcher) 패턴을 사용\n\t\t\treturn options.mutationFn;\n\t\t}\n\n\t\t// URL + Method 기반 mutation 함수 생성\n\t\treturn async (variables: TVariables, fetcher: NextTypeFetch) => {\n\t\t\tconst urlBasedOptions = options as UrlBasedUseMutationOptions<TData, TError, TVariables, TContext>;\n\t\t\tconst url = isFunction(urlBasedOptions.url) ? urlBasedOptions.url(variables) : urlBasedOptions.url;\n\t\t\tconst method = urlBasedOptions.method;\n\n\t\t\t// 요청 데이터 검증\n\t\t\tlet dataForRequest: any = variables;\n\t\t\tif (options.requestSchema) {\n\t\t\t\ttry {\n\t\t\t\t\tdataForRequest = options.requestSchema.parse(variables);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tif (e instanceof z.ZodError) {\n\t\t\t\t\t\tconst config = {\n\t\t\t\t\t\t\turl: url as string,\n\t\t\t\t\t\t\tmethod: method as HttpMethod,\n\t\t\t\t\t\t\tdata: variables,\n\t\t\t\t\t\t} as RequestConfig;\n\n\t\t\t\t\t\tconst fetchError = new FetchError(\n\t\t\t\t\t\t\t`Request validation failed: ${e.issues.map((issue) => issue.message).join(\", \")}`,\n\t\t\t\t\t\t\tconfig,\n\t\t\t\t\t\t\t\"ERR_VALIDATION\",\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tfetchError.name = \"ValidationError\";\n\t\t\t\t\t\tfetchError.cause = e;\n\t\t\t\t\t\t(fetchError as any).isValidationError = true;\n\t\t\t\t\t\tthrow fetchError;\n\t\t\t\t\t}\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst requestConfig: RequestConfig = merge(\n\t\t\t\t{ schema: options.responseSchema },\n\t\t\t\t// fetcher.defaults에서 baseURL을 가져와서 기본값으로 설정\n\t\t\t\t{ baseURL: fetcher.defaults.baseURL },\n\t\t\t\toptions.fetchConfig || {},\n\t\t\t\t{\n\t\t\t\t\turl: url as string,\n\t\t\t\t\tmethod: method as HttpMethod,\n\t\t\t\t\tdata: dataForRequest,\n\t\t\t\t},\n\t\t\t);\n\n\t\t\tconst response = await fetcher.request(requestConfig);\n\t\t\treturn response.data;\n\t\t};\n\t}, [options, fetcher]);\n\n\tconst mutateCallback = useCallback(\n\t\tasync (\n\t\t\tvariables?: TVariables,\n\t\t\tmutateLocalOptions?: {\n\t\t\t\tonSuccess?: (data: TData, variables: TVariables, context: TContext | undefined) => void;\n\t\t\t\tonError?: (error: TError, variables: TVariables, context: TContext | undefined) => void;\n\t\t\t\tonSettled?: (\n\t\t\t\t\tdata: TData | undefined,\n\t\t\t\t\terror: TError | null,\n\t\t\t\t\tvariables: TVariables,\n\t\t\t\t\tcontext: TContext | undefined,\n\t\t\t\t) => void;\n\t\t\t},\n\t\t): Promise<TData> => {\n\t\t\tdispatch({ type: \"MUTATE\", variables: variables as TVariables });\n\t\t\tlet context: TContext | void | undefined;\n\n\t\t\ttry {\n\t\t\t\t// onMutate 콜백\n\t\t\t\tconst onMutateCb = latestOptions.current.onMutate;\n\t\t\t\tif (onMutateCb) {\n\t\t\t\t\tcontext = await onMutateCb(variables as any);\n\t\t\t\t}\n\n\t\t\t\t// 실제 mutation 함수 실행\n\t\t\t\tconst mutationFn = getMutationFn();\n\t\t\t\tconst data = (await mutationFn(variables as TVariables, fetcher)) as TData;\n\t\t\t\tdispatch({ type: \"SUCCESS\", data });\n\n\t\t\t\t// onSuccess 콜백들 실행\n\t\t\t\tif (latestOptions.current.onSuccess) {\n\t\t\t\t\tawait latestOptions.current.onSuccess(data, variables as any, context as TContext);\n\t\t\t\t}\n\t\t\t\tif (mutateLocalOptions?.onSuccess) {\n\t\t\t\t\tmutateLocalOptions.onSuccess(data, variables as any, context as TContext);\n\t\t\t\t}\n\n\t\t\t\t// invalidateQueries 처리\n\t\t\t\tconst invalidateQueriesOption = latestOptions.current.invalidateQueries;\n\t\t\t\tif (invalidateQueriesOption) {\n\t\t\t\t\tlet keysToInvalidate: string[][];\n\n\t\t\t\t\tif (isFunction(invalidateQueriesOption)) {\n\t\t\t\t\t\tkeysToInvalidate = invalidateQueriesOption(data, variables as any, context as TContext) as string[][];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tkeysToInvalidate = invalidateQueriesOption as string[][];\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isArray(keysToInvalidate)) {\n\t\t\t\t\t\tkeysToInvalidate.forEach((queryKey) => {\n\t\t\t\t\t\t\tqueryClient.invalidateQueries(queryKey);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// onSettled 콜백들 실행\n\t\t\t\tif (latestOptions.current.onSettled) {\n\t\t\t\t\tawait latestOptions.current.onSettled(data, null, variables as any, context as TContext);\n\t\t\t\t}\n\t\t\t\tif (mutateLocalOptions?.onSettled) {\n\t\t\t\t\tmutateLocalOptions.onSettled(data, null, variables as any, context as TContext);\n\t\t\t\t}\n\n\t\t\t\treturn data as TData;\n\t\t\t} catch (err) {\n\t\t\t\tconst error = err as TError;\n\t\t\t\tdispatch({ type: \"ERROR\", error });\n\n\t\t\t\t// onError 콜백들 실행\n\t\t\t\tif (latestOptions.current.onError) {\n\t\t\t\t\tawait latestOptions.current.onError(error, variables as any, context as TContext);\n\t\t\t\t}\n\t\t\t\tif (mutateLocalOptions?.onError) {\n\t\t\t\t\tmutateLocalOptions.onError(error, variables as any, context as TContext);\n\t\t\t\t}\n\n\t\t\t\t// onSettled 콜백들 실행\n\t\t\t\tif (latestOptions.current.onSettled) {\n\t\t\t\t\tawait latestOptions.current.onSettled(undefined, error, variables as any, context as TContext);\n\t\t\t\t}\n\t\t\t\tif (mutateLocalOptions?.onSettled) {\n\t\t\t\t\tmutateLocalOptions.onSettled(undefined, error, variables as any, context as TContext);\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t\t[getMutationFn, queryClient, fetcher],\n\t);\n\n\tconst mutate = useCallback(\n\t\t(variables?: TVariables, localOptions?: any) => {\n\t\t\tmutateCallback(variables, localOptions).catch(() => {\n\t\t\t\t// mutateAsync에서 에러를 처리하므로, 여기서는 특별한 처리를 하지 않음\n\t\t\t});\n\t\t},\n\t\t[mutateCallback],\n\t);\n\n\tconst mutateAsync = useCallback(\n\t\t(variables?: TVariables, localOptions?: any): Promise<TData> => {\n\t\t\treturn mutateCallback(variables, localOptions);\n\t\t},\n\t\t[mutateCallback],\n\t);\n\n\tconst reset = useCallback(() => {\n\t\tdispatch({ type: \"RESET\" });\n\t}, []);\n\n\treturn {\n\t\t...state,\n\t\tmutate: mutate as any,\n\t\tmutateAsync: mutateAsync as any,\n\t\treset,\n\t};\n}\n"]}