@classytic/arc-next 0.1.3 → 0.2.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"mutation.js","names":[],"sources":["../src/mutation.ts"],"sourcesContent":["\"use client\";\n\nimport { useMutation, useQueryClient, type QueryClient, type QueryKey } from \"@tanstack/react-query\";\nimport { useTransition } from \"react\";\nimport { isArcApiError } from \"./client.js\";\nimport type { ToastHandler } from \"./client.js\";\n\n// Re-export for backward compatibility\nexport type { ToastHandler } from \"./client.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface MutationMessages {\n success?: string | ((data: unknown, variables: unknown) => string);\n error?: string | ((error: Error, variables: unknown) => string);\n}\n\nexport interface MutationCallbacks<TData, TVariables, TContext = unknown> {\n onMutate?: (variables: TVariables) => TContext | Promise<TContext>;\n onSuccess?: (data: TData, variables: TVariables, context: TContext) => void | Promise<void>;\n onError?: (error: Error, variables: TVariables, context: TContext) => void | Promise<void>;\n onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables, context: TContext) => void | Promise<void>;\n}\n\n// ============================================================================\n// Toast Configuration\n// ============================================================================\n\nlet toastHandler: ToastHandler = {\n success: (msg) => console.log(\"[Success]\", msg),\n error: (msg) => console.error(\"[Error]\", msg),\n};\n\n/**\n * Configure toast handler. Call once at app init.\n *\n * @example\n * import { toast } from \"sonner\";\n * configureToast({ success: toast.success, error: toast.error });\n */\nexport function configureToast(handler: ToastHandler): void {\n toastHandler = handler;\n}\n\nfunction showToast(\n type: \"success\" | \"error\",\n messages: MutationMessages | undefined,\n data: unknown,\n variables: unknown,\n error?: Error,\n handler?: ToastHandler,\n) {\n const activeHandler = handler ?? toastHandler;\n\n if (type === \"success\") {\n const msg = messages?.success;\n if (!msg) return;\n\n const text = typeof msg === \"function\" ? msg(data, variables) : msg;\n activeHandler.success(text);\n } else {\n const msg = messages?.error;\n let defaultMsg = error?.message || \"An error occurred\";\n if (isArcApiError(error) && error.fieldErrors) {\n const fields = Object.entries(error.fieldErrors);\n if (fields.length > 0) {\n defaultMsg = fields.map(([k, v]) => `${k}: ${v}`).join(', ');\n }\n }\n const text = typeof msg === \"function\"\n ? msg(error as Error, variables)\n : msg || defaultMsg;\n\n activeHandler.error(text);\n }\n}\n\n// ============================================================================\n// Mutation with React 19 Transitions\n// ============================================================================\n\nexport interface TransitionMutationConfig<TData, TVariables> {\n mutationFn: (variables: TVariables) => Promise<TData>;\n invalidateQueries?: QueryKey[];\n onSuccess?: (data: TData, variables: TVariables) => void;\n onError?: (error: Error, variables: TVariables) => void;\n onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables) => void;\n messages?: MutationMessages;\n useTransition?: boolean;\n showToast?: boolean;\n toastHandler?: ToastHandler;\n}\n\nexport function useMutationWithTransition<TData, TVariables>(config: TransitionMutationConfig<TData, TVariables>) {\n const {\n mutationFn,\n invalidateQueries = [],\n onSuccess,\n onError,\n onSettled,\n messages,\n useTransition: withTransition = true,\n showToast: toast = true,\n toastHandler: instanceToast,\n } = config;\n\n const queryClient = useQueryClient();\n const [isTransitioning, startTransition] = useTransition();\n\n const mutation = useMutation({\n mutationFn,\n\n onSuccess: (data, variables) => {\n const invalidate = () => {\n invalidateQueries.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));\n };\n\n if (withTransition && invalidateQueries.length > 0) {\n startTransition(invalidate);\n } else {\n invalidate();\n }\n\n if (toast) showToast(\"success\", messages, data, variables, undefined, instanceToast);\n onSuccess?.(data, variables);\n },\n\n onError: (error, variables) => {\n if (toast) showToast(\"error\", messages, null, variables, error as Error, instanceToast);\n onError?.(error as Error, variables);\n },\n\n onSettled: (data, error, variables) => {\n onSettled?.(data, error as Error | null, variables);\n },\n });\n\n return {\n mutate: mutation.mutate,\n mutateAsync: mutation.mutateAsync,\n isPending: mutation.isPending || isTransitioning,\n isSuccess: mutation.isSuccess,\n isError: mutation.isError,\n error: mutation.error as Error | null,\n data: mutation.data,\n reset: mutation.reset,\n };\n}\n\n// ============================================================================\n// Mutation with Optimistic Updates\n// ============================================================================\n\nexport interface OptimisticMutationConfig<TData, TVariables> {\n mutationFn: (variables: TVariables) => Promise<TData>;\n queryKeys?: QueryKey[];\n optimisticUpdate?: (oldData: unknown, variables: TVariables) => unknown;\n onSuccess?: (data: TData, variables: TVariables) => void;\n onError?: (error: Error, variables: TVariables) => void;\n onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables) => void;\n messages?: MutationMessages;\n showToast?: boolean;\n toastHandler?: ToastHandler;\n}\n\nexport function useMutationWithOptimistic<TData, TVariables>(config: OptimisticMutationConfig<TData, TVariables>) {\n const {\n mutationFn,\n queryKeys = [],\n optimisticUpdate,\n onSuccess,\n onError,\n onSettled,\n messages,\n showToast: toast = true,\n toastHandler: instanceToast,\n } = config;\n\n const queryClient = useQueryClient();\n\n const mutation = useMutation({\n mutationFn,\n\n onMutate: async (variables) => {\n await Promise.all(queryKeys.map((key) => queryClient.cancelQueries({ queryKey: key })));\n\n const previous = queryKeys.map((key) => ({\n key,\n data: queryClient.getQueryData(key),\n }));\n\n if (optimisticUpdate) {\n queryKeys.forEach((key) => {\n queryClient.setQueryData(key, (old: unknown) => optimisticUpdate(old, variables));\n });\n }\n\n return { previous };\n },\n\n onSuccess: (data, variables) => {\n queryKeys.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));\n if (toast) showToast(\"success\", messages, data, variables, undefined, instanceToast);\n onSuccess?.(data, variables);\n },\n\n onError: (error, variables, context) => {\n const ctx = context as { previous?: Array<{ key: QueryKey; data: unknown }> };\n ctx?.previous?.forEach(({ key, data }) => queryClient.setQueryData(key, data));\n\n if (toast) showToast(\"error\", messages, null, variables, error as Error, instanceToast);\n onError?.(error as Error, variables);\n },\n\n onSettled: (data, error, variables) => {\n onSettled?.(data, error as Error | null, variables);\n },\n });\n\n return {\n mutate: mutation.mutate,\n mutateAsync: mutation.mutateAsync,\n isPending: mutation.isPending,\n isSuccess: mutation.isSuccess,\n isError: mutation.isError,\n error: mutation.error as Error | null,\n data: mutation.data,\n reset: mutation.reset,\n };\n}\n\n// ============================================================================\n// Optimistic Mutation for CRUD Factory (handles multiple matching queries)\n// ============================================================================\n\nexport interface CreateOptimisticMutationConfig<TData, TVariables> {\n mutationFn: (variables: TVariables) => Promise<TData>;\n queryClient: QueryClient;\n queryKeys: QueryKey[];\n optimisticUpdate?: (oldData: unknown, variables: TVariables) => unknown;\n onSuccess?: (data: TData, variables: TVariables) => void;\n onError?: (error: Error, variables: TVariables) => void;\n messages?: MutationMessages;\n toastHandler?: ToastHandler;\n}\n\nexport function createOptimisticMutation<TData, TVariables>({\n mutationFn,\n queryClient,\n queryKeys,\n optimisticUpdate,\n onSuccess,\n onError,\n messages,\n toastHandler: instanceToast,\n}: CreateOptimisticMutationConfig<TData, TVariables>) {\n return useMutation({\n mutationFn,\n\n onMutate: async (variables) => {\n await Promise.all(queryKeys.map((key) => queryClient.cancelQueries({ queryKey: key, exact: false })));\n\n const previous = queryKeys.map((key) => ({\n key,\n data: queryClient.getQueriesData({ queryKey: key }),\n }));\n\n if (optimisticUpdate) {\n queryKeys.forEach((key) => {\n queryClient.getQueriesData({ queryKey: key }).forEach(([qKey, qData]) => {\n queryClient.setQueryData(qKey, optimisticUpdate(qData, variables));\n });\n });\n }\n\n return { previous };\n },\n\n onSuccess: (data, variables) => {\n if (messages?.success) showToast(\"success\", messages, data, variables, undefined, instanceToast);\n queryKeys.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));\n onSuccess?.(data, variables);\n },\n\n onError: (error, variables, context) => {\n const ctx = context as { previous?: Array<{ key: QueryKey; data: Array<[QueryKey, unknown]> }> };\n ctx?.previous?.forEach(({ data }) => {\n data.forEach(([qKey, qData]) => queryClient.setQueryData(qKey, qData));\n });\n\n showToast(\"error\", messages, null, variables, error as Error, instanceToast);\n onError?.(error as Error, variables);\n },\n });\n}\n\n// ============================================================================\n// Query Config Presets\n// ============================================================================\n\nexport const QUERY_CONFIGS = {\n realtime: { staleTime: 20_000, refetchInterval: 30_000 },\n frequent: { staleTime: 60_000 },\n stable: { staleTime: 300_000 },\n static: { staleTime: 600_000 },\n} as const;\n"],"mappings":"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"}
1
+ {"version":3,"file":"mutation.js","names":[],"sources":["../src/mutation.ts"],"sourcesContent":["\"use client\";\n\nimport { useMutation, useQueryClient, type QueryClient, type QueryKey, type UseMutateFunction, type UseMutateAsyncFunction } from \"@tanstack/react-query\";\nimport { useTransition } from \"react\";\nimport { isArcApiError } from \"./client.js\";\nimport type { ToastHandler } from \"./client.js\";\n\n// Re-export for backward compatibility\nexport type { ToastHandler } from \"./client.js\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface MutationMessages {\n success?: string | ((data: unknown, variables: unknown) => string);\n error?: string | ((error: Error, variables: unknown) => string);\n}\n\nexport interface MutationCallbacks<TData, TVariables, TContext = unknown> {\n onMutate?: (variables: TVariables) => TContext | Promise<TContext>;\n onSuccess?: (data: TData, variables: TVariables, context: TContext) => void | Promise<void>;\n onError?: (error: Error, variables: TVariables, context: TContext) => void | Promise<void>;\n onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables, context: TContext) => void | Promise<void>;\n}\n\nexport interface TransitionMutationReturn<TData, TVariables> {\n mutate: UseMutateFunction<TData, Error, TVariables>;\n mutateAsync: UseMutateAsyncFunction<TData, Error, TVariables>;\n isPending: boolean;\n isSuccess: boolean;\n isError: boolean;\n error: Error | null;\n data: TData | undefined;\n reset: () => void;\n}\n\n// ============================================================================\n// Toast Configuration\n// ============================================================================\n\nlet toastHandler: ToastHandler = {\n success: (msg) => console.log(\"[Success]\", msg),\n error: (msg) => console.error(\"[Error]\", msg),\n};\n\n/**\n * Configure toast handler. Call once at app init.\n *\n * @example\n * import { toast } from \"sonner\";\n * configureToast({ success: toast.success, error: toast.error });\n */\nexport function configureToast(handler: ToastHandler): void {\n toastHandler = handler;\n}\n\nfunction showToast(\n type: \"success\" | \"error\",\n messages: MutationMessages | undefined,\n data: unknown,\n variables: unknown,\n error?: Error,\n handler?: ToastHandler,\n) {\n const activeHandler = handler ?? toastHandler;\n\n if (type === \"success\") {\n const msg = messages?.success;\n if (!msg) return;\n\n const text = typeof msg === \"function\" ? msg(data, variables) : msg;\n activeHandler.success(text);\n } else {\n const msg = messages?.error;\n let defaultMsg = error?.message || \"An error occurred\";\n if (isArcApiError(error) && error.fieldErrors) {\n const fields = Object.entries(error.fieldErrors);\n if (fields.length > 0) {\n defaultMsg = fields.map(([k, v]) => `${k}: ${v}`).join(', ');\n }\n }\n const text = typeof msg === \"function\"\n ? msg(error as Error, variables)\n : msg || defaultMsg;\n\n activeHandler.error(text);\n }\n}\n\n// ============================================================================\n// Mutation with React 19 Transitions\n// ============================================================================\n\nexport interface TransitionMutationConfig<TData, TVariables> {\n mutationFn: (variables: TVariables) => Promise<TData>;\n invalidateQueries?: QueryKey[];\n onSuccess?: (data: TData, variables: TVariables) => void;\n onError?: (error: Error, variables: TVariables) => void;\n onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables) => void;\n messages?: MutationMessages;\n useTransition?: boolean;\n showToast?: boolean;\n /** Per-call toast guard — return false to suppress toast for this invocation */\n shouldToast?: () => boolean;\n toastHandler?: ToastHandler;\n}\n\nexport function useMutationWithTransition<TData, TVariables>(config: TransitionMutationConfig<TData, TVariables>) {\n const {\n mutationFn,\n invalidateQueries = [],\n onSuccess,\n onError,\n onSettled,\n messages,\n useTransition: withTransition = true,\n showToast: toast = true,\n toastHandler: instanceToast,\n } = config;\n\n const queryClient = useQueryClient();\n const [isTransitioning, startTransition] = useTransition();\n\n const mutation = useMutation({\n mutationFn,\n\n onSuccess: (data, variables) => {\n const invalidate = () => {\n invalidateQueries.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));\n };\n\n if (withTransition && invalidateQueries.length > 0) {\n startTransition(invalidate);\n } else {\n invalidate();\n }\n\n const doToast = toast && (config.shouldToast?.() ?? true);\n if (doToast) showToast(\"success\", messages, data, variables, undefined, instanceToast);\n onSuccess?.(data, variables);\n },\n\n onError: (error, variables) => {\n const doToast = toast && (config.shouldToast?.() ?? true);\n if (doToast) showToast(\"error\", messages, null, variables, error as Error, instanceToast);\n onError?.(error as Error, variables);\n },\n\n onSettled: (data, error, variables) => {\n onSettled?.(data, error as Error | null, variables);\n },\n });\n\n return {\n mutate: mutation.mutate,\n mutateAsync: mutation.mutateAsync,\n isPending: mutation.isPending || isTransitioning,\n isSuccess: mutation.isSuccess,\n isError: mutation.isError,\n error: mutation.error as Error | null,\n data: mutation.data,\n reset: mutation.reset,\n };\n}\n\n// ============================================================================\n// Mutation with Optimistic Updates\n// ============================================================================\n\nexport interface OptimisticMutationConfig<TData, TVariables> {\n mutationFn: (variables: TVariables) => Promise<TData>;\n queryKeys?: QueryKey[];\n optimisticUpdate?: (oldData: unknown, variables: TVariables) => unknown;\n onSuccess?: (data: TData, variables: TVariables) => void;\n onError?: (error: Error, variables: TVariables) => void;\n onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables) => void;\n messages?: MutationMessages;\n showToast?: boolean;\n toastHandler?: ToastHandler;\n}\n\nexport function useMutationWithOptimistic<TData, TVariables>(config: OptimisticMutationConfig<TData, TVariables>) {\n const {\n mutationFn,\n queryKeys = [],\n optimisticUpdate,\n onSuccess,\n onError,\n onSettled,\n messages,\n showToast: toast = true,\n toastHandler: instanceToast,\n } = config;\n\n const queryClient = useQueryClient();\n\n const mutation = useMutation({\n mutationFn,\n\n onMutate: async (variables) => {\n await Promise.all(queryKeys.map((key) => queryClient.cancelQueries({ queryKey: key })));\n\n const previous = queryKeys.map((key) => ({\n key,\n data: queryClient.getQueryData(key),\n }));\n\n if (optimisticUpdate) {\n queryKeys.forEach((key) => {\n queryClient.setQueryData(key, (old: unknown) => optimisticUpdate(old, variables));\n });\n }\n\n return { previous };\n },\n\n onSuccess: (data, variables) => {\n queryKeys.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));\n if (toast) showToast(\"success\", messages, data, variables, undefined, instanceToast);\n onSuccess?.(data, variables);\n },\n\n onError: (error, variables, context) => {\n const ctx = context as { previous?: Array<{ key: QueryKey; data: unknown }> };\n ctx?.previous?.forEach(({ key, data }) => queryClient.setQueryData(key, data));\n\n if (toast) showToast(\"error\", messages, null, variables, error as Error, instanceToast);\n onError?.(error as Error, variables);\n },\n\n onSettled: (data, error, variables) => {\n onSettled?.(data, error as Error | null, variables);\n },\n });\n\n return {\n mutate: mutation.mutate,\n mutateAsync: mutation.mutateAsync,\n isPending: mutation.isPending,\n isSuccess: mutation.isSuccess,\n isError: mutation.isError,\n error: mutation.error as Error | null,\n data: mutation.data,\n reset: mutation.reset,\n };\n}\n\n// ============================================================================\n// Optimistic Mutation for CRUD Factory (handles multiple matching queries)\n// ============================================================================\n\nexport interface CreateOptimisticMutationConfig<TData, TVariables> {\n mutationFn: (variables: TVariables) => Promise<TData>;\n queryClient: QueryClient;\n queryKeys: QueryKey[];\n optimisticUpdate?: (oldData: unknown, variables: TVariables) => unknown;\n onSuccess?: (data: TData, variables: TVariables) => void;\n onError?: (error: Error, variables: TVariables) => void;\n onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables) => void;\n messages?: MutationMessages;\n /** Per-call toast guard — return false to suppress toast for this invocation */\n shouldToast?: () => boolean;\n toastHandler?: ToastHandler;\n}\n\nexport function createOptimisticMutation<TData, TVariables>(config: CreateOptimisticMutationConfig<TData, TVariables>) {\n const {\n mutationFn,\n queryClient,\n queryKeys,\n optimisticUpdate,\n onSuccess,\n onError,\n onSettled,\n messages,\n toastHandler: instanceToast,\n } = config;\n return useMutation({\n mutationFn,\n\n onMutate: async (variables) => {\n await Promise.all(queryKeys.map((key) => queryClient.cancelQueries({ queryKey: key, exact: false })));\n\n const previous = queryKeys.map((key) => ({\n key,\n data: queryClient.getQueriesData({ queryKey: key }),\n }));\n\n if (optimisticUpdate) {\n queryKeys.forEach((key) => {\n queryClient.getQueriesData({ queryKey: key }).forEach(([qKey, qData]) => {\n queryClient.setQueryData(qKey, optimisticUpdate(qData, variables));\n });\n });\n }\n\n return { previous };\n },\n\n onSuccess: (data, variables) => {\n const doToast = config.shouldToast?.() ?? true;\n if (doToast && messages?.success) showToast(\"success\", messages, data, variables, undefined, instanceToast);\n queryKeys.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));\n onSuccess?.(data, variables);\n },\n\n onError: (error, variables, context) => {\n const ctx = context as { previous?: Array<{ key: QueryKey; data: Array<[QueryKey, unknown]> }> };\n ctx?.previous?.forEach(({ data }) => {\n data.forEach(([qKey, qData]) => queryClient.setQueryData(qKey, qData));\n });\n\n const doToast = config.shouldToast?.() ?? true;\n if (doToast) showToast(\"error\", messages, null, variables, error as Error, instanceToast);\n onError?.(error as Error, variables);\n },\n\n onSettled: (data, error, variables) => {\n onSettled?.(data, error as Error | null, variables);\n },\n });\n}\n\n// ============================================================================\n// Query Config Presets\n// ============================================================================\n\nexport const QUERY_CONFIGS = {\n realtime: { staleTime: 20_000, refetchInterval: 30_000 },\n frequent: { staleTime: 60_000 },\n stable: { staleTime: 300_000 },\n static: { staleTime: 600_000 },\n} as const;\n"],"mappings":"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"}
package/dist/query.d.ts CHANGED
@@ -17,7 +17,7 @@ interface RequestPassthrough {
17
17
  headerOptions?: Record<string, string>;
18
18
  signal?: AbortSignal;
19
19
  }
