@classytic/arc-next 0.1.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.
@@ -0,0 +1,160 @@
1
+ "use client";
2
+
3
+ import { isArcApiError } from "./client.js";
4
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
5
+ import { useTransition } from "react";
6
+
7
+ //#region src/mutation.ts
8
+ let toastHandler = {
9
+ success: (msg) => console.log("[Success]", msg),
10
+ error: (msg) => console.error("[Error]", msg)
11
+ };
12
+ /**
13
+ * Configure toast handler. Call once at app init.
14
+ *
15
+ * @example
16
+ * import { toast } from "sonner";
17
+ * configureToast({ success: toast.success, error: toast.error });
18
+ */
19
+ function configureToast(handler) {
20
+ toastHandler = handler;
21
+ }
22
+ function showToast(type, messages, data, variables, error, handler) {
23
+ const activeHandler = handler ?? toastHandler;
24
+ if (type === "success") {
25
+ const msg = messages?.success;
26
+ if (!msg) return;
27
+ const text = typeof msg === "function" ? msg(data, variables) : msg;
28
+ activeHandler.success(text);
29
+ } else {
30
+ const msg = messages?.error;
31
+ let defaultMsg = error?.message || "An error occurred";
32
+ if (isArcApiError(error) && error.fieldErrors) {
33
+ const fields = Object.entries(error.fieldErrors);
34
+ if (fields.length > 0) defaultMsg = fields.map(([k, v]) => `${k}: ${v}`).join(", ");
35
+ }
36
+ const text = typeof msg === "function" ? msg(error, variables) : msg || defaultMsg;
37
+ activeHandler.error(text);
38
+ }
39
+ }
40
+ function useMutationWithTransition(config) {
41
+ const { mutationFn, invalidateQueries = [], onSuccess, onError, onSettled, messages, useTransition: withTransition = true, showToast: toast = true, toastHandler: instanceToast } = config;
42
+ const queryClient = useQueryClient();
43
+ const [isTransitioning, startTransition] = useTransition();
44
+ const mutation = useMutation({
45
+ mutationFn,
46
+ onSuccess: (data, variables) => {
47
+ const invalidate = () => {
48
+ invalidateQueries.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));
49
+ };
50
+ if (withTransition && invalidateQueries.length > 0) startTransition(invalidate);
51
+ else invalidate();
52
+ if (toast) showToast("success", messages, data, variables, void 0, instanceToast);
53
+ onSuccess?.(data, variables);
54
+ },
55
+ onError: (error, variables) => {
56
+ if (toast) showToast("error", messages, null, variables, error, instanceToast);
57
+ onError?.(error, variables);
58
+ },
59
+ onSettled: (data, error, variables) => {
60
+ onSettled?.(data, error, variables);
61
+ }
62
+ });
63
+ return {
64
+ mutate: mutation.mutate,
65
+ mutateAsync: mutation.mutateAsync,
66
+ isPending: mutation.isPending || isTransitioning,
67
+ isSuccess: mutation.isSuccess,
68
+ isError: mutation.isError,
69
+ error: mutation.error,
70
+ data: mutation.data,
71
+ reset: mutation.reset
72
+ };
73
+ }
74
+ function useMutationWithOptimistic(config) {
75
+ const { mutationFn, queryKeys = [], optimisticUpdate, onSuccess, onError, onSettled, messages, showToast: toast = true, toastHandler: instanceToast } = config;
76
+ const queryClient = useQueryClient();
77
+ const mutation = useMutation({
78
+ mutationFn,
79
+ onMutate: async (variables) => {
80
+ await Promise.all(queryKeys.map((key) => queryClient.cancelQueries({ queryKey: key })));
81
+ const previous = queryKeys.map((key) => ({
82
+ key,
83
+ data: queryClient.getQueryData(key)
84
+ }));
85
+ if (optimisticUpdate) queryKeys.forEach((key) => {
86
+ queryClient.setQueryData(key, (old) => optimisticUpdate(old, variables));
87
+ });
88
+ return { previous };
89
+ },
90
+ onSuccess: (data, variables) => {
91
+ queryKeys.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));
92
+ if (toast) showToast("success", messages, data, variables, void 0, instanceToast);
93
+ onSuccess?.(data, variables);
94
+ },
95
+ onError: (error, variables, context) => {
96
+ context?.previous?.forEach(({ key, data }) => queryClient.setQueryData(key, data));
97
+ if (toast) showToast("error", messages, null, variables, error, instanceToast);
98
+ onError?.(error, variables);
99
+ },
100
+ onSettled: (data, error, variables) => {
101
+ onSettled?.(data, error, variables);
102
+ }
103
+ });
104
+ return {
105
+ mutate: mutation.mutate,
106
+ mutateAsync: mutation.mutateAsync,
107
+ isPending: mutation.isPending,
108
+ isSuccess: mutation.isSuccess,
109
+ isError: mutation.isError,
110
+ error: mutation.error,
111
+ data: mutation.data,
112
+ reset: mutation.reset
113
+ };
114
+ }
115
+ function createOptimisticMutation({ mutationFn, queryClient, queryKeys, optimisticUpdate, onSuccess, onError, messages, toastHandler: instanceToast }) {
116
+ return useMutation({
117
+ mutationFn,
118
+ onMutate: async (variables) => {
119
+ await Promise.all(queryKeys.map((key) => queryClient.cancelQueries({
120
+ queryKey: key,
121
+ exact: false
122
+ })));
123
+ const previous = queryKeys.map((key) => ({
124
+ key,
125
+ data: queryClient.getQueriesData({ queryKey: key })
126
+ }));
127
+ if (optimisticUpdate) queryKeys.forEach((key) => {
128
+ queryClient.getQueriesData({ queryKey: key }).forEach(([qKey, qData]) => {
129
+ queryClient.setQueryData(qKey, optimisticUpdate(qData, variables));
130
+ });
131
+ });
132
+ return { previous };
133
+ },
134
+ onSuccess: (data, variables) => {
135
+ if (messages?.success) showToast("success", messages, data, variables, void 0, instanceToast);
136
+ queryKeys.forEach((key) => queryClient.invalidateQueries({ queryKey: key }));
137
+ onSuccess?.(data, variables);
138
+ },
139
+ onError: (error, variables, context) => {
140
+ context?.previous?.forEach(({ data }) => {
141
+ data.forEach(([qKey, qData]) => queryClient.setQueryData(qKey, qData));
142
+ });
143
+ showToast("error", messages, null, variables, error, instanceToast);
144
+ onError?.(error, variables);
145
+ }
146
+ });
147
+ }
148
+ const QUERY_CONFIGS = {
149
+ realtime: {
150
+ staleTime: 2e4,
151
+ refetchInterval: 3e4
152
+ },
153
+ frequent: { staleTime: 6e4 },
154
+ stable: { staleTime: 3e5 },
155
+ static: { staleTime: 6e5 }
156
+ };
157
+
158
+ //#endregion
159
+ export { QUERY_CONFIGS, configureToast, createOptimisticMutation, useMutationWithOptimistic, useMutationWithTransition };
160
+ //# sourceMappingURL=mutation.js.map
@@ -0,0 +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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"}
@@ -0,0 +1,64 @@
1
+ import { QueryClient, dehydrate } from "@tanstack/react-query";
2
+
3
+ //#region src/prefetch.d.ts
4
+ interface PrefetchOptions {
5
+ staleTime?: number;
6
+ }
7
+ interface CrudPrefetcher {
8
+ /**
9
+ * Prefetch a list query on the server. Uses the same query keys as useList.
10
+ *
11
+ * @example
12
+ * const queryClient = getQueryClient();
13
+ * await productsPrefetcher.prefetchList(queryClient, { limit: 20 });
14
+ */
15
+ prefetchList: (queryClient: QueryClient, params?: Record<string, unknown>, options?: PrefetchOptions) => Promise<void>;
16
+ /**
17
+ * Prefetch a detail query on the server. Uses the same query keys as useDetail.
18
+ *
19
+ * @example
20
+ * const queryClient = getQueryClient();
21
+ * await productsPrefetcher.prefetchDetail(queryClient, productId);
22
+ */
23
+ prefetchDetail: (queryClient: QueryClient, id: string, options?: PrefetchOptions) => Promise<void>;
24
+ }
25
+ /**
26
+ * Create server-safe prefetch helpers for CRUD queries.
27
+ * Use in Next.js server components to pre-populate the query cache before rendering.
28
+ *
29
+ * @example
30
+ * // products-prefetch.ts
31
+ * import { productsApi } from '@/api/products-api';
32
+ * import { createCrudPrefetcher } from '@classytic/arc-next/prefetch';
33
+ * export const productsPrefetcher = createCrudPrefetcher(productsApi, 'products');
34
+ *
35
+ * // app/products/page.tsx (server component)
36
+ * import { getQueryClient } from '@classytic/arc-next/query-client';
37
+ * import { dehydrate } from '@classytic/arc-next/prefetch';
38
+ * import { HydrationBoundary } from '@tanstack/react-query';
39
+ *
40
+ * export default async function ProductsPage() {
41
+ * const queryClient = getQueryClient();
42
+ * await productsPrefetcher.prefetchList(queryClient, { limit: 20 });
43
+ * return (
44
+ * <HydrationBoundary state={dehydrate(queryClient)}>
45
+ * <ProductsList />
46
+ * </HydrationBoundary>
47
+ * );
48
+ * }
49
+ */
50
+ declare function createCrudPrefetcher(api: {
51
+ getAll: (opts: {
52
+ params?: Record<string, unknown>;
53
+ token?: string | null;
54
+ organizationId?: string | null;
55
+ }) => Promise<unknown>;
56
+ getById: (opts: {
57
+ id: string;
58
+ token?: string | null;
59
+ organizationId?: string | null;
60
+ }) => Promise<unknown>;
61
+ }, entityKey: string): CrudPrefetcher;
62
+ //#endregion
63
+ export { CrudPrefetcher, PrefetchOptions, createCrudPrefetcher, dehydrate };
64
+ //# sourceMappingURL=prefetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefetch.d.ts","names":[],"sources":["../src/prefetch.ts"],"mappings":";;;UASiB,eAAA;EACf,SAAA;AAAA;AAAA,UAGe,cAAA;EAHf;;AAGF;;;;;EAQE,YAAA,GACE,WAAA,EAAa,WAAA,EACb,MAAA,GAAS,MAAA,mBACT,OAAA,GAAU,eAAA,KACP,OAAA;EAAA;;;;;;;EASL,cAAA,GACE,WAAA,EAAa,WAAA,EACb,EAAA,UACA,OAAA,GAAU,eAAA,KACP,OAAA;AAAA;;;;;;;;;;;;;;;AA4CP;;;;;;;;;;;iBAAgB,oBAAA,CACd,GAAA;EACE,MAAA,GAAS,IAAA;IACP,MAAA,GAAS,MAAA;IACT,KAAA;IACA,cAAA;EAAA,MACI,OAAA;EACN,OAAA,GAAU,IAAA;IACR,EAAA;IACA,KAAA;IACA,cAAA;EAAA,MACI,OAAA;AAAA,GAER,SAAA,WACC,cAAA"}
@@ -0,0 +1,76 @@
1
+ import { dehydrate } from "@tanstack/react-query";
2
+
3
+ //#region src/prefetch.ts
4
+ function scopedListKey(entityKey, scope, params) {
5
+ return [
6
+ entityKey,
7
+ "list",
8
+ {
9
+ _scope: scope,
10
+ ...params || {}
11
+ }
12
+ ];
13
+ }
14
+ function detailKey(entityKey, id) {
15
+ return [
16
+ entityKey,
17
+ "detail",
18
+ id
19
+ ];
20
+ }
21
+ /**
22
+ * Create server-safe prefetch helpers for CRUD queries.
23
+ * Use in Next.js server components to pre-populate the query cache before rendering.
24
+ *
25
+ * @example
26
+ * // products-prefetch.ts
27
+ * import { productsApi } from '@/api/products-api';
28
+ * import { createCrudPrefetcher } from '@classytic/arc-next/prefetch';
29
+ * export const productsPrefetcher = createCrudPrefetcher(productsApi, 'products');
30
+ *
31
+ * // app/products/page.tsx (server component)
32
+ * import { getQueryClient } from '@classytic/arc-next/query-client';
33
+ * import { dehydrate } from '@classytic/arc-next/prefetch';
34
+ * import { HydrationBoundary } from '@tanstack/react-query';
35
+ *
36
+ * export default async function ProductsPage() {
37
+ * const queryClient = getQueryClient();
38
+ * await productsPrefetcher.prefetchList(queryClient, { limit: 20 });
39
+ * return (
40
+ * <HydrationBoundary state={dehydrate(queryClient)}>
41
+ * <ProductsList />
42
+ * </HydrationBoundary>
43
+ * );
44
+ * }
45
+ */
46
+ function createCrudPrefetcher(api, entityKey) {
47
+ return {
48
+ async prefetchList(queryClient, params = {}, options = {}) {
49
+ const { organizationId, ...restParams } = params;
50
+ const queryKey = scopedListKey(entityKey, organizationId ? "tenant" : "super-admin", {
51
+ organizationId,
52
+ ...restParams
53
+ });
54
+ await queryClient.prefetchQuery({
55
+ queryKey,
56
+ queryFn: () => api.getAll({
57
+ params: restParams,
58
+ organizationId: organizationId ?? null
59
+ }),
60
+ staleTime: options.staleTime
61
+ });
62
+ },
63
+ async prefetchDetail(queryClient, id, options = {}) {
64
+ const queryKey = detailKey(entityKey, id);
65
+ await queryClient.prefetchQuery({
66
+ queryKey,
67
+ queryFn: () => api.getById({ id }),
68
+ staleTime: options.staleTime
69
+ });
70
+ }
71
+ };
72
+ }
73
+
74
+ //#endregion
75
+ export { createCrudPrefetcher, dehydrate };
76
+ //# sourceMappingURL=prefetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prefetch.js","names":[],"sources":["../src/prefetch.ts"],"sourcesContent":["import { dehydrate, type QueryClient, type QueryKey } from '@tanstack/react-query';\n\n// Re-export for convenience in server components\nexport { dehydrate } from '@tanstack/react-query';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface PrefetchOptions {\n staleTime?: number;\n}\n\nexport interface CrudPrefetcher {\n /**\n * Prefetch a list query on the server. Uses the same query keys as useList.\n *\n * @example\n * const queryClient = getQueryClient();\n * await productsPrefetcher.prefetchList(queryClient, { limit: 20 });\n */\n prefetchList: (\n queryClient: QueryClient,\n params?: Record<string, unknown>,\n options?: PrefetchOptions,\n ) => Promise<void>;\n\n /**\n * Prefetch a detail query on the server. Uses the same query keys as useDetail.\n *\n * @example\n * const queryClient = getQueryClient();\n * await productsPrefetcher.prefetchDetail(queryClient, productId);\n */\n prefetchDetail: (\n queryClient: QueryClient,\n id: string,\n options?: PrefetchOptions,\n ) => Promise<void>;\n}\n\n// ============================================================================\n// Query Key Generators (must match createQueryKeys in query.ts)\n// ============================================================================\n\nfunction scopedListKey(entityKey: string, scope: string, params?: Record<string, unknown>): QueryKey {\n return [entityKey, 'list', { _scope: scope, ...(params || {}) }];\n}\n\nfunction detailKey(entityKey: string, id: string): QueryKey {\n return [entityKey, 'detail', id];\n}\n\n// ============================================================================\n// Factory\n// ============================================================================\n\n/**\n * Create server-safe prefetch helpers for CRUD queries.\n * Use in Next.js server components to pre-populate the query cache before rendering.\n *\n * @example\n * // products-prefetch.ts\n * import { productsApi } from '@/api/products-api';\n * import { createCrudPrefetcher } from '@classytic/arc-next/prefetch';\n * export const productsPrefetcher = createCrudPrefetcher(productsApi, 'products');\n *\n * // app/products/page.tsx (server component)\n * import { getQueryClient } from '@classytic/arc-next/query-client';\n * import { dehydrate } from '@classytic/arc-next/prefetch';\n * import { HydrationBoundary } from '@tanstack/react-query';\n *\n * export default async function ProductsPage() {\n * const queryClient = getQueryClient();\n * await productsPrefetcher.prefetchList(queryClient, { limit: 20 });\n * return (\n * <HydrationBoundary state={dehydrate(queryClient)}>\n * <ProductsList />\n * </HydrationBoundary>\n * );\n * }\n */\nexport function createCrudPrefetcher(\n api: {\n getAll: (opts: {\n params?: Record<string, unknown>;\n token?: string | null;\n organizationId?: string | null;\n }) => Promise<unknown>;\n getById: (opts: {\n id: string;\n token?: string | null;\n organizationId?: string | null;\n }) => Promise<unknown>;\n },\n entityKey: string,\n): CrudPrefetcher {\n return {\n async prefetchList(queryClient, params = {}, options = {}) {\n const { organizationId, ...restParams } = params;\n const scope = organizationId ? 'tenant' : 'super-admin';\n const queryKey = scopedListKey(entityKey, scope, { organizationId, ...restParams });\n\n await queryClient.prefetchQuery({\n queryKey,\n queryFn: () => api.getAll({\n params: restParams,\n organizationId: (organizationId as string | null) ?? null,\n }),\n staleTime: options.staleTime,\n });\n },\n\n async prefetchDetail(queryClient, id, options = {}) {\n const queryKey = detailKey(entityKey, id);\n\n await queryClient.prefetchQuery({\n queryKey,\n queryFn: () => api.getById({ id }),\n staleTime: options.staleTime,\n });\n },\n };\n}\n"],"mappings":";;;AA6CA,SAAS,cAAc,WAAmB,OAAe,QAA4C;AACnG,QAAO;EAAC;EAAW;EAAQ;GAAE,QAAQ;GAAO,GAAI,UAAU,EAAE;GAAG;EAAC;;AAGlE,SAAS,UAAU,WAAmB,IAAsB;AAC1D,QAAO;EAAC;EAAW;EAAU;EAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgClC,SAAgB,qBACd,KAYA,WACgB;AAChB,QAAO;EACL,MAAM,aAAa,aAAa,SAAS,EAAE,EAAE,UAAU,EAAE,EAAE;GACzD,MAAM,EAAE,gBAAgB,GAAG,eAAe;GAE1C,MAAM,WAAW,cAAc,WADjB,iBAAiB,WAAW,eACO;IAAE;IAAgB,GAAG;IAAY,CAAC;AAEnF,SAAM,YAAY,cAAc;IAC9B;IACA,eAAe,IAAI,OAAO;KACxB,QAAQ;KACR,gBAAiB,kBAAoC;KACtD,CAAC;IACF,WAAW,QAAQ;IACpB,CAAC;;EAGJ,MAAM,eAAe,aAAa,IAAI,UAAU,EAAE,EAAE;GAClD,MAAM,WAAW,UAAU,WAAW,GAAG;AAEzC,SAAM,YAAY,cAAc;IAC9B;IACA,eAAe,IAAI,QAAQ,EAAE,IAAI,CAAC;IAClC,WAAW,QAAQ;IACpB,CAAC;;EAEL"}
@@ -0,0 +1,25 @@
1
+ import { QueryClient } from "@tanstack/react-query";
2
+
3
+ //#region src/query-client.d.ts
4
+ interface QueryClientOverrides {
5
+ staleTime?: number;
6
+ gcTime?: number;
7
+ retry?: number | boolean;
8
+ refetchOnWindowFocus?: boolean;
9
+ }
10
+ /**
11
+ * SSR-safe QueryClient singleton factory.
12
+ * Server: always creates a new instance (one per request).
13
+ * Browser: reuses a singleton (survives Suspense re-renders).
14
+ *
15
+ * @example
16
+ * // In layout.tsx or providers
17
+ * const queryClient = getQueryClient();
18
+ *
19
+ * // With overrides
20
+ * const queryClient = getQueryClient({ staleTime: 60_000 });
21
+ */
22
+ declare function getQueryClient(overrides?: QueryClientOverrides): QueryClient;
23
+ //#endregion
24
+ export { QueryClientOverrides, getQueryClient };
25
+ //# sourceMappingURL=query-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-client.d.ts","names":[],"sources":["../src/query-client.ts"],"mappings":";;;UAUiB,oBAAA;EACf,SAAA;EACA,MAAA;EACA,KAAA;EACA,oBAAA;AAAA;;;;;;;AAoDF;;;;;;iBAAgB,cAAA,CAAe,SAAA,GAAY,oBAAA,GAAuB,WAAA"}
@@ -0,0 +1,46 @@
1
+ import { QueryClient, defaultShouldDehydrateQuery, isServer } from "@tanstack/react-query";
2
+
3
+ //#region src/query-client.ts
4
+ const DEFAULTS = {
5
+ staleTime: 300 * 1e3,
6
+ gcTime: 1800 * 1e3,
7
+ retry: 0,
8
+ refetchOnWindowFocus: false
9
+ };
10
+ function makeQueryClient(overrides) {
11
+ const opts = {
12
+ ...DEFAULTS,
13
+ ...overrides
14
+ };
15
+ return new QueryClient({ defaultOptions: {
16
+ queries: {
17
+ retry: opts.retry,
18
+ staleTime: opts.staleTime,
19
+ gcTime: opts.gcTime,
20
+ refetchOnWindowFocus: opts.refetchOnWindowFocus
21
+ },
22
+ dehydrate: { shouldDehydrateQuery: (query) => defaultShouldDehydrateQuery(query) || query.state.status === "pending" }
23
+ } });
24
+ }
25
+ let browserQueryClient;
26
+ /**
27
+ * SSR-safe QueryClient singleton factory.
28
+ * Server: always creates a new instance (one per request).
29
+ * Browser: reuses a singleton (survives Suspense re-renders).
30
+ *
31
+ * @example
32
+ * // In layout.tsx or providers
33
+ * const queryClient = getQueryClient();
34
+ *
35
+ * // With overrides
36
+ * const queryClient = getQueryClient({ staleTime: 60_000 });
37
+ */
38
+ function getQueryClient(overrides) {
39
+ if (isServer) return makeQueryClient(overrides);
40
+ if (!browserQueryClient) browserQueryClient = makeQueryClient(overrides);
41
+ return browserQueryClient;
42
+ }
43
+
44
+ //#endregion
45
+ export { getQueryClient };
46
+ //# sourceMappingURL=query-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query-client.js","names":[],"sources":["../src/query-client.ts"],"sourcesContent":["import {\n isServer,\n QueryClient,\n defaultShouldDehydrateQuery,\n} from '@tanstack/react-query';\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface QueryClientOverrides {\n staleTime?: number;\n gcTime?: number;\n retry?: number | boolean;\n refetchOnWindowFocus?: boolean;\n}\n\n// ============================================================================\n// Defaults\n// ============================================================================\n\nconst DEFAULTS: Required<QueryClientOverrides> = {\n staleTime: 5 * 60 * 1000,\n gcTime: 30 * 60 * 1000,\n retry: 0,\n refetchOnWindowFocus: false,\n};\n\n// ============================================================================\n// Factory\n// ============================================================================\n\nfunction makeQueryClient(overrides?: QueryClientOverrides): QueryClient {\n const opts = { ...DEFAULTS, ...overrides };\n\n return new QueryClient({\n defaultOptions: {\n queries: {\n retry: opts.retry as number,\n staleTime: opts.staleTime,\n gcTime: opts.gcTime,\n refetchOnWindowFocus: opts.refetchOnWindowFocus,\n },\n dehydrate: {\n shouldDehydrateQuery: (query) =>\n defaultShouldDehydrateQuery(query) ||\n query.state.status === 'pending',\n },\n },\n });\n}\n\nlet browserQueryClient: QueryClient | undefined;\n\n/**\n * SSR-safe QueryClient singleton factory.\n * Server: always creates a new instance (one per request).\n * Browser: reuses a singleton (survives Suspense re-renders).\n *\n * @example\n * // In layout.tsx or providers\n * const queryClient = getQueryClient();\n *\n * // With overrides\n * const queryClient = getQueryClient({ staleTime: 60_000 });\n */\nexport function getQueryClient(overrides?: QueryClientOverrides): QueryClient {\n if (isServer) {\n return makeQueryClient(overrides);\n }\n\n if (!browserQueryClient) {\n browserQueryClient = makeQueryClient(overrides);\n }\n return browserQueryClient;\n}\n"],"mappings":";;;AAqBA,MAAM,WAA2C;CAC/C,WAAW,MAAS;CACpB,QAAQ,OAAU;CAClB,OAAO;CACP,sBAAsB;CACvB;AAMD,SAAS,gBAAgB,WAA+C;CACtE,MAAM,OAAO;EAAE,GAAG;EAAU,GAAG;EAAW;AAE1C,QAAO,IAAI,YAAY,EACrB,gBAAgB;EACd,SAAS;GACP,OAAO,KAAK;GACZ,WAAW,KAAK;GAChB,QAAQ,KAAK;GACb,sBAAsB,KAAK;GAC5B;EACD,WAAW,EACT,uBAAuB,UACrB,4BAA4B,MAAM,IAClC,MAAM,MAAM,WAAW,WAC1B;EACF,EACF,CAAC;;AAGJ,IAAI;;;;;;;;;;;;;AAcJ,SAAgB,eAAe,WAA+C;AAC5E,KAAI,SACF,QAAO,gBAAgB,UAAU;AAGnC,KAAI,CAAC,mBACH,sBAAqB,gBAAgB,UAAU;AAEjD,QAAO"}
@@ -0,0 +1,177 @@
1
+ import { InfiniteData, QueryClient, QueryKey } from "@tanstack/react-query";
2
+
3
+ //#region src/query.d.ts
4
+ interface PaginationData {
5
+ total: number;
6
+ pages: number;
7
+ page: number;
8
+ limit: number;
9
+ hasNext: boolean;
10
+ hasPrev: boolean;
11
+ }
12
+ /** Request-level options passed through to the fetch call */
13
+ interface RequestPassthrough {
14
+ cache?: RequestCache;
15
+ revalidate?: number;
16
+ tags?: string[];
17
+ headerOptions?: Record<string, string>;
18
+ signal?: AbortSignal;
19
+ }
20
+ interface ListQueryOptions {
21
+ public?: boolean;
22
+ enabled?: boolean;
23
+ staleTime?: number;
24
+ gcTime?: number;
25
+ refetchOnWindowFocus?: boolean;
26
+ structuralSharing?: boolean;
27
+ prefillDetailCache?: boolean;
28
+ refetchInterval?: number | false;
29
+ refetchIntervalInBackground?: boolean;
30
+ _scope?: string;
31
+ /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */
32
+ request?: RequestPassthrough;
33
+ }
34
+ interface DetailQueryOptions {
35
+ public?: boolean;
36
+ organizationId?: string | null;
37
+ enabled?: boolean;
38
+ staleTime?: number;
39
+ gcTime?: number;
40
+ structuralSharing?: boolean;
41
+ refetchInterval?: number | false;
42
+ refetchIntervalInBackground?: boolean;
43
+ /** Pass-through options for the underlying fetch request (cache, revalidate, tags, headers) */
44
+ request?: RequestPassthrough;
45
+ }
46
+ interface ListQueryResult<T> {
47
+ items: T[];
48
+ pagination: PaginationData | null;
49
+ isLoading: boolean;
50
+ isFetching: boolean;
51
+ isError: boolean;
52
+ isSuccess: boolean;
53
+ isStale: boolean;
54
+ error: Error | null;
55
+ refetch: () => Promise<unknown>;
56
+ data: unknown;
57
+ }
58
+ interface DetailQueryResult<T> {
59
+ item: T | null;
60
+ isLoading: boolean;
61
+ isFetching: boolean;
62
+ isError: boolean;
63
+ isSuccess: boolean;
64
+ isStale: boolean;
65
+ error: Error | null;
66
+ refetch: () => Promise<unknown>;
67
+ data: unknown;
68
+ }
69
+ interface QueryKeys {
70
+ all: string[];
71
+ lists: () => QueryKey;
72
+ list: (params?: unknown) => QueryKey;
73
+ details: () => QueryKey;
74
+ detail: (id: string) => QueryKey;
75
+ custom: (key: string, ...args: unknown[]) => QueryKey;
76
+ scopedList: (scope: string, params?: unknown) => QueryKey;
77
+ }
78
+ interface CacheUtils<T> {
79
+ invalidateAll: (client: QueryClient) => Promise<void>;
80
+ invalidateLists: (client: QueryClient) => Promise<void>;
81
+ invalidateDetail: (client: QueryClient, id: string) => Promise<void>;
82
+ setDetail: (client: QueryClient, id: string, data: T) => void;
83
+ getDetail: (client: QueryClient, id: string) => T | undefined;
84
+ removeDetail: (client: QueryClient, id: string) => void;
85
+ }
86
+ declare const DEFAULT_QUERY_CONFIG: {
87
+ readonly staleTime: number;
88
+ readonly gcTime: number;
89
+ readonly refetchOnWindowFocus: false;
90
+ readonly retry: 1;
91
+ };
92
+ declare function getItemId(item: unknown): string | null;
93
+ declare function updateListCache<T>(listData: unknown, updater: (items: T[]) => T[]): unknown;
94
+ declare function createQueryKeys(entityKey: string): QueryKeys;
95
+ declare function createCacheUtils<T>(KEYS: QueryKeys): CacheUtils<T>;
96
+ interface CreateListQueryConfig {
97
+ queryKey: QueryKey;
98
+ queryFn: (context: {
99
+ signal: AbortSignal;
100
+ }) => Promise<unknown>;
101
+ enabled?: boolean;
102
+ options?: Record<string, unknown>;
103
+ prefillDetailCache?: boolean;
104
+ detailKeyBuilder?: (id: string) => QueryKey;
105
+ }
106
+ declare function createListQuery<T>({
107
+ queryKey,
108
+ queryFn,
109
+ enabled,
110
+ options,
111
+ prefillDetailCache,
112
+ detailKeyBuilder
113
+ }: CreateListQueryConfig): ListQueryResult<T>;
114
+ interface CreateDetailQueryConfig {
115
+ queryKey: QueryKey;
116
+ queryFn: (context: {
117
+ signal: AbortSignal;
118
+ }) => Promise<unknown>;
119
+ enabled?: boolean;
120
+ options?: Record<string, unknown>;
121
+ }
122
+ declare function createDetailQuery<T>({
123
+ queryKey,
124
+ queryFn,
125
+ enabled,
126
+ options
127
+ }: CreateDetailQueryConfig): DetailQueryResult<T>;
128
+ interface InfiniteListQueryOptions {
129
+ public?: boolean;
130
+ enabled?: boolean;
131
+ staleTime?: number;
132
+ gcTime?: number;
133
+ refetchOnWindowFocus?: boolean;
134
+ structuralSharing?: boolean;
135
+ _scope?: string;
136
+ request?: RequestPassthrough;
137
+ }
138
+ interface InfiniteListQueryResult<T> {
139
+ items: T[];
140
+ hasNextPage: boolean;
141
+ hasPreviousPage: boolean;
142
+ isFetchingNextPage: boolean;
143
+ isFetchingPreviousPage: boolean;
144
+ fetchNextPage: () => void;
145
+ fetchPreviousPage: () => void;
146
+ isLoading: boolean;
147
+ isFetching: boolean;
148
+ isError: boolean;
149
+ isSuccess: boolean;
150
+ error: Error | null;
151
+ refetch: () => Promise<unknown>;
152
+ data: InfiniteData<unknown> | undefined;
153
+ }
154
+ interface CreateInfiniteListQueryConfig {
155
+ queryKey: QueryKey;
156
+ queryFn: (context: {
157
+ signal: AbortSignal;
158
+ pageParam: unknown;
159
+ }) => Promise<unknown>;
160
+ enabled?: boolean;
161
+ options?: Record<string, unknown>;
162
+ initialPageParam?: unknown;
163
+ getNextPageParam: (lastPage: unknown) => unknown;
164
+ getPreviousPageParam?: (firstPage: unknown) => unknown;
165
+ }
166
+ declare function createInfiniteListQuery<T>({
167
+ queryKey,
168
+ queryFn,
169
+ enabled,
170
+ options,
171
+ initialPageParam,
172
+ getNextPageParam,
173
+ getPreviousPageParam
174
+ }: CreateInfiniteListQueryConfig): InfiniteListQueryResult<T>;
175
+ //#endregion
176
+ export { CacheUtils, CreateDetailQueryConfig, CreateInfiniteListQueryConfig, CreateListQueryConfig, DEFAULT_QUERY_CONFIG, DetailQueryOptions, DetailQueryResult, InfiniteListQueryOptions, InfiniteListQueryResult, ListQueryOptions, ListQueryResult, PaginationData, QueryKeys, RequestPassthrough, createCacheUtils, createDetailQuery, createInfiniteListQuery, createListQuery, createQueryKeys, getItemId, updateListCache };
177
+ //# sourceMappingURL=query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"query.d.ts","names":[],"sources":["../src/query.ts"],"mappings":"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"}