@classytic/arc-next 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks.js +6 -15
- package/dist/hooks.js.map +1 -1
- package/dist/query.d.ts +4 -4
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +4 -7
- package/dist/query.js.map +1 -1
- package/package.json +1 -1
package/dist/hooks.js
CHANGED
|
@@ -68,14 +68,11 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
68
68
|
organizationId,
|
|
69
69
|
...restParams
|
|
70
70
|
}),
|
|
71
|
-
queryFn: (
|
|
71
|
+
queryFn: () => api.getAll({
|
|
72
72
|
token,
|
|
73
73
|
organizationId,
|
|
74
74
|
params: restParams,
|
|
75
|
-
options: {
|
|
76
|
-
signal,
|
|
77
|
-
...requestOpts
|
|
78
|
-
}
|
|
75
|
+
options: { ...requestOpts }
|
|
79
76
|
}),
|
|
80
77
|
enabled: createEnabledRule(token, queryOpts),
|
|
81
78
|
options: {
|
|
@@ -108,14 +105,11 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
108
105
|
const { organizationId, request: requestOpts, ...restOptions } = options;
|
|
109
106
|
return createDetailQuery({
|
|
110
107
|
queryKey: KEYS.detail(id || ""),
|
|
111
|
-
queryFn: (
|
|
108
|
+
queryFn: () => api.getById({
|
|
112
109
|
id,
|
|
113
110
|
token,
|
|
114
111
|
organizationId,
|
|
115
|
-
options: {
|
|
116
|
-
signal,
|
|
117
|
-
...requestOpts
|
|
118
|
-
}
|
|
112
|
+
options: { ...requestOpts }
|
|
119
113
|
}),
|
|
120
114
|
enabled: !!id && createEnabledRule(token, restOptions),
|
|
121
115
|
options: {
|
|
@@ -297,7 +291,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
297
291
|
organizationId,
|
|
298
292
|
...restParams
|
|
299
293
|
}), "infinite"],
|
|
300
|
-
queryFn: ({
|
|
294
|
+
queryFn: ({ pageParam }) => {
|
|
301
295
|
const paginationParams = typeof pageParam === "string" ? { after: pageParam } : { page: pageParam };
|
|
302
296
|
return api.getAll({
|
|
303
297
|
token,
|
|
@@ -306,10 +300,7 @@ function createCrudHooks({ api, entityKey, singular, defaults = {}, callbacks =
|
|
|
306
300
|
...restParams,
|
|
307
301
|
...paginationParams
|
|
308
302
|
},
|
|
309
|
-
options: {
|
|
310
|
-
signal,
|
|
311
|
-
...requestOpts
|
|
312
|
-
}
|
|
303
|
+
options: { ...requestOpts }
|
|
313
304
|
});
|
|
314
305
|
},
|
|
315
306
|
enabled: createEnabledRule(token, queryOpts),
|
package/dist/hooks.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useCallback } from \"react\";\nimport { createOptimisticMutation } from \"./mutation.js\";\nimport {\n createListQuery,\n createDetailQuery,\n createInfiniteListQuery,\n updateListCache,\n getItemId,\n createQueryKeys,\n createCacheUtils,\n DEFAULT_QUERY_CONFIG,\n} from \"./query.js\";\nimport type {\n QueryKeys,\n CacheUtils,\n ListQueryOptions,\n DetailQueryOptions,\n ListQueryResult,\n DetailQueryResult,\n InfiniteListQueryOptions,\n InfiniteListQueryResult,\n} from \"./query.js\";\nimport {\n isOffsetPagination,\n isKeysetPagination,\n} from \"./api.js\";\nimport type { PaginatedResponse } from \"./api.js\";\nimport type { MutationCallbacks } from \"./mutation.js\";\nimport { getAuthMode, getAuthContext } from \"./client.js\";\nimport type { ArcClient, ToastHandler, UseRouterHook } from \"./client.js\";\n\n// Re-export UseRouterHook for backward compatibility\nexport type { UseRouterHook } from \"./client.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CrudApi<T, TCreate = Partial<T>, TUpdate = Partial<T>> {\n getAll: (options: {\n token?: string | null;\n organizationId?: string | null;\n params?: Record<string, unknown>;\n options?: { signal?: AbortSignal; [key: string]: unknown };\n }) => Promise<unknown>;\n\n getById: (options: {\n id: string;\n token?: string | null;\n organizationId?: string | null;\n options?: { signal?: AbortSignal; [key: string]: unknown };\n }) => Promise<unknown>;\n\n create: (options: {\n token?: string | null;\n organizationId?: string | null;\n data: TCreate;\n }) => Promise<unknown>;\n\n update: (options: {\n token?: string | null;\n organizationId?: string | null;\n id: string;\n data: TUpdate;\n }) => Promise<unknown>;\n\n delete: (options: {\n token?: string | null;\n organizationId?: string | null;\n id: string;\n }) => Promise<unknown>;\n}\n\nexport interface CrudHooksConfig<T, TCreate = Partial<T>, TUpdate = Partial<T>> {\n api: CrudApi<T, TCreate, TUpdate>;\n entityKey: string;\n singular: string;\n plural?: string;\n defaults?: {\n staleTime?: number;\n gcTime?: number;\n refetchOnWindowFocus?: boolean;\n structuralSharing?: boolean;\n messages?: {\n createSuccess?: string;\n createError?: string;\n updateSuccess?: string;\n updateError?: string;\n deleteSuccess?: string;\n deleteError?: string;\n };\n };\n callbacks?: {\n onCreate?: MutationCallbacks<T, { data: TCreate }>;\n onUpdate?: MutationCallbacks<T, { id: string; data: TUpdate }>;\n onDelete?: MutationCallbacks<unknown, { id: string }>;\n };\n client?: ArcClient;\n}\n\nexport interface MutationParams<TData> {\n token?: string | null;\n organizationId?: string | null;\n data: TData;\n}\n\nexport interface UpdateParams<TData> extends MutationParams<TData> {\n id: string;\n}\n\nexport interface DeleteParams {\n token?: string | null;\n organizationId?: string | null;\n id: string;\n}\n\nexport interface CallOptions<TData = unknown> {\n onSuccess?: (data: TData) => void;\n onError?: (error: Error) => void;\n silent?: boolean;\n}\n\nexport interface CrudActions<T, TCreate, TUpdate> {\n create: (params: MutationParams<TCreate>, options?: CallOptions<T>) => Promise<T>;\n update: (params: UpdateParams<TUpdate>, options?: CallOptions<T>) => Promise<T>;\n remove: (params: DeleteParams, options?: CallOptions) => Promise<unknown>;\n isCreating: boolean;\n isUpdating: boolean;\n isDeleting: boolean;\n isMutating: boolean;\n}\n\nexport interface NavigationOptions {\n scroll?: boolean;\n replace?: boolean;\n}\n\nexport type NavigateFn<T> = (href: string, item: T, options?: NavigationOptions) => void;\n\nexport interface CrudHooksReturn<T, TCreate, TUpdate> {\n KEYS: QueryKeys;\n cache: CacheUtils<T>;\n useList: {\n /** New signature — auto-injects token/orgId from configureAuth() context */\n (params?: Record<string, unknown>, options?: ListQueryOptions): ListQueryResult<T>;\n /** Legacy signature — explicit token */\n (token: string | null, params?: Record<string, unknown>, options?: ListQueryOptions): ListQueryResult<T>;\n };\n useDetail: {\n /** New signature — auto-injects token from configureAuth() context */\n (id: string | null, options?: DetailQueryOptions): DetailQueryResult<T>;\n /** Legacy signature — explicit token */\n (id: string | null, token: string | null, options?: DetailQueryOptions): DetailQueryResult<T>;\n };\n useInfiniteList: {\n /** New signature — auto-injects token/orgId from configureAuth() context */\n (params?: Record<string, unknown>, options?: InfiniteListQueryOptions): InfiniteListQueryResult<T>;\n /** Legacy signature — explicit token */\n (token: string | null, params?: Record<string, unknown>, options?: InfiniteListQueryOptions): InfiniteListQueryResult<T>;\n };\n useActions: () => CrudActions<T, TCreate, TUpdate>;\n useNavigation: () => NavigateFn<T>;\n}\n\n// ============================================================================\n// Navigation Configuration (Global)\n// ============================================================================\n\nlet useRouterHook: UseRouterHook | null = null;\n\n/**\n * Configure the router hook for useNavigation. Call once at app init.\n *\n * @example\n * import { useRouter } from \"next/navigation\";\n * configureNavigation(useRouter);\n */\nexport function configureNavigation(hook: UseRouterHook): void {\n useRouterHook = hook;\n}\n\n// ============================================================================\n// Enabled Rule\n// ============================================================================\n\nfunction createEnabledRule(token: string | null, options: { public?: boolean; enabled?: boolean }): boolean {\n // Cookie-based auth: no token needed, queries always enabled (cookies sent via credentials: 'include')\n if (getAuthMode() === 'cookie' || options.public) {\n return options.enabled ?? true;\n }\n // Bearer token auth: require token to enable queries\n return options.enabled !== undefined ? options.enabled && !!token : !!token;\n}\n\n// ============================================================================\n// Create CRUD Hooks Factory\n// ============================================================================\n\nexport function createCrudHooks<T, TCreate = Partial<T>, TUpdate = Partial<T>>({\n api,\n entityKey,\n singular,\n defaults = {},\n callbacks = {},\n client,\n}: CrudHooksConfig<T, TCreate, TUpdate>): CrudHooksReturn<T, TCreate, TUpdate> {\n const KEYS = createQueryKeys(entityKey);\n const cache = createCacheUtils<T>(KEYS);\n\n // Resolve toast handler: client instance → global\n const instanceToast: ToastHandler | undefined = client?.toast;\n // Resolve navigation hook: client instance → global\n const instanceNavigation: UseRouterHook | null = client?.navigation ?? null;\n\n const config = {\n ...DEFAULT_QUERY_CONFIG,\n ...defaults,\n structuralSharing: defaults.structuralSharing,\n messages: {\n createSuccess: `${singular} created successfully`,\n createError: `Failed to create ${singular.toLowerCase()}`,\n updateSuccess: `${singular} updated successfully`,\n updateError: `Failed to update ${singular.toLowerCase()}`,\n deleteSuccess: `${singular} deleted successfully`,\n deleteError: `Failed to delete ${singular.toLowerCase()}`,\n ...defaults.messages,\n },\n };\n\n // ========== useList ==========\n\n function useList(\n tokenOrParams?: string | null | Record<string, unknown>,\n paramsOrOptions?: Record<string, unknown> | ListQueryOptions,\n maybeOptions?: ListQueryOptions,\n ): ListQueryResult<T> {\n let token: string | null;\n let params: Record<string, unknown>;\n let options: ListQueryOptions;\n\n // Detect which overload: first arg is string|null = legacy, object/undefined = new\n if (tokenOrParams === null || typeof tokenOrParams === 'string') {\n token = tokenOrParams;\n params = (paramsOrOptions as Record<string, unknown>) ?? {};\n options = maybeOptions ?? {};\n } else {\n const auth = getAuthContext();\n token = auth.token;\n params = (tokenOrParams as Record<string, unknown>) ?? {};\n options = (paramsOrOptions as ListQueryOptions) ?? {};\n if (auth.organizationId && !params.organizationId) {\n params = { ...params, organizationId: auth.organizationId };\n }\n }\n\n const { organizationId, ...restParams } = params;\n const scope = options._scope || (organizationId ? \"tenant\" : \"super-admin\");\n const { request: requestOpts, ...queryOpts } = options;\n\n return createListQuery<T>({\n queryKey: KEYS.scopedList(scope, { organizationId, ...restParams }),\n queryFn: ({ signal }) => api.getAll({ token, organizationId: organizationId as string | null, params: restParams, options: { signal, ...requestOpts } }),\n enabled: createEnabledRule(token, queryOpts),\n options: {\n staleTime: queryOpts.staleTime ?? config.staleTime,\n gcTime: queryOpts.gcTime ?? config.gcTime,\n refetchOnWindowFocus: queryOpts.refetchOnWindowFocus ?? config.refetchOnWindowFocus,\n structuralSharing: queryOpts.structuralSharing ?? config.structuralSharing,\n refetchInterval: queryOpts.refetchInterval,\n refetchIntervalInBackground: queryOpts.refetchIntervalInBackground,\n },\n prefillDetailCache: queryOpts.prefillDetailCache ?? true,\n detailKeyBuilder: (id) => KEYS.detail(id),\n });\n }\n\n // ========== useDetail ==========\n\n function useDetail(\n id: string | null,\n tokenOrOptions?: string | null | DetailQueryOptions,\n maybeOptions?: DetailQueryOptions,\n ): DetailQueryResult<T> {\n let token: string | null;\n let options: DetailQueryOptions;\n\n // Detect which overload: second arg is string|null = legacy, object/undefined = new\n if (tokenOrOptions === null || typeof tokenOrOptions === 'string') {\n token = tokenOrOptions;\n options = maybeOptions ?? {};\n } else {\n const auth = getAuthContext();\n token = auth.token;\n options = (tokenOrOptions as DetailQueryOptions) ?? {};\n if (auth.organizationId && !options.organizationId) {\n options = { ...options, organizationId: auth.organizationId };\n }\n }\n\n const { organizationId, request: requestOpts, ...restOptions } = options;\n\n return createDetailQuery<T>({\n queryKey: KEYS.detail(id || \"\"),\n queryFn: ({ signal }) => api.getById({ id: id!, token, organizationId, options: { signal, ...requestOpts } }),\n enabled: !!id && createEnabledRule(token, restOptions),\n options: {\n staleTime: restOptions.staleTime ?? config.staleTime,\n gcTime: restOptions.gcTime ?? config.gcTime,\n structuralSharing: restOptions.structuralSharing ?? config.structuralSharing,\n refetchInterval: restOptions.refetchInterval,\n refetchIntervalInBackground: restOptions.refetchIntervalInBackground,\n },\n });\n }\n\n // ========== useActions ==========\n\n function useActions(): CrudActions<T, TCreate, TUpdate> {\n const queryClient = useQueryClient();\n\n const createMutation = createOptimisticMutation({\n mutationFn: ({ token, organizationId, data }: MutationParams<TCreate>) =>\n api.create({ token, organizationId, data }),\n queryClient,\n queryKeys: [KEYS.lists()],\n optimisticUpdate: (oldData, { data }) => {\n const optimisticItem = {\n ...(data as object),\n _optimistic: true,\n [getItemId(data) ? \"id\" : \"_id\"]: getItemId(data) ?? `temp-${Date.now()}`,\n };\n return updateListCache(oldData, (arr: unknown[]) => [optimisticItem, ...(arr || [])]);\n },\n onSuccess: (data, variables) => {\n callbacks.onCreate?.onSuccess?.(data as T, { data: variables.data }, undefined);\n },\n onError: (error, variables) => {\n callbacks.onCreate?.onError?.(error, { data: variables.data }, undefined);\n },\n messages: { success: config.messages.createSuccess, error: config.messages.createError },\n toastHandler: instanceToast,\n });\n\n const updateMutation = createOptimisticMutation({\n mutationFn: ({ token, organizationId, id, data }: UpdateParams<TUpdate>) =>\n api.update({ token, organizationId, id, data }),\n queryClient,\n queryKeys: [KEYS.lists()],\n optimisticUpdate: (oldData, { id, data }) => {\n const updated = updateListCache(oldData, (arr: unknown[]) =>\n (arr || []).map((item) => (getItemId(item) === id ? { ...(item as object), ...(data as object) } : item))\n );\n queryClient.setQueryData(KEYS.detail(id), (current: unknown) =>\n current ? { ...(current as object), data: { ...((current as { data?: object }).data || {}), ...(data as object) } } : current\n );\n return updated;\n },\n onSuccess: (data, { id }) => {\n queryClient.invalidateQueries({ queryKey: KEYS.detail(id) });\n callbacks.onUpdate?.onSuccess?.(data as T, { id, data: {} as TUpdate }, undefined);\n },\n onError: (error, { id, data }) => {\n callbacks.onUpdate?.onError?.(error, { id, data }, undefined);\n },\n messages: { success: config.messages.updateSuccess, error: config.messages.updateError },\n toastHandler: instanceToast,\n });\n\n const deleteMutation = createOptimisticMutation({\n mutationFn: ({ token, organizationId, id }: DeleteParams) => api.delete({ token, organizationId, id }),\n queryClient,\n queryKeys: [KEYS.lists()],\n optimisticUpdate: (oldData, { id }) => {\n queryClient.removeQueries({ queryKey: KEYS.detail(id) });\n return updateListCache(oldData, (arr: unknown[]) => (arr || []).filter((item) => getItemId(item) !== id));\n },\n onSuccess: (data, { id }) => {\n callbacks.onDelete?.onSuccess?.(data, { id }, undefined);\n },\n onError: (error, { id }) => {\n callbacks.onDelete?.onError?.(error, { id }, undefined);\n },\n messages: { success: config.messages.deleteSuccess, error: config.messages.deleteError },\n toastHandler: instanceToast,\n });\n\n const resolveAuth = <P extends { token?: string | null; organizationId?: string | null }>(params: P): P => {\n const auth = getAuthContext();\n return {\n ...params,\n token: params.token ?? auth.token,\n organizationId: params.organizationId ?? auth.organizationId,\n };\n };\n\n const create = async (params: MutationParams<TCreate>, options?: CallOptions<T>): Promise<T> => {\n try {\n const result = await createMutation.mutateAsync(resolveAuth(params));\n options?.onSuccess?.(result as T);\n return result as T;\n } catch (error) {\n options?.onError?.(error as Error);\n throw error;\n }\n };\n\n const update = async (params: UpdateParams<TUpdate>, options?: CallOptions<T>): Promise<T> => {\n try {\n const result = await updateMutation.mutateAsync(resolveAuth(params));\n options?.onSuccess?.(result as T);\n return result as T;\n } catch (error) {\n options?.onError?.(error as Error);\n throw error;\n }\n };\n\n const remove = async (params: DeleteParams, options?: CallOptions): Promise<unknown> => {\n try {\n const result = await deleteMutation.mutateAsync(resolveAuth(params));\n options?.onSuccess?.(result);\n return result;\n } catch (error) {\n options?.onError?.(error as Error);\n throw error;\n }\n };\n\n return {\n create,\n update,\n remove,\n isCreating: createMutation.isPending,\n isUpdating: updateMutation.isPending,\n isDeleting: deleteMutation.isPending,\n isMutating: createMutation.isPending || updateMutation.isPending || deleteMutation.isPending,\n };\n }\n\n // ========== useInfiniteList ==========\n\n function useInfiniteList(\n tokenOrParams?: string | null | Record<string, unknown>,\n paramsOrOptions?: Record<string, unknown> | InfiniteListQueryOptions,\n maybeOptions?: InfiniteListQueryOptions,\n ): InfiniteListQueryResult<T> {\n let token: string | null;\n let params: Record<string, unknown>;\n let options: InfiniteListQueryOptions;\n\n if (tokenOrParams === null || typeof tokenOrParams === 'string') {\n token = tokenOrParams;\n params = (paramsOrOptions as Record<string, unknown>) ?? {};\n options = maybeOptions ?? {};\n } else {\n const auth = getAuthContext();\n token = auth.token;\n params = (tokenOrParams as Record<string, unknown>) ?? {};\n options = (paramsOrOptions as InfiniteListQueryOptions) ?? {};\n if (auth.organizationId && !params.organizationId) {\n params = { ...params, organizationId: auth.organizationId };\n }\n }\n\n const { organizationId, ...restParams } = params;\n const scope = options._scope || (organizationId ? \"tenant\" : \"super-admin\");\n const { request: requestOpts, ...queryOpts } = options;\n\n return createInfiniteListQuery<T>({\n queryKey: [...KEYS.scopedList(scope, { organizationId, ...restParams }), 'infinite'],\n queryFn: ({ signal, pageParam }) => {\n const paginationParams = typeof pageParam === 'string'\n ? { after: pageParam }\n : { page: pageParam };\n\n return api.getAll({\n token,\n organizationId: organizationId as string | null,\n params: { ...restParams, ...paginationParams },\n options: { signal, ...requestOpts },\n });\n },\n enabled: createEnabledRule(token, queryOpts),\n initialPageParam: restParams.after ? restParams.after : 1,\n getNextPageParam: (lastPage) => {\n const page = lastPage as PaginatedResponse<T>;\n if (isKeysetPagination(page)) {\n return page.hasMore ? page.next : undefined;\n }\n if (isOffsetPagination(page)) {\n return page.hasNext ? page.page + 1 : undefined;\n }\n // Fallback: check common pagination fields\n const p = page as unknown as Record<string, unknown>;\n if (typeof p.hasNext === 'boolean' && typeof p.page === 'number') {\n return p.hasNext ? (p.page as number) + 1 : undefined;\n }\n return undefined;\n },\n options: {\n staleTime: queryOpts.staleTime ?? config.staleTime,\n gcTime: queryOpts.gcTime ?? config.gcTime,\n refetchOnWindowFocus: queryOpts.refetchOnWindowFocus ?? config.refetchOnWindowFocus,\n structuralSharing: queryOpts.structuralSharing ?? config.structuralSharing,\n },\n });\n }\n\n // ========== useNavigation ==========\n\n function useNavigation(): NavigateFn<T> {\n const queryClient = useQueryClient();\n const activeRouterHook = instanceNavigation ?? useRouterHook;\n const router = activeRouterHook?.();\n\n return useCallback(\n (href: string, item: T, options: NavigationOptions = {}) => {\n const id = getItemId(item);\n if (id) {\n queryClient.setQueryData(KEYS.detail(id), { data: item });\n }\n\n if (!router) return;\n\n const { scroll = true, replace = false } = options;\n if (replace) {\n router.replace(href, { scroll });\n } else {\n router.push(href, { scroll });\n }\n },\n [queryClient, router]\n );\n }\n\n return {\n KEYS,\n cache,\n useList,\n useDetail,\n useInfiniteList,\n useActions,\n useNavigation,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"hooks.js","names":[],"sources":["../src/hooks.ts"],"sourcesContent":["\"use client\";\n\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport { useCallback } from \"react\";\nimport { createOptimisticMutation } from \"./mutation.js\";\nimport {\n createListQuery,\n createDetailQuery,\n createInfiniteListQuery,\n updateListCache,\n getItemId,\n createQueryKeys,\n createCacheUtils,\n DEFAULT_QUERY_CONFIG,\n} from \"./query.js\";\nimport type {\n QueryKeys,\n CacheUtils,\n ListQueryOptions,\n DetailQueryOptions,\n ListQueryResult,\n DetailQueryResult,\n InfiniteListQueryOptions,\n InfiniteListQueryResult,\n} from \"./query.js\";\nimport {\n isOffsetPagination,\n isKeysetPagination,\n} from \"./api.js\";\nimport type { PaginatedResponse } from \"./api.js\";\nimport type { MutationCallbacks } from \"./mutation.js\";\nimport { getAuthMode, getAuthContext } from \"./client.js\";\nimport type { ArcClient, ToastHandler, UseRouterHook } from \"./client.js\";\n\n// Re-export UseRouterHook for backward compatibility\nexport type { UseRouterHook } from \"./client.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface CrudApi<T, TCreate = Partial<T>, TUpdate = Partial<T>> {\n getAll: (options: {\n token?: string | null;\n organizationId?: string | null;\n params?: Record<string, unknown>;\n options?: { signal?: AbortSignal; [key: string]: unknown };\n }) => Promise<unknown>;\n\n getById: (options: {\n id: string;\n token?: string | null;\n organizationId?: string | null;\n options?: { signal?: AbortSignal; [key: string]: unknown };\n }) => Promise<unknown>;\n\n create: (options: {\n token?: string | null;\n organizationId?: string | null;\n data: TCreate;\n }) => Promise<unknown>;\n\n update: (options: {\n token?: string | null;\n organizationId?: string | null;\n id: string;\n data: TUpdate;\n }) => Promise<unknown>;\n\n delete: (options: {\n token?: string | null;\n organizationId?: string | null;\n id: string;\n }) => Promise<unknown>;\n}\n\nexport interface CrudHooksConfig<T, TCreate = Partial<T>, TUpdate = Partial<T>> {\n api: CrudApi<T, TCreate, TUpdate>;\n entityKey: string;\n singular: string;\n plural?: string;\n defaults?: {\n staleTime?: number;\n gcTime?: number;\n refetchOnWindowFocus?: boolean;\n structuralSharing?: boolean;\n messages?: {\n createSuccess?: string;\n createError?: string;\n updateSuccess?: string;\n updateError?: string;\n deleteSuccess?: string;\n deleteError?: string;\n };\n };\n callbacks?: {\n onCreate?: MutationCallbacks<T, { data: TCreate }>;\n onUpdate?: MutationCallbacks<T, { id: string; data: TUpdate }>;\n onDelete?: MutationCallbacks<unknown, { id: string }>;\n };\n client?: ArcClient;\n}\n\nexport interface MutationParams<TData> {\n token?: string | null;\n organizationId?: string | null;\n data: TData;\n}\n\nexport interface UpdateParams<TData> extends MutationParams<TData> {\n id: string;\n}\n\nexport interface DeleteParams {\n token?: string | null;\n organizationId?: string | null;\n id: string;\n}\n\nexport interface CallOptions<TData = unknown> {\n onSuccess?: (data: TData) => void;\n onError?: (error: Error) => void;\n silent?: boolean;\n}\n\nexport interface CrudActions<T, TCreate, TUpdate> {\n create: (params: MutationParams<TCreate>, options?: CallOptions<T>) => Promise<T>;\n update: (params: UpdateParams<TUpdate>, options?: CallOptions<T>) => Promise<T>;\n remove: (params: DeleteParams, options?: CallOptions) => Promise<unknown>;\n isCreating: boolean;\n isUpdating: boolean;\n isDeleting: boolean;\n isMutating: boolean;\n}\n\nexport interface NavigationOptions {\n scroll?: boolean;\n replace?: boolean;\n}\n\nexport type NavigateFn<T> = (href: string, item: T, options?: NavigationOptions) => void;\n\nexport interface CrudHooksReturn<T, TCreate, TUpdate> {\n KEYS: QueryKeys;\n cache: CacheUtils<T>;\n useList: {\n /** New signature — auto-injects token/orgId from configureAuth() context */\n (params?: Record<string, unknown>, options?: ListQueryOptions): ListQueryResult<T>;\n /** Legacy signature — explicit token */\n (token: string | null, params?: Record<string, unknown>, options?: ListQueryOptions): ListQueryResult<T>;\n };\n useDetail: {\n /** New signature — auto-injects token from configureAuth() context */\n (id: string | null, options?: DetailQueryOptions): DetailQueryResult<T>;\n /** Legacy signature — explicit token */\n (id: string | null, token: string | null, options?: DetailQueryOptions): DetailQueryResult<T>;\n };\n useInfiniteList: {\n /** New signature — auto-injects token/orgId from configureAuth() context */\n (params?: Record<string, unknown>, options?: InfiniteListQueryOptions): InfiniteListQueryResult<T>;\n /** Legacy signature — explicit token */\n (token: string | null, params?: Record<string, unknown>, options?: InfiniteListQueryOptions): InfiniteListQueryResult<T>;\n };\n useActions: () => CrudActions<T, TCreate, TUpdate>;\n useNavigation: () => NavigateFn<T>;\n}\n\n// ============================================================================\n// Navigation Configuration (Global)\n// ============================================================================\n\nlet useRouterHook: UseRouterHook | null = null;\n\n/**\n * Configure the router hook for useNavigation. Call once at app init.\n *\n * @example\n * import { useRouter } from \"next/navigation\";\n * configureNavigation(useRouter);\n */\nexport function configureNavigation(hook: UseRouterHook): void {\n useRouterHook = hook;\n}\n\n// ============================================================================\n// Enabled Rule\n// ============================================================================\n\nfunction createEnabledRule(token: string | null, options: { public?: boolean; enabled?: boolean }): boolean {\n // Cookie-based auth: no token needed, queries always enabled (cookies sent via credentials: 'include')\n if (getAuthMode() === 'cookie' || options.public) {\n return options.enabled ?? true;\n }\n // Bearer token auth: require token to enable queries\n return options.enabled !== undefined ? options.enabled && !!token : !!token;\n}\n\n// ============================================================================\n// Create CRUD Hooks Factory\n// ============================================================================\n\nexport function createCrudHooks<T, TCreate = Partial<T>, TUpdate = Partial<T>>({\n api,\n entityKey,\n singular,\n defaults = {},\n callbacks = {},\n client,\n}: CrudHooksConfig<T, TCreate, TUpdate>): CrudHooksReturn<T, TCreate, TUpdate> {\n const KEYS = createQueryKeys(entityKey);\n const cache = createCacheUtils<T>(KEYS);\n\n // Resolve toast handler: client instance → global\n const instanceToast: ToastHandler | undefined = client?.toast;\n // Resolve navigation hook: client instance → global\n const instanceNavigation: UseRouterHook | null = client?.navigation ?? null;\n\n const config = {\n ...DEFAULT_QUERY_CONFIG,\n ...defaults,\n structuralSharing: defaults.structuralSharing,\n messages: {\n createSuccess: `${singular} created successfully`,\n createError: `Failed to create ${singular.toLowerCase()}`,\n updateSuccess: `${singular} updated successfully`,\n updateError: `Failed to update ${singular.toLowerCase()}`,\n deleteSuccess: `${singular} deleted successfully`,\n deleteError: `Failed to delete ${singular.toLowerCase()}`,\n ...defaults.messages,\n },\n };\n\n // ========== useList ==========\n\n function useList(\n tokenOrParams?: string | null | Record<string, unknown>,\n paramsOrOptions?: Record<string, unknown> | ListQueryOptions,\n maybeOptions?: ListQueryOptions,\n ): ListQueryResult<T> {\n let token: string | null;\n let params: Record<string, unknown>;\n let options: ListQueryOptions;\n\n // Detect which overload: first arg is string|null = legacy, object/undefined = new\n if (tokenOrParams === null || typeof tokenOrParams === 'string') {\n token = tokenOrParams;\n params = (paramsOrOptions as Record<string, unknown>) ?? {};\n options = maybeOptions ?? {};\n } else {\n const auth = getAuthContext();\n token = auth.token;\n params = (tokenOrParams as Record<string, unknown>) ?? {};\n options = (paramsOrOptions as ListQueryOptions) ?? {};\n if (auth.organizationId && !params.organizationId) {\n params = { ...params, organizationId: auth.organizationId };\n }\n }\n\n const { organizationId, ...restParams } = params;\n const scope = options._scope || (organizationId ? \"tenant\" : \"super-admin\");\n const { request: requestOpts, ...queryOpts } = options;\n\n return createListQuery<T>({\n queryKey: KEYS.scopedList(scope, { organizationId, ...restParams }),\n queryFn: () => api.getAll({ token, organizationId: organizationId as string | null, params: restParams, options: { ...requestOpts } }),\n enabled: createEnabledRule(token, queryOpts),\n options: {\n staleTime: queryOpts.staleTime ?? config.staleTime,\n gcTime: queryOpts.gcTime ?? config.gcTime,\n refetchOnWindowFocus: queryOpts.refetchOnWindowFocus ?? config.refetchOnWindowFocus,\n structuralSharing: queryOpts.structuralSharing ?? config.structuralSharing,\n refetchInterval: queryOpts.refetchInterval,\n refetchIntervalInBackground: queryOpts.refetchIntervalInBackground,\n },\n prefillDetailCache: queryOpts.prefillDetailCache ?? true,\n detailKeyBuilder: (id) => KEYS.detail(id),\n });\n }\n\n // ========== useDetail ==========\n\n function useDetail(\n id: string | null,\n tokenOrOptions?: string | null | DetailQueryOptions,\n maybeOptions?: DetailQueryOptions,\n ): DetailQueryResult<T> {\n let token: string | null;\n let options: DetailQueryOptions;\n\n // Detect which overload: second arg is string|null = legacy, object/undefined = new\n if (tokenOrOptions === null || typeof tokenOrOptions === 'string') {\n token = tokenOrOptions;\n options = maybeOptions ?? {};\n } else {\n const auth = getAuthContext();\n token = auth.token;\n options = (tokenOrOptions as DetailQueryOptions) ?? {};\n if (auth.organizationId && !options.organizationId) {\n options = { ...options, organizationId: auth.organizationId };\n }\n }\n\n const { organizationId, request: requestOpts, ...restOptions } = options;\n\n return createDetailQuery<T>({\n queryKey: KEYS.detail(id || \"\"),\n queryFn: () => api.getById({ id: id!, token, organizationId, options: { ...requestOpts } }),\n enabled: !!id && createEnabledRule(token, restOptions),\n options: {\n staleTime: restOptions.staleTime ?? config.staleTime,\n gcTime: restOptions.gcTime ?? config.gcTime,\n structuralSharing: restOptions.structuralSharing ?? config.structuralSharing,\n refetchInterval: restOptions.refetchInterval,\n refetchIntervalInBackground: restOptions.refetchIntervalInBackground,\n },\n });\n }\n\n // ========== useActions ==========\n\n function useActions(): CrudActions<T, TCreate, TUpdate> {\n const queryClient = useQueryClient();\n\n const createMutation = createOptimisticMutation({\n mutationFn: ({ token, organizationId, data }: MutationParams<TCreate>) =>\n api.create({ token, organizationId, data }),\n queryClient,\n queryKeys: [KEYS.lists()],\n optimisticUpdate: (oldData, { data }) => {\n const optimisticItem = {\n ...(data as object),\n _optimistic: true,\n [getItemId(data) ? \"id\" : \"_id\"]: getItemId(data) ?? `temp-${Date.now()}`,\n };\n return updateListCache(oldData, (arr: unknown[]) => [optimisticItem, ...(arr || [])]);\n },\n onSuccess: (data, variables) => {\n callbacks.onCreate?.onSuccess?.(data as T, { data: variables.data }, undefined);\n },\n onError: (error, variables) => {\n callbacks.onCreate?.onError?.(error, { data: variables.data }, undefined);\n },\n messages: { success: config.messages.createSuccess, error: config.messages.createError },\n toastHandler: instanceToast,\n });\n\n const updateMutation = createOptimisticMutation({\n mutationFn: ({ token, organizationId, id, data }: UpdateParams<TUpdate>) =>\n api.update({ token, organizationId, id, data }),\n queryClient,\n queryKeys: [KEYS.lists()],\n optimisticUpdate: (oldData, { id, data }) => {\n const updated = updateListCache(oldData, (arr: unknown[]) =>\n (arr || []).map((item) => (getItemId(item) === id ? { ...(item as object), ...(data as object) } : item))\n );\n queryClient.setQueryData(KEYS.detail(id), (current: unknown) =>\n current ? { ...(current as object), data: { ...((current as { data?: object }).data || {}), ...(data as object) } } : current\n );\n return updated;\n },\n onSuccess: (data, { id }) => {\n queryClient.invalidateQueries({ queryKey: KEYS.detail(id) });\n callbacks.onUpdate?.onSuccess?.(data as T, { id, data: {} as TUpdate }, undefined);\n },\n onError: (error, { id, data }) => {\n callbacks.onUpdate?.onError?.(error, { id, data }, undefined);\n },\n messages: { success: config.messages.updateSuccess, error: config.messages.updateError },\n toastHandler: instanceToast,\n });\n\n const deleteMutation = createOptimisticMutation({\n mutationFn: ({ token, organizationId, id }: DeleteParams) => api.delete({ token, organizationId, id }),\n queryClient,\n queryKeys: [KEYS.lists()],\n optimisticUpdate: (oldData, { id }) => {\n queryClient.removeQueries({ queryKey: KEYS.detail(id) });\n return updateListCache(oldData, (arr: unknown[]) => (arr || []).filter((item) => getItemId(item) !== id));\n },\n onSuccess: (data, { id }) => {\n callbacks.onDelete?.onSuccess?.(data, { id }, undefined);\n },\n onError: (error, { id }) => {\n callbacks.onDelete?.onError?.(error, { id }, undefined);\n },\n messages: { success: config.messages.deleteSuccess, error: config.messages.deleteError },\n toastHandler: instanceToast,\n });\n\n const resolveAuth = <P extends { token?: string | null; organizationId?: string | null }>(params: P): P => {\n const auth = getAuthContext();\n return {\n ...params,\n token: params.token ?? auth.token,\n organizationId: params.organizationId ?? auth.organizationId,\n };\n };\n\n const create = async (params: MutationParams<TCreate>, options?: CallOptions<T>): Promise<T> => {\n try {\n const result = await createMutation.mutateAsync(resolveAuth(params));\n options?.onSuccess?.(result as T);\n return result as T;\n } catch (error) {\n options?.onError?.(error as Error);\n throw error;\n }\n };\n\n const update = async (params: UpdateParams<TUpdate>, options?: CallOptions<T>): Promise<T> => {\n try {\n const result = await updateMutation.mutateAsync(resolveAuth(params));\n options?.onSuccess?.(result as T);\n return result as T;\n } catch (error) {\n options?.onError?.(error as Error);\n throw error;\n }\n };\n\n const remove = async (params: DeleteParams, options?: CallOptions): Promise<unknown> => {\n try {\n const result = await deleteMutation.mutateAsync(resolveAuth(params));\n options?.onSuccess?.(result);\n return result;\n } catch (error) {\n options?.onError?.(error as Error);\n throw error;\n }\n };\n\n return {\n create,\n update,\n remove,\n isCreating: createMutation.isPending,\n isUpdating: updateMutation.isPending,\n isDeleting: deleteMutation.isPending,\n isMutating: createMutation.isPending || updateMutation.isPending || deleteMutation.isPending,\n };\n }\n\n // ========== useInfiniteList ==========\n\n function useInfiniteList(\n tokenOrParams?: string | null | Record<string, unknown>,\n paramsOrOptions?: Record<string, unknown> | InfiniteListQueryOptions,\n maybeOptions?: InfiniteListQueryOptions,\n ): InfiniteListQueryResult<T> {\n let token: string | null;\n let params: Record<string, unknown>;\n let options: InfiniteListQueryOptions;\n\n if (tokenOrParams === null || typeof tokenOrParams === 'string') {\n token = tokenOrParams;\n params = (paramsOrOptions as Record<string, unknown>) ?? {};\n options = maybeOptions ?? {};\n } else {\n const auth = getAuthContext();\n token = auth.token;\n params = (tokenOrParams as Record<string, unknown>) ?? {};\n options = (paramsOrOptions as InfiniteListQueryOptions) ?? {};\n if (auth.organizationId && !params.organizationId) {\n params = { ...params, organizationId: auth.organizationId };\n }\n }\n\n const { organizationId, ...restParams } = params;\n const scope = options._scope || (organizationId ? \"tenant\" : \"super-admin\");\n const { request: requestOpts, ...queryOpts } = options;\n\n return createInfiniteListQuery<T>({\n queryKey: [...KEYS.scopedList(scope, { organizationId, ...restParams }), 'infinite'],\n queryFn: ({ pageParam }) => {\n const paginationParams = typeof pageParam === 'string'\n ? { after: pageParam }\n : { page: pageParam };\n\n return api.getAll({\n token,\n organizationId: organizationId as string | null,\n params: { ...restParams, ...paginationParams },\n options: { ...requestOpts },\n });\n },\n enabled: createEnabledRule(token, queryOpts),\n initialPageParam: restParams.after ? restParams.after : 1,\n getNextPageParam: (lastPage) => {\n const page = lastPage as PaginatedResponse<T>;\n if (isKeysetPagination(page)) {\n return page.hasMore ? page.next : undefined;\n }\n if (isOffsetPagination(page)) {\n return page.hasNext ? page.page + 1 : undefined;\n }\n // Fallback: check common pagination fields\n const p = page as unknown as Record<string, unknown>;\n if (typeof p.hasNext === 'boolean' && typeof p.page === 'number') {\n return p.hasNext ? (p.page as number) + 1 : undefined;\n }\n return undefined;\n },\n options: {\n staleTime: queryOpts.staleTime ?? config.staleTime,\n gcTime: queryOpts.gcTime ?? config.gcTime,\n refetchOnWindowFocus: queryOpts.refetchOnWindowFocus ?? config.refetchOnWindowFocus,\n structuralSharing: queryOpts.structuralSharing ?? config.structuralSharing,\n },\n });\n }\n\n // ========== useNavigation ==========\n\n function useNavigation(): NavigateFn<T> {\n const queryClient = useQueryClient();\n const activeRouterHook = instanceNavigation ?? useRouterHook;\n const router = activeRouterHook?.();\n\n return useCallback(\n (href: string, item: T, options: NavigationOptions = {}) => {\n const id = getItemId(item);\n if (id) {\n queryClient.setQueryData(KEYS.detail(id), { data: item });\n }\n\n if (!router) return;\n\n const { scroll = true, replace = false } = options;\n if (replace) {\n router.replace(href, { scroll });\n } else {\n router.push(href, { scroll });\n }\n },\n [queryClient, router]\n );\n }\n\n return {\n KEYS,\n cache,\n useList,\n useDetail,\n useInfiniteList,\n useActions,\n useNavigation,\n };\n}\n"],"mappings":"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"}
|
package/dist/query.d.ts
CHANGED
|
@@ -87,7 +87,7 @@ declare const DEFAULT_QUERY_CONFIG: {
|
|
|
87
87
|
readonly staleTime: number;
|
|
88
88
|
readonly gcTime: number;
|
|
89
89
|
readonly refetchOnWindowFocus: false;
|
|
90
|
-
readonly retry:
|
|
90
|
+
readonly retry: 0;
|
|
91
91
|
};
|
|
92
92
|
declare function getItemId(item: unknown): string | null;
|
|
93
93
|
declare function updateListCache<T>(listData: unknown, updater: (items: T[]) => T[]): unknown;
|
|
@@ -96,7 +96,7 @@ declare function createCacheUtils<T>(KEYS: QueryKeys): CacheUtils<T>;
|
|
|
96
96
|
interface CreateListQueryConfig {
|
|
97
97
|
queryKey: QueryKey;
|
|
98
98
|
queryFn: (context: {
|
|
99
|
-
signal
|
|
99
|
+
signal?: AbortSignal;
|
|
100
100
|
}) => Promise<unknown>;
|
|
101
101
|
enabled?: boolean;
|
|
102
102
|
options?: Record<string, unknown>;
|
|
@@ -114,7 +114,7 @@ declare function createListQuery<T>({
|
|
|
114
114
|
interface CreateDetailQueryConfig {
|
|
115
115
|
queryKey: QueryKey;
|
|
116
116
|
queryFn: (context: {
|
|
117
|
-
signal
|
|
117
|
+
signal?: AbortSignal;
|
|
118
118
|
}) => Promise<unknown>;
|
|
119
119
|
enabled?: boolean;
|
|
120
120
|
options?: Record<string, unknown>;
|
|
@@ -154,7 +154,7 @@ interface InfiniteListQueryResult<T> {
|
|
|
154
154
|
interface CreateInfiniteListQueryConfig {
|
|
155
155
|
queryKey: QueryKey;
|
|
156
156
|
queryFn: (context: {
|
|
157
|
-
signal
|
|
157
|
+
signal?: AbortSignal;
|
|
158
158
|
pageParam: unknown;
|
|
159
159
|
}) => Promise<unknown>;
|
|
160
160
|
enabled?: boolean;
|
package/dist/query.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.d.ts","names":[],"sources":["../src/query.ts"],"mappings":";;;UAUiB,cAAA;EACf,KAAA;EACA,KAAA;EACA,IAAA;EACA,KAAA;EACA,OAAA;EACA,OAAA;AAAA;;UAIe,kBAAA;EACf,KAAA,GAAQ,YAAA;EACR,UAAA;EACA,IAAA;EACA,aAAA,GAAgB,MAAA;EAChB,MAAA,GAAS,WAAA;AAAA;AAAA,UAGM,gBAAA;EACf,MAAA;EACA,OAAA;EACA,SAAA;EACA,MAAA;EACA,oBAAA;EACA,iBAAA;EACA,kBAAA;EACA,eAAA;EACA,2BAAA;EACA,MAAA;EAbA;EAeA,OAAA,GAAU,kBAAA;AAAA;AAAA,UAGK,kBAAA;EACf,MAAA;EACA,cAAA;EACA,OAAA;EACA,SAAA;EACA,MAAA;EACA,iBAAA;EACA,eAAA;EACA,2BAAA;EAlBA;EAoBA,OAAA,GAAU,kBAAA;AAAA;AAAA,UAGK,eAAA;EACf,KAAA,EAAO,CAAA;EACP,UAAA,EAAY,cAAA;EACZ,SAAA;EACA,UAAA;EACA,OAAA;EACA,SAAA;EACA,OAAA;EACA,KAAA,EAAO,KAAA;EACP,OAAA,QAAe,OAAA;EACf,IAAA;AAAA;AAAA,UAGe,iBAAA;EACf,IAAA,EAAM,CAAA;EACN,SAAA;EACA,UAAA;EACA,OAAA;EACA,SAAA;EACA,OAAA;EACA,KAAA,EAAO,KAAA;EACP,OAAA,QAAe,OAAA;EACf,IAAA;AAAA;AAAA,UAGe,SAAA;EACf,GAAA;EACA,KAAA,QAAa,QAAA;EACb,IAAA,GAAO,MAAA,eAAqB,QAAA;EAC5B,OAAA,QAAe,QAAA;EACf,MAAA,GAAS,EAAA,aAAe,QAAA;EACxB,MAAA,GAAS,GAAA,aAAgB,IAAA,gBAAoB,QAAA;EAC7C,UAAA,GAAa,KAAA,UAAe,MAAA,eAAqB,QAAA;AAAA;AAAA,UAGlC,UAAA;EACf,aAAA,GAAgB,MAAA,EAAQ,WAAA,KAAgB,OAAA;EACxC,eAAA,GAAkB,MAAA,EAAQ,WAAA,KAAgB,OAAA;EAC1C,gBAAA,GAAmB,MAAA,EAAQ,WAAA,EAAa,EAAA,aAAe,OAAA;EACvD,SAAA,GAAY,MAAA,EAAQ,WAAA,EAAa,EAAA,UAAY,IAAA,EAAM,CAAA;EACnD,SAAA,GAAY,MAAA,EAAQ,WAAA,EAAa,EAAA,aAAe,CAAA;EAChD,YAAA,GAAe,MAAA,EAAQ,WAAA,EAAa,EAAA;AAAA;AAAA,cAOzB,oBAAA;EAAA;;;;;iBAWG,SAAA,CAAU,IAAA;AAAA,iBA2CV,eAAA,GAAA,CAAmB,QAAA,WAAmB,OAAA,GAAU,KAAA,EAAO,CAAA,OAAQ,CAAA;AAAA,iBA2B/D,eAAA,CAAgB,SAAA,WAAoB,SAAA;AAAA,iBAgBpC,gBAAA,GAAA,CAAoB,IAAA,EAAM,SAAA,GAAY,UAAA,CAAW,CAAA;AAAA,UAkBhD,qBAAA;EACf,QAAA,EAAU,QAAA;EACV,OAAA,GAAU,OAAA;IAAW,MAAA,
|
|
1
|
+
{"version":3,"file":"query.d.ts","names":[],"sources":["../src/query.ts"],"mappings":"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"}
|
package/dist/query.js
CHANGED
|
@@ -8,7 +8,7 @@ const DEFAULT_QUERY_CONFIG = {
|
|
|
8
8
|
staleTime: 300 * 1e3,
|
|
9
9
|
gcTime: 1800 * 1e3,
|
|
10
10
|
refetchOnWindowFocus: false,
|
|
11
|
-
retry:
|
|
11
|
+
retry: 0
|
|
12
12
|
};
|
|
13
13
|
function getItemId(item) {
|
|
14
14
|
if (!item || typeof item !== "object") return null;
|
|
@@ -113,7 +113,7 @@ function createListQuery({ queryKey, queryFn, enabled = true, options = {}, pref
|
|
|
113
113
|
const queryClient = useQueryClient();
|
|
114
114
|
const query = useQuery({
|
|
115
115
|
queryKey,
|
|
116
|
-
queryFn: (
|
|
116
|
+
queryFn: () => queryFn({}),
|
|
117
117
|
enabled,
|
|
118
118
|
...DEFAULT_QUERY_CONFIG,
|
|
119
119
|
...options,
|
|
@@ -149,7 +149,7 @@ function createListQuery({ queryKey, queryFn, enabled = true, options = {}, pref
|
|
|
149
149
|
function createDetailQuery({ queryKey, queryFn, enabled = true, options = {} }) {
|
|
150
150
|
const query = useQuery({
|
|
151
151
|
queryKey,
|
|
152
|
-
queryFn: (
|
|
152
|
+
queryFn: () => queryFn({}),
|
|
153
153
|
enabled,
|
|
154
154
|
...DEFAULT_QUERY_CONFIG,
|
|
155
155
|
...options
|
|
@@ -169,10 +169,7 @@ function createDetailQuery({ queryKey, queryFn, enabled = true, options = {} })
|
|
|
169
169
|
function createInfiniteListQuery({ queryKey, queryFn, enabled = true, options = {}, initialPageParam = 1, getNextPageParam, getPreviousPageParam }) {
|
|
170
170
|
const query = useInfiniteQuery({
|
|
171
171
|
queryKey,
|
|
172
|
-
queryFn: ({
|
|
173
|
-
signal,
|
|
174
|
-
pageParam
|
|
175
|
-
}),
|
|
172
|
+
queryFn: ({ pageParam }) => queryFn({ pageParam }),
|
|
176
173
|
enabled,
|
|
177
174
|
initialPageParam,
|
|
178
175
|
getNextPageParam,
|
package/dist/query.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query.js","names":[],"sources":["../src/query.ts"],"sourcesContent":["\"use client\";\n\nimport { useQuery, useInfiniteQuery, useQueryClient, keepPreviousData, type QueryKey, type InfiniteData } from \"@tanstack/react-query\";\nimport { useEffect } from \"react\";\nimport type { QueryClient } from \"@tanstack/react-query\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PaginationData {\n total: number;\n pages: number;\n page: number;\n limit: number;\n hasNext: boolean;\n hasPrev: boolean;\n}\n\n/** Request-level options passed through to the fetch call */\nexport interface RequestPassthrough {\n cache?: RequestCache;\n revalidate?: number;\n tags?: string[];\n headerOptions?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport interface ListQueryOptions {\n public?: boolean;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnWindowFocus?: boolean;\n structuralSharing?: boolean;\n prefillDetailCache?: boolean;\n refetchInterval?: number | false;\n refetchIntervalInBackground?: boolean;\n _scope?: string;\n /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */\n request?: RequestPassthrough;\n}\n\nexport interface DetailQueryOptions {\n public?: boolean;\n organizationId?: string | null;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n structuralSharing?: boolean;\n refetchInterval?: number | false;\n refetchIntervalInBackground?: boolean;\n /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */\n request?: RequestPassthrough;\n}\n\nexport interface ListQueryResult<T> {\n items: T[];\n pagination: PaginationData | null;\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n isSuccess: boolean;\n isStale: boolean;\n error: Error | null;\n refetch: () => Promise<unknown>;\n data: unknown;\n}\n\nexport interface DetailQueryResult<T> {\n item: T | null;\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n isSuccess: boolean;\n isStale: boolean;\n error: Error | null;\n refetch: () => Promise<unknown>;\n data: unknown;\n}\n\nexport interface QueryKeys {\n all: string[];\n lists: () => QueryKey;\n list: (params?: unknown) => QueryKey;\n details: () => QueryKey;\n detail: (id: string) => QueryKey;\n custom: (key: string, ...args: unknown[]) => QueryKey;\n scopedList: (scope: string, params?: unknown) => QueryKey;\n}\n\nexport interface CacheUtils<T> {\n invalidateAll: (client: QueryClient) => Promise<void>;\n invalidateLists: (client: QueryClient) => Promise<void>;\n invalidateDetail: (client: QueryClient, id: string) => Promise<void>;\n setDetail: (client: QueryClient, id: string, data: T) => void;\n getDetail: (client: QueryClient, id: string) => T | undefined;\n removeDetail: (client: QueryClient, id: string) => void;\n}\n\n// ============================================================================\n// Default Config\n// ============================================================================\n\nexport const DEFAULT_QUERY_CONFIG = {\n staleTime: 5 * 60 * 1000,\n gcTime: 30 * 60 * 1000,\n refetchOnWindowFocus: false,\n retry: 1,\n} as const;\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\nexport function getItemId(item: unknown): string | null {\n if (!item || typeof item !== \"object\") return null;\n const obj = item as Record<string, unknown>;\n const id = obj._id ?? obj.id;\n return typeof id === \"string\" ? id : id ? String(id) : null;\n}\n\nfunction normalizePagination(data: unknown): PaginationData | null {\n if (!data || typeof data !== \"object\") return null;\n const d = data as Record<string, unknown>;\n\n const hasTotal = d.total != null || d.totalDocs != null;\n const hasPages = d.pages != null || d.totalPages != null;\n if (!hasTotal && !hasPages) return null;\n\n return {\n total: Number(d.total ?? d.totalDocs ?? 0),\n pages: Number(d.pages ?? d.totalPages ?? 1),\n page: Number(d.page ?? d.currentPage ?? 1),\n limit: Number(d.limit ?? 10),\n hasNext: Boolean(d.hasNext ?? d.hasNextPage ?? d.hasMore ?? false),\n hasPrev: Boolean(d.hasPrev ?? d.hasPrevPage ?? false),\n };\n}\n\nfunction extractItems<T>(data: unknown): T[] {\n if (!data) return [];\n if (Array.isArray(data)) return data as T[];\n if (typeof data !== \"object\") return [];\n\n const d = data as Record<string, unknown>;\n const items = d.docs ?? d.data ?? d.items ?? d.results;\n return Array.isArray(items) ? (items as T[]) : [];\n}\n\nfunction extractItem<T>(data: unknown): T | null {\n if (!data) return null;\n if (typeof data !== \"object\") return null;\n\n const d = data as Record<string, unknown>;\n return (d.data ?? d) as T | null;\n}\n\nexport function updateListCache<T>(listData: unknown, updater: (items: T[]) => T[]): unknown {\n if (!listData) return listData;\n\n if (typeof listData === \"object\" && \"docs\" in (listData as object)) {\n const d = listData as Record<string, unknown>;\n const updatedDocs = updater(d.docs as T[]);\n return { ...d, docs: updatedDocs, total: updatedDocs.length, totalDocs: updatedDocs.length };\n }\n\n if (Array.isArray(listData)) {\n return updater(listData as T[]);\n }\n\n if (typeof listData === \"object\" && \"data\" in (listData as object)) {\n const d = listData as Record<string, unknown>;\n if (Array.isArray(d.data)) {\n return { ...d, data: updater(d.data as T[]) };\n }\n }\n\n return listData;\n}\n\n// ============================================================================\n// Query Keys Factory\n// ============================================================================\n\nexport function createQueryKeys(entityKey: string): QueryKeys {\n return {\n all: [entityKey],\n lists: () => [entityKey, \"list\"],\n list: (params) => [entityKey, \"list\", params],\n details: () => [entityKey, \"detail\"],\n detail: (id) => [entityKey, \"detail\", id],\n custom: (key, ...args) => [entityKey, key, ...args],\n scopedList: (scope, params) => [entityKey, \"list\", { _scope: scope, ...(params as object) }],\n };\n}\n\n// ============================================================================\n// Cache Utilities Factory\n// ============================================================================\n\nexport function createCacheUtils<T>(KEYS: QueryKeys): CacheUtils<T> {\n return {\n invalidateAll: (client) => client.invalidateQueries({ queryKey: KEYS.all }),\n invalidateLists: (client) => client.invalidateQueries({ queryKey: KEYS.lists() }),\n invalidateDetail: (client, id) => client.invalidateQueries({ queryKey: KEYS.detail(id) }),\n setDetail: (client, id, data) => client.setQueryData(KEYS.detail(id), { data }),\n getDetail: (client, id) => {\n const cached = client.getQueryData(KEYS.detail(id)) as { data?: T } | undefined;\n return cached?.data;\n },\n removeDetail: (client, id) => client.removeQueries({ queryKey: KEYS.detail(id) }),\n };\n}\n\n// ============================================================================\n// List Query Hook\n// ============================================================================\n\nexport interface CreateListQueryConfig {\n queryKey: QueryKey;\n queryFn: (context: { signal: AbortSignal }) => Promise<unknown>;\n enabled?: boolean;\n options?: Record<string, unknown>;\n prefillDetailCache?: boolean;\n detailKeyBuilder?: (id: string) => QueryKey;\n}\n\nexport function createListQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n prefillDetailCache = true,\n detailKeyBuilder,\n}: CreateListQueryConfig): ListQueryResult<T> {\n const queryClient = useQueryClient();\n\n const query = useQuery({\n queryKey,\n queryFn: ({ signal }) => queryFn({ signal }),\n enabled,\n ...DEFAULT_QUERY_CONFIG,\n ...options,\n placeholderData: keepPreviousData,\n });\n\n const items = extractItems<T>(query.data);\n const pagination = normalizePagination(query.data);\n\n useEffect(() => {\n if (!prefillDetailCache || !detailKeyBuilder || items.length === 0) return;\n\n items.forEach((item) => {\n const id = getItemId(item);\n if (id) queryClient.setQueryData(detailKeyBuilder(id), { data: item });\n });\n }, [items, prefillDetailCache, detailKeyBuilder, queryClient]);\n\n return {\n items,\n pagination,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n isError: query.isError,\n isSuccess: query.isSuccess,\n isStale: query.isStale,\n error: query.error,\n refetch: query.refetch,\n data: query.data,\n };\n}\n\n// ============================================================================\n// Detail Query Hook\n// ============================================================================\n\nexport interface CreateDetailQueryConfig {\n queryKey: QueryKey;\n queryFn: (context: { signal: AbortSignal }) => Promise<unknown>;\n enabled?: boolean;\n options?: Record<string, unknown>;\n}\n\nexport function createDetailQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n}: CreateDetailQueryConfig): DetailQueryResult<T> {\n const query = useQuery({\n queryKey,\n queryFn: ({ signal }) => queryFn({ signal }),\n enabled,\n ...DEFAULT_QUERY_CONFIG,\n ...options,\n });\n\n const item = extractItem<T>(query.data);\n\n return {\n item,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n isError: query.isError,\n isSuccess: query.isSuccess,\n isStale: query.isStale,\n error: query.error,\n refetch: query.refetch,\n data: query.data,\n };\n}\n\n// ============================================================================\n// Infinite List Query Hook\n// ============================================================================\n\nexport interface InfiniteListQueryOptions {\n public?: boolean;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnWindowFocus?: boolean;\n structuralSharing?: boolean;\n _scope?: string;\n request?: RequestPassthrough;\n}\n\nexport interface InfiniteListQueryResult<T> {\n items: T[];\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n isFetchingNextPage: boolean;\n isFetchingPreviousPage: boolean;\n fetchNextPage: () => void;\n fetchPreviousPage: () => void;\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n isSuccess: boolean;\n error: Error | null;\n refetch: () => Promise<unknown>;\n data: InfiniteData<unknown> | undefined;\n}\n\nexport interface CreateInfiniteListQueryConfig {\n queryKey: QueryKey;\n queryFn: (context: { signal: AbortSignal; pageParam: unknown }) => Promise<unknown>;\n enabled?: boolean;\n options?: Record<string, unknown>;\n initialPageParam?: unknown;\n getNextPageParam: (lastPage: unknown) => unknown;\n getPreviousPageParam?: (firstPage: unknown) => unknown;\n}\n\nexport function createInfiniteListQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n initialPageParam = 1,\n getNextPageParam,\n getPreviousPageParam,\n}: CreateInfiniteListQueryConfig): InfiniteListQueryResult<T> {\n const query = useInfiniteQuery({\n queryKey,\n queryFn: ({ signal, pageParam }) => queryFn({ signal, pageParam }),\n enabled,\n initialPageParam,\n getNextPageParam,\n getPreviousPageParam,\n ...DEFAULT_QUERY_CONFIG,\n ...options,\n });\n\n const items: T[] = query.data?.pages.flatMap((page) => extractItems<T>(page)) ?? [];\n\n return {\n items,\n hasNextPage: query.hasNextPage,\n hasPreviousPage: query.hasPreviousPage,\n isFetchingNextPage: query.isFetchingNextPage,\n isFetchingPreviousPage: query.isFetchingPreviousPage,\n fetchNextPage: query.fetchNextPage,\n fetchPreviousPage: query.fetchPreviousPage,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n isError: query.isError,\n isSuccess: query.isSuccess,\n error: query.error,\n refetch: query.refetch,\n data: query.data,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"query.js","names":[],"sources":["../src/query.ts"],"sourcesContent":["\"use client\";\n\nimport { useQuery, useInfiniteQuery, useQueryClient, keepPreviousData, type QueryKey, type InfiniteData } from \"@tanstack/react-query\";\nimport { useEffect } from \"react\";\nimport type { QueryClient } from \"@tanstack/react-query\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PaginationData {\n total: number;\n pages: number;\n page: number;\n limit: number;\n hasNext: boolean;\n hasPrev: boolean;\n}\n\n/** Request-level options passed through to the fetch call */\nexport interface RequestPassthrough {\n cache?: RequestCache;\n revalidate?: number;\n tags?: string[];\n headerOptions?: Record<string, string>;\n signal?: AbortSignal;\n}\n\nexport interface ListQueryOptions {\n public?: boolean;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnWindowFocus?: boolean;\n structuralSharing?: boolean;\n prefillDetailCache?: boolean;\n refetchInterval?: number | false;\n refetchIntervalInBackground?: boolean;\n _scope?: string;\n /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */\n request?: RequestPassthrough;\n}\n\nexport interface DetailQueryOptions {\n public?: boolean;\n organizationId?: string | null;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n structuralSharing?: boolean;\n refetchInterval?: number | false;\n refetchIntervalInBackground?: boolean;\n /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */\n request?: RequestPassthrough;\n}\n\nexport interface ListQueryResult<T> {\n items: T[];\n pagination: PaginationData | null;\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n isSuccess: boolean;\n isStale: boolean;\n error: Error | null;\n refetch: () => Promise<unknown>;\n data: unknown;\n}\n\nexport interface DetailQueryResult<T> {\n item: T | null;\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n isSuccess: boolean;\n isStale: boolean;\n error: Error | null;\n refetch: () => Promise<unknown>;\n data: unknown;\n}\n\nexport interface QueryKeys {\n all: string[];\n lists: () => QueryKey;\n list: (params?: unknown) => QueryKey;\n details: () => QueryKey;\n detail: (id: string) => QueryKey;\n custom: (key: string, ...args: unknown[]) => QueryKey;\n scopedList: (scope: string, params?: unknown) => QueryKey;\n}\n\nexport interface CacheUtils<T> {\n invalidateAll: (client: QueryClient) => Promise<void>;\n invalidateLists: (client: QueryClient) => Promise<void>;\n invalidateDetail: (client: QueryClient, id: string) => Promise<void>;\n setDetail: (client: QueryClient, id: string, data: T) => void;\n getDetail: (client: QueryClient, id: string) => T | undefined;\n removeDetail: (client: QueryClient, id: string) => void;\n}\n\n// ============================================================================\n// Default Config\n// ============================================================================\n\nexport const DEFAULT_QUERY_CONFIG = {\n staleTime: 5 * 60 * 1000,\n gcTime: 30 * 60 * 1000,\n refetchOnWindowFocus: false,\n retry: 0,\n} as const;\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\nexport function getItemId(item: unknown): string | null {\n if (!item || typeof item !== \"object\") return null;\n const obj = item as Record<string, unknown>;\n const id = obj._id ?? obj.id;\n return typeof id === \"string\" ? id : id ? String(id) : null;\n}\n\nfunction normalizePagination(data: unknown): PaginationData | null {\n if (!data || typeof data !== \"object\") return null;\n const d = data as Record<string, unknown>;\n\n const hasTotal = d.total != null || d.totalDocs != null;\n const hasPages = d.pages != null || d.totalPages != null;\n if (!hasTotal && !hasPages) return null;\n\n return {\n total: Number(d.total ?? d.totalDocs ?? 0),\n pages: Number(d.pages ?? d.totalPages ?? 1),\n page: Number(d.page ?? d.currentPage ?? 1),\n limit: Number(d.limit ?? 10),\n hasNext: Boolean(d.hasNext ?? d.hasNextPage ?? d.hasMore ?? false),\n hasPrev: Boolean(d.hasPrev ?? d.hasPrevPage ?? false),\n };\n}\n\nfunction extractItems<T>(data: unknown): T[] {\n if (!data) return [];\n if (Array.isArray(data)) return data as T[];\n if (typeof data !== \"object\") return [];\n\n const d = data as Record<string, unknown>;\n const items = d.docs ?? d.data ?? d.items ?? d.results;\n return Array.isArray(items) ? (items as T[]) : [];\n}\n\nfunction extractItem<T>(data: unknown): T | null {\n if (!data) return null;\n if (typeof data !== \"object\") return null;\n\n const d = data as Record<string, unknown>;\n return (d.data ?? d) as T | null;\n}\n\nexport function updateListCache<T>(listData: unknown, updater: (items: T[]) => T[]): unknown {\n if (!listData) return listData;\n\n if (typeof listData === \"object\" && \"docs\" in (listData as object)) {\n const d = listData as Record<string, unknown>;\n const updatedDocs = updater(d.docs as T[]);\n return { ...d, docs: updatedDocs, total: updatedDocs.length, totalDocs: updatedDocs.length };\n }\n\n if (Array.isArray(listData)) {\n return updater(listData as T[]);\n }\n\n if (typeof listData === \"object\" && \"data\" in (listData as object)) {\n const d = listData as Record<string, unknown>;\n if (Array.isArray(d.data)) {\n return { ...d, data: updater(d.data as T[]) };\n }\n }\n\n return listData;\n}\n\n// ============================================================================\n// Query Keys Factory\n// ============================================================================\n\nexport function createQueryKeys(entityKey: string): QueryKeys {\n return {\n all: [entityKey],\n lists: () => [entityKey, \"list\"],\n list: (params) => [entityKey, \"list\", params],\n details: () => [entityKey, \"detail\"],\n detail: (id) => [entityKey, \"detail\", id],\n custom: (key, ...args) => [entityKey, key, ...args],\n scopedList: (scope, params) => [entityKey, \"list\", { _scope: scope, ...(params as object) }],\n };\n}\n\n// ============================================================================\n// Cache Utilities Factory\n// ============================================================================\n\nexport function createCacheUtils<T>(KEYS: QueryKeys): CacheUtils<T> {\n return {\n invalidateAll: (client) => client.invalidateQueries({ queryKey: KEYS.all }),\n invalidateLists: (client) => client.invalidateQueries({ queryKey: KEYS.lists() }),\n invalidateDetail: (client, id) => client.invalidateQueries({ queryKey: KEYS.detail(id) }),\n setDetail: (client, id, data) => client.setQueryData(KEYS.detail(id), { data }),\n getDetail: (client, id) => {\n const cached = client.getQueryData(KEYS.detail(id)) as { data?: T } | undefined;\n return cached?.data;\n },\n removeDetail: (client, id) => client.removeQueries({ queryKey: KEYS.detail(id) }),\n };\n}\n\n// ============================================================================\n// List Query Hook\n// ============================================================================\n\nexport interface CreateListQueryConfig {\n queryKey: QueryKey;\n queryFn: (context: { signal?: AbortSignal }) => Promise<unknown>;\n enabled?: boolean;\n options?: Record<string, unknown>;\n prefillDetailCache?: boolean;\n detailKeyBuilder?: (id: string) => QueryKey;\n}\n\nexport function createListQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n prefillDetailCache = true,\n detailKeyBuilder,\n}: CreateListQueryConfig): ListQueryResult<T> {\n const queryClient = useQueryClient();\n\n const query = useQuery({\n queryKey,\n queryFn: () => queryFn({}),\n enabled,\n ...DEFAULT_QUERY_CONFIG,\n ...options,\n placeholderData: keepPreviousData,\n });\n\n const items = extractItems<T>(query.data);\n const pagination = normalizePagination(query.data);\n\n useEffect(() => {\n if (!prefillDetailCache || !detailKeyBuilder || items.length === 0) return;\n\n items.forEach((item) => {\n const id = getItemId(item);\n if (id) queryClient.setQueryData(detailKeyBuilder(id), { data: item });\n });\n }, [items, prefillDetailCache, detailKeyBuilder, queryClient]);\n\n return {\n items,\n pagination,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n isError: query.isError,\n isSuccess: query.isSuccess,\n isStale: query.isStale,\n error: query.error,\n refetch: query.refetch,\n data: query.data,\n };\n}\n\n// ============================================================================\n// Detail Query Hook\n// ============================================================================\n\nexport interface CreateDetailQueryConfig {\n queryKey: QueryKey;\n queryFn: (context: { signal?: AbortSignal }) => Promise<unknown>;\n enabled?: boolean;\n options?: Record<string, unknown>;\n}\n\nexport function createDetailQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n}: CreateDetailQueryConfig): DetailQueryResult<T> {\n const query = useQuery({\n queryKey,\n queryFn: () => queryFn({}),\n enabled,\n ...DEFAULT_QUERY_CONFIG,\n ...options,\n });\n\n const item = extractItem<T>(query.data);\n\n return {\n item,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n isError: query.isError,\n isSuccess: query.isSuccess,\n isStale: query.isStale,\n error: query.error,\n refetch: query.refetch,\n data: query.data,\n };\n}\n\n// ============================================================================\n// Infinite List Query Hook\n// ============================================================================\n\nexport interface InfiniteListQueryOptions {\n public?: boolean;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnWindowFocus?: boolean;\n structuralSharing?: boolean;\n _scope?: string;\n request?: RequestPassthrough;\n}\n\nexport interface InfiniteListQueryResult<T> {\n items: T[];\n hasNextPage: boolean;\n hasPreviousPage: boolean;\n isFetchingNextPage: boolean;\n isFetchingPreviousPage: boolean;\n fetchNextPage: () => void;\n fetchPreviousPage: () => void;\n isLoading: boolean;\n isFetching: boolean;\n isError: boolean;\n isSuccess: boolean;\n error: Error | null;\n refetch: () => Promise<unknown>;\n data: InfiniteData<unknown> | undefined;\n}\n\nexport interface CreateInfiniteListQueryConfig {\n queryKey: QueryKey;\n queryFn: (context: { signal?: AbortSignal; pageParam: unknown }) => Promise<unknown>;\n enabled?: boolean;\n options?: Record<string, unknown>;\n initialPageParam?: unknown;\n getNextPageParam: (lastPage: unknown) => unknown;\n getPreviousPageParam?: (firstPage: unknown) => unknown;\n}\n\nexport function createInfiniteListQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n initialPageParam = 1,\n getNextPageParam,\n getPreviousPageParam,\n}: CreateInfiniteListQueryConfig): InfiniteListQueryResult<T> {\n const query = useInfiniteQuery({\n queryKey,\n queryFn: ({ pageParam }) => queryFn({ pageParam }),\n enabled,\n initialPageParam,\n getNextPageParam,\n getPreviousPageParam,\n ...DEFAULT_QUERY_CONFIG,\n ...options,\n });\n\n const items: T[] = query.data?.pages.flatMap((page) => extractItems<T>(page)) ?? [];\n\n return {\n items,\n hasNextPage: query.hasNextPage,\n hasPreviousPage: query.hasPreviousPage,\n isFetchingNextPage: query.isFetchingNextPage,\n isFetchingPreviousPage: query.isFetchingPreviousPage,\n fetchNextPage: query.fetchNextPage,\n fetchPreviousPage: query.fetchPreviousPage,\n isLoading: query.isLoading,\n isFetching: query.isFetching,\n isError: query.isError,\n isSuccess: query.isSuccess,\n error: query.error,\n refetch: query.refetch,\n data: query.data,\n };\n}\n"],"mappings":"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"}
|