20
- interface ListQueryOptions {
20
+ interface ListQueryOptions<TData = unknown> {
21
21
  public?: boolean;
22
22
  enabled?: boolean;
23
23
  staleTime?: number;
@@ -28,10 +28,12 @@ interface ListQueryOptions {
28
28
  refetchInterval?: number | false;
29
29
  refetchIntervalInBackground?: boolean;
30
30
  _scope?: string;
31
+ /** Transform raw API response before returning. Runs on each render, receives raw data. */
32
+ select?: (data: unknown) => TData;
31
33
  /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */
32
34
  request?: RequestPassthrough;
33
35
  }
34
- interface DetailQueryOptions {
36
+ interface DetailQueryOptions<TData = unknown> {
35
37
  public?: boolean;
36
38
  organizationId?: string | null;
37
39
  enabled?: boolean;
@@ -45,6 +47,8 @@ interface DetailQueryOptions {
45
47
  select?: string;
46
48
  populate?: string | string[];
47
49
  };
50
+ /** Transform raw API response before returning. Runs on each render, receives raw data. */
51
+ select?: (data: unknown) => TData;
48
52
  /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */
49
53
  request?: RequestPassthrough;
50
54
  }
@@ -107,6 +111,7 @@ interface CreateListQueryConfig {
107
111
  options?: Record<string, unknown>;
108
112
  prefillDetailCache?: boolean;
109
113
  detailKeyBuilder?: (id: string) => QueryKey;
114
+ select?: (data: unknown) => unknown;
110
115
  }
111
116
  declare function createListQuery<T>({
112
117
  queryKey,
@@ -114,7 +119,8 @@ declare function createListQuery<T>({
114
119
  enabled,
115
120
  options,
116
121
  prefillDetailCache,
117
- detailKeyBuilder
122
+ detailKeyBuilder,
123
+ select
118
124
  }: CreateListQueryConfig): ListQueryResult<T>;
119
125
  interface CreateDetailQueryConfig {
120
126
  queryKey: QueryKey;
@@ -123,12 +129,14 @@ interface CreateDetailQueryConfig {
123
129
  }) => Promise<unknown>;
124
130
  enabled?: boolean;
125
131
  options?: Record<string, unknown>;
132
+ select?: (data: unknown) => unknown;
126
133
  }
127
134
  declare function createDetailQuery<T>({
128
135
  queryKey,
129
136
  queryFn,
130
137
  enabled,
131
- options
138
+ options,
139
+ select
132
140
  }: CreateDetailQueryConfig): DetailQueryResult<T>;
133
141
  interface InfiniteListQueryOptions {
134
142
  public?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","names":[],"sources":["../src/query.ts"],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","names":[],"sources":["../src/query.ts"],"mappings":"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"}
package/dist/query.js CHANGED
@@ -107,14 +107,15 @@ function createCacheUtils(KEYS) {
107
107
  removeDetail: (client, id) => client.removeQueries({ queryKey: KEYS.detail(id) })
108
108
  };
109
109
  }
110
- function createListQuery({ queryKey, queryFn, enabled = true, options = {}, prefillDetailCache = true, detailKeyBuilder }) {
110
+ function createListQuery({ queryKey, queryFn, enabled = true, options = {}, prefillDetailCache = true, detailKeyBuilder, select }) {
111
111
  const queryClient = useQueryClient();
112
112
  const query = useQuery({
113
113
  queryKey,
114
- queryFn: () => queryFn({}),
114
+ queryFn: ({ signal }) => queryFn({ signal }),
115
115
  enabled,
116
116
  ...DEFAULT_QUERY_CONFIG,
117
117
  ...options,
118
+ ...select ? { select } : {},
118
119
  placeholderData: keepPreviousData
119
120
  });
120
121
  const items = extractItems(query.data);
@@ -144,13 +145,14 @@ function createListQuery({ queryKey, queryFn, enabled = true, options = {}, pref
144
145
  data: query.data
145
146
  };
146
147
  }
147
- function createDetailQuery({ queryKey, queryFn, enabled = true, options = {} }) {
148
+ function createDetailQuery({ queryKey, queryFn, enabled = true, options = {}, select }) {
148
149
  const query = useQuery({
149
150
  queryKey,
150
- queryFn: () => queryFn({}),
151
+ queryFn: ({ signal }) => queryFn({ signal }),
151
152
  enabled,
152
153
  ...DEFAULT_QUERY_CONFIG,
153
- ...options
154
+ ...options,
155
+ ...select ? { select } : {}
154
156
  });
155
157
  return {
156
158
  item: extractItem(query.data),
@@ -167,7 +169,10 @@ function createDetailQuery({ queryKey, queryFn, enabled = true, options = {} })
167
169
  function createInfiniteListQuery({ queryKey, queryFn, enabled = true, options = {}, initialPageParam = 1, getNextPageParam, getPreviousPageParam }) {
168
170
  const query = useInfiniteQuery({
169
171
  queryKey,
170
- queryFn: ({ pageParam }) => queryFn({ pageParam }),
172
+ queryFn: ({ pageParam, signal }) => queryFn({
173
+ pageParam,
174
+ signal
175
+ }),
171
176
  enabled,
172
177
  initialPageParam,
173
178
  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 /** Query params passed to getById (e.g. select, populate) */\n params?: { select?: string; populate?: string | string[] };\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 (Array.isArray(listData)) {\n return updater(listData as T[]);\n }\n\n if (typeof listData !== \"object\") return listData;\n const d = listData as Record<string, unknown>;\n\n // Detect the items array field: docs > data > items > results (same order as extractItems)\n const arrayField = \"docs\" in d ? \"docs\"\n : (Array.isArray(d.data) ? \"data\"\n : (\"items\" in d && Array.isArray(d.items) ? \"items\"\n : (\"results\" in d && Array.isArray(d.results) ? \"results\" : null)));\n\n if (!arrayField) return listData;\n\n const updated = updater(d[arrayField] as T[]);\n const original = d[arrayField] as T[];\n const delta = updated.length - original.length;\n\n // Update total/totalDocs when item count changes (optimistic add/delete)\n const result: Record<string, unknown> = { ...d, [arrayField]: updated };\n if (delta !== 0) {\n if (d.total != null) result.total = Math.max(0, Number(d.total) + delta);\n if (d.totalDocs != null) result.totalDocs = Math.max(0, Number(d.totalDocs) + delta);\n }\n\n return result;\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":";;;;;;AA0GA,MAAa,uBAAuB;CAClC,WAAW,MAAS;CACpB,QAAQ,OAAU;CAClB,sBAAsB;CACtB,OAAO;CACR;AAMD,SAAgB,UAAU,MAA8B;AACtD,KAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;CAC9C,MAAM,MAAM;CACZ,MAAM,KAAK,IAAI,OAAO,IAAI;AAC1B,QAAO,OAAO,OAAO,WAAW,KAAK,KAAK,OAAO,GAAG,GAAG;;AAGzD,SAAS,oBAAoB,MAAsC;AACjE,KAAI,CAAC,QAAQ,OAAO,SAAS,SAAU,QAAO;CAC9C,MAAM,IAAI;CAEV,MAAM,WAAW,EAAE,SAAS,QAAQ,EAAE,aAAa;CACnD,MAAM,WAAW,EAAE,SAAS,QAAQ,EAAE,cAAc;AACpD,KAAI,CAAC,YAAY,CAAC,SAAU,QAAO;AAEnC,QAAO;EACL,OAAO,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE;EAC1C,OAAO,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE;EAC3C,MAAM,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE;EAC1C,OAAO,OAAO,EAAE,SAAS,GAAG;EAC5B,SAAS,QAAQ,EAAE,WAAW,EAAE,eAAe,EAAE,WAAW,MAAM;EAClE,SAAS,QAAQ,EAAE,WAAW,EAAE,eAAe,MAAM;EACtD;;AAGH,SAAS,aAAgB,MAAoB;AAC3C,KAAI,CAAC,KAAM,QAAO,EAAE;AACpB,KAAI,MAAM,QAAQ,KAAK,CAAE,QAAO;AAChC,KAAI,OAAO,SAAS,SAAU,QAAO,EAAE;CAEvC,MAAM,IAAI;CACV,MAAM,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE;AAC/C,QAAO,MAAM,QAAQ,MAAM,GAAI,QAAgB,EAAE;;AAGnD,SAAS,YAAe,MAAyB;AAC/C,KAAI,CAAC,KAAM,QAAO;AAClB,KAAI,OAAO,SAAS,SAAU,QAAO;CAErC,MAAM,IAAI;AACV,QAAQ,EAAE,QAAQ;;AAGpB,SAAgB,gBAAmB,UAAmB,SAAuC;AAC3F,KAAI,CAAC,SAAU,QAAO;AAEtB,KAAI,MAAM,QAAQ,SAAS,CACzB,QAAO,QAAQ,SAAgB;AAGjC,KAAI,OAAO,aAAa,SAAU,QAAO;CACzC,MAAM,IAAI;CAGV,MAAM,aAAa,UAAU,IAAI,SAC5B,MAAM,QAAQ,EAAE,KAAK,GAAG,SACxB,WAAW,KAAK,MAAM,QAAQ,EAAE,MAAM,GAAG,UACzC,aAAa,KAAK,MAAM,QAAQ,EAAE,QAAQ,GAAG,YAAY;AAE9D,KAAI,CAAC,WAAY,QAAO;CAExB,MAAM,UAAU,QAAQ,EAAE,YAAmB;CAC7C,MAAM,WAAW,EAAE;CACnB,MAAM,QAAQ,QAAQ,SAAS,SAAS;CAGxC,MAAM,SAAkC;EAAE,GAAG;GAAI,aAAa;EAAS;AACvE,KAAI,UAAU,GAAG;AACf,MAAI,EAAE,SAAS,KAAM,QAAO,QAAQ,KAAK,IAAI,GAAG,OAAO,EAAE,MAAM,GAAG,MAAM;AACxE,MAAI,EAAE,aAAa,KAAM,QAAO,YAAY,KAAK,IAAI,GAAG,OAAO,EAAE,UAAU,GAAG,MAAM;;AAGtF,QAAO;;AAOT,SAAgB,gBAAgB,WAA8B;AAC5D,QAAO;EACL,KAAK,CAAC,UAAU;EAChB,aAAa,CAAC,WAAW,OAAO;EAChC,OAAO,WAAW;GAAC;GAAW;GAAQ;GAAO;EAC7C,eAAe,CAAC,WAAW,SAAS;EACpC,SAAS,OAAO;GAAC;GAAW;GAAU;GAAG;EACzC,SAAS,KAAK,GAAG,SAAS;GAAC;GAAW;GAAK,GAAG;GAAK;EACnD,aAAa,OAAO,WAAW;GAAC;GAAW;GAAQ;IAAE,QAAQ;IAAO,GAAI;IAAmB;GAAC;EAC7F;;AAOH,SAAgB,iBAAoB,MAAgC;AAClE,QAAO;EACL,gBAAgB,WAAW,OAAO,kBAAkB,EAAE,UAAU,KAAK,KAAK,CAAC;EAC3E,kBAAkB,WAAW,OAAO,kBAAkB,EAAE,UAAU,KAAK,OAAO,EAAE,CAAC;EACjF,mBAAmB,QAAQ,OAAO,OAAO,kBAAkB,EAAE,UAAU,KAAK,OAAO,GAAG,EAAE,CAAC;EACzF,YAAY,QAAQ,IAAI,SAAS,OAAO,aAAa,KAAK,OAAO,GAAG,EAAE,EAAE,MAAM,CAAC;EAC/E,YAAY,QAAQ,OAAO;AAEzB,UADe,OAAO,aAAa,KAAK,OAAO,GAAG,CAAC,EACpC;;EAEjB,eAAe,QAAQ,OAAO,OAAO,cAAc,EAAE,UAAU,KAAK,OAAO,GAAG,EAAE,CAAC;EAClF;;AAgBH,SAAgB,gBAAmB,EACjC,UACA,SACA,UAAU,MACV,UAAU,EAAE,EACZ,qBAAqB,MACrB,oBAC4C;CAC5C,MAAM,cAAc,gBAAgB;CAEpC,MAAM,QAAQ,SAAS;EACrB;EACA,eAAe,QAAQ,EAAE,CAAC;EAC1B;EACA,GAAG;EACH,GAAG;EACH,iBAAiB;EAClB,CAAC;CAEF,MAAM,QAAQ,aAAgB,MAAM,KAAK;CACzC,MAAM,aAAa,oBAAoB,MAAM,KAAK;AAElD,iBAAgB;AACd,MAAI,CAAC,sBAAsB,CAAC,oBAAoB,MAAM,WAAW,EAAG;AAEpE,QAAM,SAAS,SAAS;GACtB,MAAM,KAAK,UAAU,KAAK;AAC1B,OAAI,GAAI,aAAY,aAAa,iBAAiB,GAAG,EAAE,EAAE,MAAM,MAAM,CAAC;IACtE;IACD;EAAC;EAAO;EAAoB;EAAkB;EAAY,CAAC;AAE9D,QAAO;EACL;EACA;EACA,WAAW,MAAM;EACjB,YAAY,MAAM;EAClB,SAAS,MAAM;EACf,WAAW,MAAM;EACjB,SAAS,MAAM;EACf,OAAO,MAAM;EACb,SAAS,MAAM;EACf,MAAM,MAAM;EACb;;AAcH,SAAgB,kBAAqB,EACnC,UACA,SACA,UAAU,MACV,UAAU,EAAE,IACoC;CAChD,MAAM,QAAQ,SAAS;EACrB;EACA,eAAe,QAAQ,EAAE,CAAC;EAC1B;EACA,GAAG;EACH,GAAG;EACJ,CAAC;AAIF,QAAO;EACL,MAHW,YAAe,MAAM,KAAK;EAIrC,WAAW,MAAM;EACjB,YAAY,MAAM;EAClB,SAAS,MAAM;EACf,WAAW,MAAM;EACjB,SAAS,MAAM;EACf,OAAO,MAAM;EACb,SAAS,MAAM;EACf,MAAM,MAAM;EACb;;AA6CH,SAAgB,wBAA2B,EACzC,UACA,SACA,UAAU,MACV,UAAU,EAAE,EACZ,mBAAmB,GACnB,kBACA,wBAC4D;CAC5D,MAAM,QAAQ,iBAAiB;EAC7B;EACA,UAAU,EAAE,gBAAgB,QAAQ,EAAE,WAAW,CAAC;EAClD;EACA;EACA;EACA;EACA,GAAG;EACH,GAAG;EACJ,CAAC;AAIF,QAAO;EACL,OAHiB,MAAM,MAAM,MAAM,SAAS,SAAS,aAAgB,KAAK,CAAC,IAAI,EAAE;EAIjF,aAAa,MAAM;EACnB,iBAAiB,MAAM;EACvB,oBAAoB,MAAM;EAC1B,wBAAwB,MAAM;EAC9B,eAAe,MAAM;EACrB,mBAAmB,MAAM;EACzB,WAAW,MAAM;EACjB,YAAY,MAAM;EAClB,SAAS,MAAM;EACf,WAAW,MAAM;EACjB,OAAO,MAAM;EACb,SAAS,MAAM;EACf,MAAM,MAAM;EACb"}
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<TData = unknown> {\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 /** Transform raw API response before returning. Runs on each render, receives raw data. */\n select?: (data: unknown) => TData;\n /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */\n request?: RequestPassthrough;\n}\n\nexport interface DetailQueryOptions<TData = unknown> {\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 /** Query params passed to getById (e.g. select, populate) */\n params?: { select?: string; populate?: string | string[] };\n /** Transform raw API response before returning. Runs on each render, receives raw data. */\n select?: (data: unknown) => TData;\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 (Array.isArray(listData)) {\n return updater(listData as T[]);\n }\n\n if (typeof listData !== \"object\") return listData;\n const d = listData as Record<string, unknown>;\n\n // Detect the items array field: docs > data > items > results (same order as extractItems)\n const arrayField = \"docs\" in d ? \"docs\"\n : (Array.isArray(d.data) ? \"data\"\n : (\"items\" in d && Array.isArray(d.items) ? \"items\"\n : (\"results\" in d && Array.isArray(d.results) ? \"results\" : null)));\n\n if (!arrayField) return listData;\n\n const updated = updater(d[arrayField] as T[]);\n const original = d[arrayField] as T[];\n const delta = updated.length - original.length;\n\n // Update total/totalDocs when item count changes (optimistic add/delete)\n const result: Record<string, unknown> = { ...d, [arrayField]: updated };\n if (delta !== 0) {\n if (d.total != null) result.total = Math.max(0, Number(d.total) + delta);\n if (d.totalDocs != null) result.totalDocs = Math.max(0, Number(d.totalDocs) + delta);\n }\n\n return result;\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 select?: (data: unknown) => unknown;\n}\n\nexport function createListQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n prefillDetailCache = true,\n detailKeyBuilder,\n select,\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 ...(select ? { select } : {}),\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 select?: (data: unknown) => unknown;\n}\n\nexport function createDetailQuery<T>({\n queryKey,\n queryFn,\n enabled = true,\n options = {},\n select,\n}: CreateDetailQueryConfig): DetailQueryResult<T> {\n const query = useQuery({\n queryKey,\n queryFn: ({ signal }) => queryFn({ signal }),\n enabled,\n ...DEFAULT_QUERY_CONFIG,\n ...options,\n ...(select ? { select } : {}),\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, signal }) => queryFn({ pageParam, signal }),\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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/arc-next",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "React + TanStack Query SDK for Arc resources",
5
5
  "type": "module",
6
6
  "sideEffects": false,