@void-snippets/react 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,82 @@
1
+ import * as _tanstack_react_query from '@tanstack/react-query';
2
+ import { ResourceService } from '@void-snippets/client';
3
+ import { ResourceAdapters, TQueryParams, TPagination, TDefaultPaginatedResponse, TDefaultSingleResponse, ResourceListResult } from '@void-snippets/core';
4
+
5
+ type Capitalize<S extends string> = S extends `${infer F}${infer Rest}` ? `${Uppercase<F>}${Rest}` : S;
6
+ type UseListReturn<K extends string, TBase> = {
7
+ [P in K]: TBase[];
8
+ } & {
9
+ pagination: TPagination;
10
+ } & {
11
+ [P in `is${Capitalize<K>}Loading`]: boolean;
12
+ } & {
13
+ [P in `${K}Error`]: Error | null;
14
+ } & {
15
+ [P in `invalidate${Capitalize<K>}`]: () => void;
16
+ };
17
+ interface CreateResourceHooksOptions<TListRaw, TBase, TSingleRaw, TDetail> {
18
+ /**
19
+ * Adapters let you map your API's raw response shapes to the library's
20
+ * internal format. If your API matches the default shape
21
+ * ({ data: { items, page, limit, totalPages, totalDocuments } })
22
+ * you can omit this entirely.
23
+ *
24
+ * @example
25
+ * createResourceHooks("contacts", ContactsApis, {
26
+ * adapters: {
27
+ * fromList: (raw) => ({
28
+ * items: raw.results,
29
+ * pagination: { page: raw.page, limit: raw.perPage, totalPages: raw.pages, totalDocuments: raw.total },
30
+ * }),
31
+ * fromSingle: (raw) => raw.payload,
32
+ * }
33
+ * })
34
+ */
35
+ adapters?: ResourceAdapters<TListRaw, TBase, TSingleRaw, TDetail>;
36
+ /**
37
+ * Default params for useList and useInfinite.
38
+ * @default { page: 1, limit: 10 }
39
+ */
40
+ defaultParams?: TQueryParams;
41
+ }
42
+ /**
43
+ * Creates a set of TanStack Query hooks for a resource.
44
+ *
45
+ * @param queryKeyPrefix - Used as the TanStack Query cache key prefix AND
46
+ * to name the returned hook properties dynamically.
47
+ * e.g. "contacts" → { contacts, isContactsLoading, ... }
48
+ * @param apiService - An instance of ResourceService (or a subclass).
49
+ * @param options - Optional adapters and default params.
50
+ *
51
+ * @example
52
+ * // contacts.hooks.ts
53
+ * import { createResourceHooks } from '@void-snippets/react';
54
+ * import { ContactsApis } from './contacts.api';
55
+ *
56
+ * export const contactHooks = createResourceHooks('contacts', ContactsApis);
57
+ *
58
+ * // In a component:
59
+ * const { contacts, isContactsLoading } = contactHooks.useList();
60
+ * const { data } = contactHooks.useGet(id);
61
+ * const { create, update, delete: deleteContact } = contactHooks.useMutations();
62
+ */
63
+ declare function createResourceHooks<K extends string, TId, TBase, TDetail = TBase, TCreate = Partial<TBase>, TUpdate = Partial<TBase>, TListRaw = TDefaultPaginatedResponse<TBase>, TSingleRaw = TDefaultSingleResponse<TDetail>>(queryKeyPrefix: K, apiService: ResourceService<TId, TBase, TDetail, TCreate, TUpdate, TListRaw, TSingleRaw>, options?: CreateResourceHooksOptions<TListRaw, TBase, TSingleRaw, TDetail>): {
64
+ useList: (params?: TQueryParams) => UseListReturn<K, TBase>;
65
+ useGet: (id: TId, staleTime?: number) => {
66
+ data: _tanstack_react_query.NoInfer<TDetail> | undefined;
67
+ isLoading: boolean;
68
+ error: Error | null;
69
+ refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<_tanstack_react_query.NoInfer<TDetail>, Error>>;
70
+ };
71
+ useMutations: () => {
72
+ create: _tanstack_react_query.UseMutationResult<TDetail, Error, TCreate, unknown>;
73
+ update: _tanstack_react_query.UseMutationResult<TDetail, Error, {
74
+ _id: TId;
75
+ payload: TUpdate;
76
+ }, unknown>;
77
+ delete: _tanstack_react_query.UseMutationResult<TDetail, Error, TId, unknown>;
78
+ };
79
+ useInfinite: (params?: TQueryParams) => _tanstack_react_query.UseInfiniteQueryResult<_tanstack_react_query.InfiniteData<ResourceListResult<TBase>, unknown>, Error>;
80
+ };
81
+
82
+ export { type CreateResourceHooksOptions, type UseListReturn, createResourceHooks };
@@ -0,0 +1,82 @@
1
+ import * as _tanstack_react_query from '@tanstack/react-query';
2
+ import { ResourceService } from '@void-snippets/client';
3
+ import { ResourceAdapters, TQueryParams, TPagination, TDefaultPaginatedResponse, TDefaultSingleResponse, ResourceListResult } from '@void-snippets/core';
4
+
5
+ type Capitalize<S extends string> = S extends `${infer F}${infer Rest}` ? `${Uppercase<F>}${Rest}` : S;
6
+ type UseListReturn<K extends string, TBase> = {
7
+ [P in K]: TBase[];
8
+ } & {
9
+ pagination: TPagination;
10
+ } & {
11
+ [P in `is${Capitalize<K>}Loading`]: boolean;
12
+ } & {
13
+ [P in `${K}Error`]: Error | null;
14
+ } & {
15
+ [P in `invalidate${Capitalize<K>}`]: () => void;
16
+ };
17
+ interface CreateResourceHooksOptions<TListRaw, TBase, TSingleRaw, TDetail> {
18
+ /**
19
+ * Adapters let you map your API's raw response shapes to the library's
20
+ * internal format. If your API matches the default shape
21
+ * ({ data: { items, page, limit, totalPages, totalDocuments } })
22
+ * you can omit this entirely.
23
+ *
24
+ * @example
25
+ * createResourceHooks("contacts", ContactsApis, {
26
+ * adapters: {
27
+ * fromList: (raw) => ({
28
+ * items: raw.results,
29
+ * pagination: { page: raw.page, limit: raw.perPage, totalPages: raw.pages, totalDocuments: raw.total },
30
+ * }),
31
+ * fromSingle: (raw) => raw.payload,
32
+ * }
33
+ * })
34
+ */
35
+ adapters?: ResourceAdapters<TListRaw, TBase, TSingleRaw, TDetail>;
36
+ /**
37
+ * Default params for useList and useInfinite.
38
+ * @default { page: 1, limit: 10 }
39
+ */
40
+ defaultParams?: TQueryParams;
41
+ }
42
+ /**
43
+ * Creates a set of TanStack Query hooks for a resource.
44
+ *
45
+ * @param queryKeyPrefix - Used as the TanStack Query cache key prefix AND
46
+ * to name the returned hook properties dynamically.
47
+ * e.g. "contacts" → { contacts, isContactsLoading, ... }
48
+ * @param apiService - An instance of ResourceService (or a subclass).
49
+ * @param options - Optional adapters and default params.
50
+ *
51
+ * @example
52
+ * // contacts.hooks.ts
53
+ * import { createResourceHooks } from '@void-snippets/react';
54
+ * import { ContactsApis } from './contacts.api';
55
+ *
56
+ * export const contactHooks = createResourceHooks('contacts', ContactsApis);
57
+ *
58
+ * // In a component:
59
+ * const { contacts, isContactsLoading } = contactHooks.useList();
60
+ * const { data } = contactHooks.useGet(id);
61
+ * const { create, update, delete: deleteContact } = contactHooks.useMutations();
62
+ */
63
+ declare function createResourceHooks<K extends string, TId, TBase, TDetail = TBase, TCreate = Partial<TBase>, TUpdate = Partial<TBase>, TListRaw = TDefaultPaginatedResponse<TBase>, TSingleRaw = TDefaultSingleResponse<TDetail>>(queryKeyPrefix: K, apiService: ResourceService<TId, TBase, TDetail, TCreate, TUpdate, TListRaw, TSingleRaw>, options?: CreateResourceHooksOptions<TListRaw, TBase, TSingleRaw, TDetail>): {
64
+ useList: (params?: TQueryParams) => UseListReturn<K, TBase>;
65
+ useGet: (id: TId, staleTime?: number) => {
66
+ data: _tanstack_react_query.NoInfer<TDetail> | undefined;
67
+ isLoading: boolean;
68
+ error: Error | null;
69
+ refetch: (options?: _tanstack_react_query.RefetchOptions) => Promise<_tanstack_react_query.QueryObserverResult<_tanstack_react_query.NoInfer<TDetail>, Error>>;
70
+ };
71
+ useMutations: () => {
72
+ create: _tanstack_react_query.UseMutationResult<TDetail, Error, TCreate, unknown>;
73
+ update: _tanstack_react_query.UseMutationResult<TDetail, Error, {
74
+ _id: TId;
75
+ payload: TUpdate;
76
+ }, unknown>;
77
+ delete: _tanstack_react_query.UseMutationResult<TDetail, Error, TId, unknown>;
78
+ };
79
+ useInfinite: (params?: TQueryParams) => _tanstack_react_query.UseInfiniteQueryResult<_tanstack_react_query.InfiniteData<ResourceListResult<TBase>, unknown>, Error>;
80
+ };
81
+
82
+ export { type CreateResourceHooksOptions, type UseListReturn, createResourceHooks };
package/dist/index.js ADDED
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ createResourceHooks: () => createResourceHooks
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+
27
+ // src/hooks/createResourceHooks.ts
28
+ var import_react_query = require("@tanstack/react-query");
29
+ var import_core = require("@void-snippets/core");
30
+ var DEFAULT_PAGINATION = {
31
+ page: 1,
32
+ limit: 10
33
+ };
34
+ function createResourceHooks(queryKeyPrefix, apiService, options = {}) {
35
+ const {
36
+ adapters = (0, import_core.createDefaultAdapters)(),
37
+ defaultParams = DEFAULT_PAGINATION
38
+ } = options;
39
+ const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
40
+ const capPrefix = capitalize(queryKeyPrefix);
41
+ return {
42
+ // -------------------------------------------------------------------------
43
+ // useList — paginated list with invalidation helper
44
+ // -------------------------------------------------------------------------
45
+ useList: (params = defaultParams) => {
46
+ var _a, _b, _c, _d, _e;
47
+ const queryClient = (0, import_react_query.useQueryClient)();
48
+ const queryKey = [queryKeyPrefix, params];
49
+ const query = (0, import_react_query.useQuery)({
50
+ queryKey,
51
+ queryFn: async () => {
52
+ const raw = await apiService.list(params);
53
+ return adapters.fromList(raw);
54
+ }
55
+ });
56
+ const items = (_b = (_a = query.data) == null ? void 0 : _a.items) != null ? _b : [];
57
+ const pagination = (_e = (_c = query.data) == null ? void 0 : _c.pagination) != null ? _e : {
58
+ page: 1,
59
+ limit: (_d = defaultParams.limit) != null ? _d : 10,
60
+ totalPages: 0,
61
+ totalDocuments: 0
62
+ };
63
+ return {
64
+ [queryKeyPrefix]: items,
65
+ pagination,
66
+ [`is${capPrefix}Loading`]: query.isLoading || query.isFetching,
67
+ [`${queryKeyPrefix}Error`]: query.error,
68
+ [`invalidate${capPrefix}`]: () => queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] })
69
+ };
70
+ },
71
+ // -------------------------------------------------------------------------
72
+ // useGet — single item by id
73
+ // -------------------------------------------------------------------------
74
+ useGet: (id, staleTime = 3e4) => {
75
+ const query = (0, import_react_query.useQuery)({
76
+ queryKey: [queryKeyPrefix, id],
77
+ queryFn: async () => {
78
+ const raw = await apiService.get(id);
79
+ return adapters.fromSingle(raw);
80
+ },
81
+ enabled: id !== void 0 && id !== null && id !== "",
82
+ staleTime
83
+ });
84
+ return {
85
+ data: query.data,
86
+ isLoading: query.isLoading || query.isFetching,
87
+ error: query.error,
88
+ refetch: query.refetch
89
+ };
90
+ },
91
+ // -------------------------------------------------------------------------
92
+ // useMutations — create / update / delete with auto-invalidation
93
+ // -------------------------------------------------------------------------
94
+ useMutations: () => {
95
+ const queryClient = (0, import_react_query.useQueryClient)();
96
+ const invalidate = () => queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] });
97
+ const createMutation = (0, import_react_query.useMutation)({
98
+ mutationFn: async (payload) => {
99
+ const raw = await apiService.create(payload);
100
+ return adapters.fromSingle(raw);
101
+ },
102
+ onSuccess: invalidate
103
+ });
104
+ const updateMutation = (0, import_react_query.useMutation)({
105
+ mutationFn: async ({ _id, payload }) => {
106
+ const raw = await apiService.update(_id, payload);
107
+ return adapters.fromSingle(raw);
108
+ },
109
+ onSuccess: invalidate
110
+ });
111
+ const deleteMutation = (0, import_react_query.useMutation)({
112
+ mutationFn: async (_id) => {
113
+ const raw = await apiService.delete(_id);
114
+ return adapters.fromSingle(raw);
115
+ },
116
+ onSuccess: invalidate
117
+ });
118
+ return {
119
+ create: createMutation,
120
+ update: updateMutation,
121
+ delete: deleteMutation
122
+ };
123
+ },
124
+ // -------------------------------------------------------------------------
125
+ // useInfinite — infinite scroll / load more
126
+ // -------------------------------------------------------------------------
127
+ useInfinite: (params = defaultParams) => {
128
+ return (0, import_react_query.useInfiniteQuery)({
129
+ queryKey: [queryKeyPrefix, "INFINITE", params],
130
+ queryFn: async ({ pageParam }) => {
131
+ var _a;
132
+ const raw = await apiService.list({
133
+ ...params,
134
+ page: pageParam,
135
+ limit: (_a = params.limit) != null ? _a : 20
136
+ });
137
+ return adapters.fromList(raw);
138
+ },
139
+ getNextPageParam: (lastPage) => {
140
+ const { page, totalPages } = lastPage.pagination;
141
+ return page < totalPages ? page + 1 : void 0;
142
+ },
143
+ initialPageParam: 1
144
+ });
145
+ }
146
+ };
147
+ }
148
+ // Annotate the CommonJS export names for ESM import in node:
149
+ 0 && (module.exports = {
150
+ createResourceHooks
151
+ });
152
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/hooks/createResourceHooks.ts"],"sourcesContent":["export { createResourceHooks } from \"./hooks/createResourceHooks\";\nexport type {\n UseListReturn,\n CreateResourceHooksOptions,\n} from \"./hooks/createResourceHooks\";\n","import {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n} from \"@tanstack/react-query\";\nimport type { ResourceService } from \"@void-snippets/client\";\nimport type {\n ResourceAdapters,\n ResourceListResult,\n TPagination,\n TQueryParams,\n TDefaultPaginatedResponse,\n TDefaultSingleResponse,\n} from \"@void-snippets/core\";\nimport { createDefaultAdapters } from \"@void-snippets/core\";\n\n// ============================================================================\n// TYPE HELPERS\n// ============================================================================\n\ntype Capitalize<S extends string> = S extends `${infer F}${infer Rest}`\n ? `${Uppercase<F>}${Rest}`\n : S;\n\nconst DEFAULT_PAGINATION: Required<TQueryParams> = {\n page: 1,\n limit: 10,\n};\n\n// ============================================================================\n// RETURN TYPE — useList\n// Dynamically named keys based on the queryKeyPrefix (e.g. \"contacts\"):\n// { contacts: TBase[], isContactsLoading: boolean, contactsError: Error | null, invalidateContacts: () => void }\n// ============================================================================\n\nexport type UseListReturn<K extends string, TBase> = {\n [P in K]: TBase[];\n} & {\n pagination: TPagination;\n} & {\n [P in `is${Capitalize<K>}Loading`]: boolean;\n} & {\n [P in `${K}Error`]: Error | null;\n} & {\n [P in `invalidate${Capitalize<K>}`]: () => void;\n};\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport interface CreateResourceHooksOptions<\n TListRaw,\n TBase,\n TSingleRaw,\n TDetail\n> {\n /**\n * Adapters let you map your API's raw response shapes to the library's\n * internal format. If your API matches the default shape\n * ({ data: { items, page, limit, totalPages, totalDocuments } })\n * you can omit this entirely.\n *\n * @example\n * createResourceHooks(\"contacts\", ContactsApis, {\n * adapters: {\n * fromList: (raw) => ({\n * items: raw.results,\n * pagination: { page: raw.page, limit: raw.perPage, totalPages: raw.pages, totalDocuments: raw.total },\n * }),\n * fromSingle: (raw) => raw.payload,\n * }\n * })\n */\n adapters?: ResourceAdapters<TListRaw, TBase, TSingleRaw, TDetail>;\n\n /**\n * Default params for useList and useInfinite.\n * @default { page: 1, limit: 10 }\n */\n defaultParams?: TQueryParams;\n}\n\n// ============================================================================\n// FACTORY\n// ============================================================================\n\n/**\n * Creates a set of TanStack Query hooks for a resource.\n *\n * @param queryKeyPrefix - Used as the TanStack Query cache key prefix AND\n * to name the returned hook properties dynamically.\n * e.g. \"contacts\" → { contacts, isContactsLoading, ... }\n * @param apiService - An instance of ResourceService (or a subclass).\n * @param options - Optional adapters and default params.\n *\n * @example\n * // contacts.hooks.ts\n * import { createResourceHooks } from '@void-snippets/react';\n * import { ContactsApis } from './contacts.api';\n *\n * export const contactHooks = createResourceHooks('contacts', ContactsApis);\n *\n * // In a component:\n * const { contacts, isContactsLoading } = contactHooks.useList();\n * const { data } = contactHooks.useGet(id);\n * const { create, update, delete: deleteContact } = contactHooks.useMutations();\n */\nexport function createResourceHooks<\n K extends string,\n TId,\n TBase,\n TDetail = TBase,\n TCreate = Partial<TBase>,\n TUpdate = Partial<TBase>,\n TListRaw = TDefaultPaginatedResponse<TBase>,\n TSingleRaw = TDefaultSingleResponse<TDetail>\n>(\n queryKeyPrefix: K,\n apiService: ResourceService<TId, TBase, TDetail, TCreate, TUpdate, TListRaw, TSingleRaw>,\n options: CreateResourceHooksOptions<TListRaw, TBase, TSingleRaw, TDetail> = {}\n) {\n const {\n adapters = createDefaultAdapters<TBase, TDetail>() as unknown as ResourceAdapters<TListRaw, TBase, TSingleRaw, TDetail>,\n defaultParams = DEFAULT_PAGINATION,\n } = options;\n\n const capitalize = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n const capPrefix = capitalize(queryKeyPrefix);\n\n return {\n\n // -------------------------------------------------------------------------\n // useList — paginated list with invalidation helper\n // -------------------------------------------------------------------------\n useList: (\n params: TQueryParams = defaultParams\n ): UseListReturn<K, TBase> => {\n const queryClient = useQueryClient();\n const queryKey = [queryKeyPrefix, params];\n\n const query = useQuery<ResourceListResult<TBase>, Error>({\n queryKey,\n queryFn: async () => {\n const raw = await apiService.list(params);\n return adapters.fromList(raw as TListRaw);\n },\n });\n\n const items = query.data?.items ?? [];\n const pagination: TPagination = query.data?.pagination ?? {\n page: 1,\n limit: defaultParams.limit ?? 10,\n totalPages: 0,\n totalDocuments: 0,\n };\n\n return {\n [queryKeyPrefix]: items,\n pagination,\n [`is${capPrefix}Loading`]: query.isLoading || query.isFetching,\n [`${queryKeyPrefix}Error`]: query.error,\n [`invalidate${capPrefix}`]: () =>\n queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] }),\n } as UseListReturn<K, TBase>;\n },\n\n // -------------------------------------------------------------------------\n // useGet — single item by id\n // -------------------------------------------------------------------------\n useGet: (id: TId, staleTime = 30_000) => {\n const query = useQuery<TDetail, Error>({\n queryKey: [queryKeyPrefix, id],\n queryFn: async () => {\n const raw = await apiService.get(id);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n enabled: id !== undefined && id !== null && id !== \"\",\n staleTime,\n });\n\n return {\n data: query.data,\n isLoading: query.isLoading || query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n },\n\n // -------------------------------------------------------------------------\n // useMutations — create / update / delete with auto-invalidation\n // -------------------------------------------------------------------------\n useMutations: () => {\n const queryClient = useQueryClient();\n const invalidate = () =>\n queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] });\n\n const createMutation = useMutation<TDetail, Error, TCreate>({\n mutationFn: async (payload) => {\n const raw = await apiService.create(payload);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n onSuccess: invalidate,\n });\n\n const updateMutation = useMutation<\n TDetail,\n Error,\n { _id: TId; payload: TUpdate }\n >({\n mutationFn: async ({ _id, payload }) => {\n const raw = await apiService.update(_id, payload);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n onSuccess: invalidate,\n });\n\n const deleteMutation = useMutation<TDetail, Error, TId>({\n mutationFn: async (_id) => {\n const raw = await apiService.delete(_id);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n onSuccess: invalidate,\n });\n\n return {\n create: createMutation,\n update: updateMutation,\n delete: deleteMutation,\n };\n },\n\n // -------------------------------------------------------------------------\n // useInfinite — infinite scroll / load more\n // -------------------------------------------------------------------------\n useInfinite: (params: TQueryParams = defaultParams) => {\n return useInfiniteQuery<ResourceListResult<TBase>, Error>({\n queryKey: [queryKeyPrefix, \"INFINITE\", params],\n queryFn: async ({ pageParam }) => {\n const raw = await apiService.list({\n ...params,\n page: pageParam as number,\n limit: params.limit ?? 20,\n });\n return adapters.fromList(raw as TListRaw);\n },\n getNextPageParam: (lastPage) => {\n const { page, totalPages } = lastPage.pagination;\n return page < totalPages ? page + 1 : undefined;\n },\n initialPageParam: 1,\n });\n },\n };\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,130 @@
1
+ // src/hooks/createResourceHooks.ts
2
+ import {
3
+ useInfiniteQuery,
4
+ useMutation,
5
+ useQuery,
6
+ useQueryClient
7
+ } from "@tanstack/react-query";
8
+ import { createDefaultAdapters } from "@void-snippets/core";
9
+ var DEFAULT_PAGINATION = {
10
+ page: 1,
11
+ limit: 10
12
+ };
13
+ function createResourceHooks(queryKeyPrefix, apiService, options = {}) {
14
+ const {
15
+ adapters = createDefaultAdapters(),
16
+ defaultParams = DEFAULT_PAGINATION
17
+ } = options;
18
+ const capitalize = (str) => str.charAt(0).toUpperCase() + str.slice(1);
19
+ const capPrefix = capitalize(queryKeyPrefix);
20
+ return {
21
+ // -------------------------------------------------------------------------
22
+ // useList — paginated list with invalidation helper
23
+ // -------------------------------------------------------------------------
24
+ useList: (params = defaultParams) => {
25
+ var _a, _b, _c, _d, _e;
26
+ const queryClient = useQueryClient();
27
+ const queryKey = [queryKeyPrefix, params];
28
+ const query = useQuery({
29
+ queryKey,
30
+ queryFn: async () => {
31
+ const raw = await apiService.list(params);
32
+ return adapters.fromList(raw);
33
+ }
34
+ });
35
+ const items = (_b = (_a = query.data) == null ? void 0 : _a.items) != null ? _b : [];
36
+ const pagination = (_e = (_c = query.data) == null ? void 0 : _c.pagination) != null ? _e : {
37
+ page: 1,
38
+ limit: (_d = defaultParams.limit) != null ? _d : 10,
39
+ totalPages: 0,
40
+ totalDocuments: 0
41
+ };
42
+ return {
43
+ [queryKeyPrefix]: items,
44
+ pagination,
45
+ [`is${capPrefix}Loading`]: query.isLoading || query.isFetching,
46
+ [`${queryKeyPrefix}Error`]: query.error,
47
+ [`invalidate${capPrefix}`]: () => queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] })
48
+ };
49
+ },
50
+ // -------------------------------------------------------------------------
51
+ // useGet — single item by id
52
+ // -------------------------------------------------------------------------
53
+ useGet: (id, staleTime = 3e4) => {
54
+ const query = useQuery({
55
+ queryKey: [queryKeyPrefix, id],
56
+ queryFn: async () => {
57
+ const raw = await apiService.get(id);
58
+ return adapters.fromSingle(raw);
59
+ },
60
+ enabled: id !== void 0 && id !== null && id !== "",
61
+ staleTime
62
+ });
63
+ return {
64
+ data: query.data,
65
+ isLoading: query.isLoading || query.isFetching,
66
+ error: query.error,
67
+ refetch: query.refetch
68
+ };
69
+ },
70
+ // -------------------------------------------------------------------------
71
+ // useMutations — create / update / delete with auto-invalidation
72
+ // -------------------------------------------------------------------------
73
+ useMutations: () => {
74
+ const queryClient = useQueryClient();
75
+ const invalidate = () => queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] });
76
+ const createMutation = useMutation({
77
+ mutationFn: async (payload) => {
78
+ const raw = await apiService.create(payload);
79
+ return adapters.fromSingle(raw);
80
+ },
81
+ onSuccess: invalidate
82
+ });
83
+ const updateMutation = useMutation({
84
+ mutationFn: async ({ _id, payload }) => {
85
+ const raw = await apiService.update(_id, payload);
86
+ return adapters.fromSingle(raw);
87
+ },
88
+ onSuccess: invalidate
89
+ });
90
+ const deleteMutation = useMutation({
91
+ mutationFn: async (_id) => {
92
+ const raw = await apiService.delete(_id);
93
+ return adapters.fromSingle(raw);
94
+ },
95
+ onSuccess: invalidate
96
+ });
97
+ return {
98
+ create: createMutation,
99
+ update: updateMutation,
100
+ delete: deleteMutation
101
+ };
102
+ },
103
+ // -------------------------------------------------------------------------
104
+ // useInfinite — infinite scroll / load more
105
+ // -------------------------------------------------------------------------
106
+ useInfinite: (params = defaultParams) => {
107
+ return useInfiniteQuery({
108
+ queryKey: [queryKeyPrefix, "INFINITE", params],
109
+ queryFn: async ({ pageParam }) => {
110
+ var _a;
111
+ const raw = await apiService.list({
112
+ ...params,
113
+ page: pageParam,
114
+ limit: (_a = params.limit) != null ? _a : 20
115
+ });
116
+ return adapters.fromList(raw);
117
+ },
118
+ getNextPageParam: (lastPage) => {
119
+ const { page, totalPages } = lastPage.pagination;
120
+ return page < totalPages ? page + 1 : void 0;
121
+ },
122
+ initialPageParam: 1
123
+ });
124
+ }
125
+ };
126
+ }
127
+ export {
128
+ createResourceHooks
129
+ };
130
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/createResourceHooks.ts"],"sourcesContent":["import {\n useInfiniteQuery,\n useMutation,\n useQuery,\n useQueryClient,\n} from \"@tanstack/react-query\";\nimport type { ResourceService } from \"@void-snippets/client\";\nimport type {\n ResourceAdapters,\n ResourceListResult,\n TPagination,\n TQueryParams,\n TDefaultPaginatedResponse,\n TDefaultSingleResponse,\n} from \"@void-snippets/core\";\nimport { createDefaultAdapters } from \"@void-snippets/core\";\n\n// ============================================================================\n// TYPE HELPERS\n// ============================================================================\n\ntype Capitalize<S extends string> = S extends `${infer F}${infer Rest}`\n ? `${Uppercase<F>}${Rest}`\n : S;\n\nconst DEFAULT_PAGINATION: Required<TQueryParams> = {\n page: 1,\n limit: 10,\n};\n\n// ============================================================================\n// RETURN TYPE — useList\n// Dynamically named keys based on the queryKeyPrefix (e.g. \"contacts\"):\n// { contacts: TBase[], isContactsLoading: boolean, contactsError: Error | null, invalidateContacts: () => void }\n// ============================================================================\n\nexport type UseListReturn<K extends string, TBase> = {\n [P in K]: TBase[];\n} & {\n pagination: TPagination;\n} & {\n [P in `is${Capitalize<K>}Loading`]: boolean;\n} & {\n [P in `${K}Error`]: Error | null;\n} & {\n [P in `invalidate${Capitalize<K>}`]: () => void;\n};\n\n// ============================================================================\n// OPTIONS\n// ============================================================================\n\nexport interface CreateResourceHooksOptions<\n TListRaw,\n TBase,\n TSingleRaw,\n TDetail\n> {\n /**\n * Adapters let you map your API's raw response shapes to the library's\n * internal format. If your API matches the default shape\n * ({ data: { items, page, limit, totalPages, totalDocuments } })\n * you can omit this entirely.\n *\n * @example\n * createResourceHooks(\"contacts\", ContactsApis, {\n * adapters: {\n * fromList: (raw) => ({\n * items: raw.results,\n * pagination: { page: raw.page, limit: raw.perPage, totalPages: raw.pages, totalDocuments: raw.total },\n * }),\n * fromSingle: (raw) => raw.payload,\n * }\n * })\n */\n adapters?: ResourceAdapters<TListRaw, TBase, TSingleRaw, TDetail>;\n\n /**\n * Default params for useList and useInfinite.\n * @default { page: 1, limit: 10 }\n */\n defaultParams?: TQueryParams;\n}\n\n// ============================================================================\n// FACTORY\n// ============================================================================\n\n/**\n * Creates a set of TanStack Query hooks for a resource.\n *\n * @param queryKeyPrefix - Used as the TanStack Query cache key prefix AND\n * to name the returned hook properties dynamically.\n * e.g. \"contacts\" → { contacts, isContactsLoading, ... }\n * @param apiService - An instance of ResourceService (or a subclass).\n * @param options - Optional adapters and default params.\n *\n * @example\n * // contacts.hooks.ts\n * import { createResourceHooks } from '@void-snippets/react';\n * import { ContactsApis } from './contacts.api';\n *\n * export const contactHooks = createResourceHooks('contacts', ContactsApis);\n *\n * // In a component:\n * const { contacts, isContactsLoading } = contactHooks.useList();\n * const { data } = contactHooks.useGet(id);\n * const { create, update, delete: deleteContact } = contactHooks.useMutations();\n */\nexport function createResourceHooks<\n K extends string,\n TId,\n TBase,\n TDetail = TBase,\n TCreate = Partial<TBase>,\n TUpdate = Partial<TBase>,\n TListRaw = TDefaultPaginatedResponse<TBase>,\n TSingleRaw = TDefaultSingleResponse<TDetail>\n>(\n queryKeyPrefix: K,\n apiService: ResourceService<TId, TBase, TDetail, TCreate, TUpdate, TListRaw, TSingleRaw>,\n options: CreateResourceHooksOptions<TListRaw, TBase, TSingleRaw, TDetail> = {}\n) {\n const {\n adapters = createDefaultAdapters<TBase, TDetail>() as unknown as ResourceAdapters<TListRaw, TBase, TSingleRaw, TDetail>,\n defaultParams = DEFAULT_PAGINATION,\n } = options;\n\n const capitalize = (str: string) =>\n str.charAt(0).toUpperCase() + str.slice(1);\n const capPrefix = capitalize(queryKeyPrefix);\n\n return {\n\n // -------------------------------------------------------------------------\n // useList — paginated list with invalidation helper\n // -------------------------------------------------------------------------\n useList: (\n params: TQueryParams = defaultParams\n ): UseListReturn<K, TBase> => {\n const queryClient = useQueryClient();\n const queryKey = [queryKeyPrefix, params];\n\n const query = useQuery<ResourceListResult<TBase>, Error>({\n queryKey,\n queryFn: async () => {\n const raw = await apiService.list(params);\n return adapters.fromList(raw as TListRaw);\n },\n });\n\n const items = query.data?.items ?? [];\n const pagination: TPagination = query.data?.pagination ?? {\n page: 1,\n limit: defaultParams.limit ?? 10,\n totalPages: 0,\n totalDocuments: 0,\n };\n\n return {\n [queryKeyPrefix]: items,\n pagination,\n [`is${capPrefix}Loading`]: query.isLoading || query.isFetching,\n [`${queryKeyPrefix}Error`]: query.error,\n [`invalidate${capPrefix}`]: () =>\n queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] }),\n } as UseListReturn<K, TBase>;\n },\n\n // -------------------------------------------------------------------------\n // useGet — single item by id\n // -------------------------------------------------------------------------\n useGet: (id: TId, staleTime = 30_000) => {\n const query = useQuery<TDetail, Error>({\n queryKey: [queryKeyPrefix, id],\n queryFn: async () => {\n const raw = await apiService.get(id);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n enabled: id !== undefined && id !== null && id !== \"\",\n staleTime,\n });\n\n return {\n data: query.data,\n isLoading: query.isLoading || query.isFetching,\n error: query.error,\n refetch: query.refetch,\n };\n },\n\n // -------------------------------------------------------------------------\n // useMutations — create / update / delete with auto-invalidation\n // -------------------------------------------------------------------------\n useMutations: () => {\n const queryClient = useQueryClient();\n const invalidate = () =>\n queryClient.invalidateQueries({ queryKey: [queryKeyPrefix] });\n\n const createMutation = useMutation<TDetail, Error, TCreate>({\n mutationFn: async (payload) => {\n const raw = await apiService.create(payload);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n onSuccess: invalidate,\n });\n\n const updateMutation = useMutation<\n TDetail,\n Error,\n { _id: TId; payload: TUpdate }\n >({\n mutationFn: async ({ _id, payload }) => {\n const raw = await apiService.update(_id, payload);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n onSuccess: invalidate,\n });\n\n const deleteMutation = useMutation<TDetail, Error, TId>({\n mutationFn: async (_id) => {\n const raw = await apiService.delete(_id);\n return adapters.fromSingle(raw as TSingleRaw);\n },\n onSuccess: invalidate,\n });\n\n return {\n create: createMutation,\n update: updateMutation,\n delete: deleteMutation,\n };\n },\n\n // -------------------------------------------------------------------------\n // useInfinite — infinite scroll / load more\n // -------------------------------------------------------------------------\n useInfinite: (params: TQueryParams = defaultParams) => {\n return useInfiniteQuery<ResourceListResult<TBase>, Error>({\n queryKey: [queryKeyPrefix, \"INFINITE\", params],\n queryFn: async ({ pageParam }) => {\n const raw = await apiService.list({\n ...params,\n page: pageParam as number,\n limit: params.limit ?? 20,\n });\n return adapters.fromList(raw as TListRaw);\n },\n getNextPageParam: (lastPage) => {\n const { page, totalPages } = lastPage.pagination;\n return page < totalPages ? page + 1 : undefined;\n },\n initialPageParam: 1,\n });\n },\n };\n}\n"],"mappings":"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","names":[]}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@void-snippets/react",
3
+ "version": "0.1.0",
4
+ "description": "TanStack Query resource hooks factory for React",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "import": "./dist/index.js",
11
+ "require": "./dist/index.cjs"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist"
16
+ ],
17
+ "keywords": [
18
+ "react",
19
+ "tanstack-query",
20
+ "react-query",
21
+ "hooks",
22
+ "api",
23
+ "void-snippets"
24
+ ],
25
+ "license": "MIT",
26
+ "peerDependencies": {
27
+ "react": ">=17.0.0"
28
+ },
29
+ "dependencies": {
30
+ "@tanstack/react-query": "^5.0.0",
31
+ "@void-snippets/client": "0.1.0",
32
+ "@void-snippets/core": "0.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/react": "^18.0.0",
36
+ "react": "^18.0.0",
37
+ "tsup": "^8.0.0",
38
+ "typescript": "^5.4.0"
39
+ },
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "dev": "tsup --watch"
43
+ }
44
+ }