@react-pakistan/util-functions 1.25.2 → 1.25.4

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.
@@ -24,13 +24,18 @@ export declare const getCachedCurrenciesSync: () => {
24
24
  * - If currencies exist but are older than 1 week, fetch fresh data and update cache
25
25
  * - If currencies don't exist in cache, fetch from API and cache them
26
26
  *
27
+ * @param searchQuery - Optional search query to filter currencies
28
+ * @param pageLimit - Number of currencies to fetch (default: 100)
27
29
  * @returns Promise<{count:number, items: CurrencyBE[]}> - Paged currencies
28
30
  *
29
31
  * @example
30
32
  * const currencies = await getCachedCurrencies();
31
33
  * console.log(currencies.items[0].label);
34
+ *
35
+ * // With search
36
+ * const filtered = await getCachedCurrencies('USD');
32
37
  */
33
- export declare const getCachedCurrencies: () => Promise<{
38
+ export declare const getCachedCurrencies: (searchQuery?: string, pageLimit?: number) => Promise<{
34
39
  count: number;
35
40
  items: CurrencyBE[];
36
41
  }>;
@@ -35,6 +35,15 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
35
35
  if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
36
  }
37
37
  };
38
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
39
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
40
+ if (ar || !(i in from)) {
41
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
42
+ ar[i] = from[i];
43
+ }
44
+ }
45
+ return to.concat(ar || Array.prototype.slice.call(from));
46
+ };
38
47
  Object.defineProperty(exports, "__esModule", { value: true });
39
48
  exports.isCurrenciesCacheStale = exports.preloadCurrencies = exports.invalidateCurrenciesCache = exports.getCachedCurrencyByCode = exports.getCachedCurrencyById = exports.getCachedCurrencies = exports.getCachedCurrenciesSync = void 0;
40
49
  var constants_1 = require("../constants");
@@ -88,56 +97,86 @@ exports.getCachedCurrenciesSync = getCachedCurrenciesSync;
88
97
  * - If currencies exist but are older than 1 week, fetch fresh data and update cache
89
98
  * - If currencies don't exist in cache, fetch from API and cache them
90
99
  *
100
+ * @param searchQuery - Optional search query to filter currencies
101
+ * @param pageLimit - Number of currencies to fetch (default: 100)
91
102
  * @returns Promise<{count:number, items: CurrencyBE[]}> - Paged currencies
92
103
  *
93
104
  * @example
94
105
  * const currencies = await getCachedCurrencies();
95
106
  * console.log(currencies.items[0].label);
107
+ *
108
+ * // With search
109
+ * const filtered = await getCachedCurrencies('USD');
96
110
  */
97
- var getCachedCurrencies = function () { return __awaiter(void 0, void 0, void 0, function () {
98
- var cachedData, currentTime, cachedTime, ageInMs, response, updatedCache, error_1;
99
- var _a;
100
- return __generator(this, function (_b) {
101
- switch (_b.label) {
102
- case 0:
103
- _b.trys.push([0, 2, , 3]);
104
- cachedData = (0, get_storage_value_1.getStorageValue)(type_1.LS_KEYS.CURRENCIES);
105
- currentTime = new Date().getTime();
106
- // Check if cached data exists and is still fresh
107
- if (cachedData) {
108
- cachedTime = new Date(cachedData.cachedAt).getTime();
109
- ageInMs = currentTime - cachedTime;
110
- // If cached data is less than 1 week old, return it
111
- if (ageInMs < constants_1.ONE_WEEK_IN_MS) {
112
- return [2 /*return*/, {
113
- count: cachedData.currencies.length,
114
- items: cachedData.currencies,
115
- }];
111
+ var getCachedCurrencies = function (searchQuery_1) {
112
+ var args_1 = [];
113
+ for (var _i = 1; _i < arguments.length; _i++) {
114
+ args_1[_i - 1] = arguments[_i];
115
+ }
116
+ return __awaiter(void 0, __spreadArray([searchQuery_1], args_1, true), void 0, function (searchQuery, pageLimit) {
117
+ var response_1, cachedData, currentTime, cachedTime, ageInMs, response, updatedCache, error_1;
118
+ var _a;
119
+ if (pageLimit === void 0) { pageLimit = 100; }
120
+ return __generator(this, function (_b) {
121
+ switch (_b.label) {
122
+ case 0:
123
+ _b.trys.push([0, 4, , 5]);
124
+ if (!(searchQuery && searchQuery.trim())) return [3 /*break*/, 2];
125
+ return [4 /*yield*/, (0, fetch_data_1.fetchData)({
126
+ url: constants_1.API_ROUTES.CURRENCIES,
127
+ body: JSON.stringify({
128
+ searchQuery: searchQuery,
129
+ pageLimit: pageLimit,
130
+ currentPage: 1,
131
+ }),
132
+ method: api_methods_1.API_METHODS.POST,
133
+ })];
134
+ case 1:
135
+ response_1 = _b.sent();
136
+ return [2 /*return*/, (response_1 === null || response_1 === void 0 ? void 0 : response_1.data) || { count: 0, items: [] }];
137
+ case 2:
138
+ cachedData = (0, get_storage_value_1.getStorageValue)(type_1.LS_KEYS.CURRENCIES);
139
+ currentTime = new Date().getTime();
140
+ // Check if cached data exists and is still fresh
141
+ if (cachedData) {
142
+ cachedTime = new Date(cachedData.cachedAt).getTime();
143
+ ageInMs = currentTime - cachedTime;
144
+ // If cached data is less than 1 week old, return it
145
+ if (ageInMs < constants_1.ONE_WEEK_IN_MS) {
146
+ return [2 /*return*/, {
147
+ count: cachedData.currencies.length,
148
+ items: cachedData.currencies,
149
+ }];
150
+ }
116
151
  }
117
- }
118
- return [4 /*yield*/, (0, fetch_data_1.fetchData)({
119
- url: constants_1.API_ROUTES.CURRENCIES,
120
- method: api_methods_1.API_METHODS.GET,
121
- })];
122
- case 1:
123
- response = _b.sent();
124
- if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.items) {
125
- updatedCache = {
126
- currencies: response.data.items,
127
- cachedAt: new Date().toISOString(),
128
- };
129
- (0, set_storage_value_1.setStorageValue)(type_1.LS_KEYS.CURRENCIES, updatedCache);
130
- return [2 /*return*/, response.data];
131
- }
132
- return [2 /*return*/, { count: 0, items: [] }];
133
- case 2:
134
- error_1 = _b.sent();
135
- console.error('Error fetching currencies:', error_1);
136
- return [2 /*return*/, { count: 0, items: [] }];
137
- case 3: return [2 /*return*/];
138
- }
152
+ return [4 /*yield*/, (0, fetch_data_1.fetchData)({
153
+ url: constants_1.API_ROUTES.CURRENCIES,
154
+ body: JSON.stringify({
155
+ pageLimit: pageLimit,
156
+ currentPage: 1,
157
+ }),
158
+ method: api_methods_1.API_METHODS.POST,
159
+ })];
160
+ case 3:
161
+ response = _b.sent();
162
+ if ((_a = response === null || response === void 0 ? void 0 : response.data) === null || _a === void 0 ? void 0 : _a.items) {
163
+ updatedCache = {
164
+ currencies: response.data.items,
165
+ cachedAt: new Date().toISOString(),
166
+ };
167
+ (0, set_storage_value_1.setStorageValue)(type_1.LS_KEYS.CURRENCIES, updatedCache);
168
+ return [2 /*return*/, response.data];
169
+ }
170
+ return [2 /*return*/, { count: 0, items: [] }];
171
+ case 4:
172
+ error_1 = _b.sent();
173
+ console.error('Error fetching currencies:', error_1);
174
+ return [2 /*return*/, { count: 0, items: [] }];
175
+ case 5: return [2 /*return*/];
176
+ }
177
+ });
139
178
  });
140
- }); };
179
+ };
141
180
  exports.getCachedCurrencies = getCachedCurrencies;
142
181
  /**
143
182
  * Utility function to get a specific currency by ID from cache
@@ -1,7 +1,11 @@
1
1
  export declare enum API_METHODS {
2
+ CONNECT = "CONNECT",
2
3
  DELETE = "DELETE",
3
4
  GET = "GET",
5
+ HEAD = "HEAD",
6
+ OPTIONS = "OPTIONS",
4
7
  PATCH = "PATCH",
5
8
  POST = "POST",
6
- UPDATE = "UPDATE"
9
+ PUT = "PUT",
10
+ TRACE = "TRACE"
7
11
  }
@@ -3,9 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.API_METHODS = void 0;
4
4
  var API_METHODS;
5
5
  (function (API_METHODS) {
6
+ API_METHODS["CONNECT"] = "CONNECT";
6
7
  API_METHODS["DELETE"] = "DELETE";
7
8
  API_METHODS["GET"] = "GET";
9
+ API_METHODS["HEAD"] = "HEAD";
10
+ API_METHODS["OPTIONS"] = "OPTIONS";
8
11
  API_METHODS["PATCH"] = "PATCH";
9
12
  API_METHODS["POST"] = "POST";
10
- API_METHODS["UPDATE"] = "UPDATE";
13
+ API_METHODS["PUT"] = "PUT";
14
+ API_METHODS["TRACE"] = "TRACE";
11
15
  })(API_METHODS || (exports.API_METHODS = API_METHODS = {}));
@@ -7,6 +7,7 @@ export interface FetchResult {
7
7
  export interface FetchConfig extends RequestInit {
8
8
  autoFetch?: boolean;
9
9
  callback?: (result: FetchResult) => void;
10
+ params?: Record<string, any>;
10
11
  }
11
12
  export interface Return {
12
13
  apiResult: API_RESULT | undefined;
@@ -93,34 +93,67 @@ var useFetch = function (url, config, deps) {
93
93
  };
94
94
  }, []);
95
95
  var fetchNow = (0, react_1.useCallback)(function (overrideUrl, overrideOptions) { return __awaiter(void 0, void 0, void 0, function () {
96
- var finalUrl, finalOptions, controller, response, parsed, _a, err, err_1;
97
- return __generator(this, function (_b) {
98
- switch (_b.label) {
96
+ var finalUrl, _a, defaultParams, restDefaultOptions, _b, overrideParams, restOverrideOptions, mergedParams, finalOptions, method, hashIndex, hash, basePart, searchIndex, pathname, existingSearch, searchParams_1, newSearch, controller, response, parsed, _c, err, err_1;
97
+ return __generator(this, function (_d) {
98
+ switch (_d.label) {
99
99
  case 0:
100
100
  finalUrl = overrideUrl || url;
101
- finalOptions = __assign(__assign(__assign({}, defaultOptions), overrideOptions), { headers: __assign(__assign({}, defaultOptions.headers), ((overrideOptions === null || overrideOptions === void 0 ? void 0 : overrideOptions.headers) || {})) });
101
+ _a = defaultOptions || {}, defaultParams = _a.params, restDefaultOptions = __rest(_a, ["params"]);
102
+ _b = overrideOptions || {}, overrideParams = _b.params, restOverrideOptions = __rest(_b, ["params"]);
103
+ mergedParams = __assign(__assign({}, (defaultParams || {})), (overrideParams || {}));
104
+ finalOptions = __assign(__assign(__assign({}, restDefaultOptions), restOverrideOptions), { headers: __assign(__assign({}, (restDefaultOptions.headers || {})), (restOverrideOptions.headers || {})) });
105
+ method = (finalOptions.method || 'GET')
106
+ .toString()
107
+ .toUpperCase();
108
+ if (method === 'GET' &&
109
+ mergedParams &&
110
+ Object.keys(mergedParams).length) {
111
+ hashIndex = finalUrl.indexOf('#');
112
+ hash = hashIndex >= 0 ? finalUrl.slice(hashIndex) : '';
113
+ basePart = hashIndex >= 0 ? finalUrl.slice(0, hashIndex) : finalUrl;
114
+ searchIndex = basePart.indexOf('?');
115
+ pathname = searchIndex >= 0 ? basePart.slice(0, searchIndex) : basePart;
116
+ existingSearch = searchIndex >= 0 ? basePart.slice(searchIndex + 1) : '';
117
+ searchParams_1 = new URLSearchParams(existingSearch);
118
+ Object.entries(mergedParams).forEach(function (_a) {
119
+ var key = _a[0], value = _a[1];
120
+ if (value == null)
121
+ return;
122
+ if (Array.isArray(value)) {
123
+ value.forEach(function (v) { return searchParams_1.append(key, String(v)); });
124
+ }
125
+ else if (typeof value === 'object') {
126
+ searchParams_1.append(key, JSON.stringify(value));
127
+ }
128
+ else {
129
+ searchParams_1.append(key, String(value));
130
+ }
131
+ });
132
+ newSearch = searchParams_1.toString();
133
+ finalUrl = pathname + (newSearch ? "?".concat(newSearch) : '') + hash;
134
+ }
102
135
  setLoading(true);
103
136
  setError(null);
104
137
  setData(null);
105
138
  controller = new AbortController();
106
139
  abortControllerRef.current = controller;
107
140
  finalOptions.signal = controller.signal;
108
- _b.label = 1;
141
+ _d.label = 1;
109
142
  case 1:
110
- _b.trys.push([1, 7, 8, 9]);
143
+ _d.trys.push([1, 7, 8, 9]);
111
144
  return [4 /*yield*/, fetch(finalUrl, finalOptions)];
112
145
  case 2:
113
- response = _b.sent();
146
+ response = _d.sent();
114
147
  parsed = null;
115
- _b.label = 3;
148
+ _d.label = 3;
116
149
  case 3:
117
- _b.trys.push([3, 5, , 6]);
150
+ _d.trys.push([3, 5, , 6]);
118
151
  return [4 /*yield*/, response.json()];
119
152
  case 4:
120
- parsed = _b.sent();
153
+ parsed = _d.sent();
121
154
  return [3 /*break*/, 6];
122
155
  case 5:
123
- _a = _b.sent();
156
+ _c = _d.sent();
124
157
  // non-json or empty body
125
158
  parsed = null;
126
159
  return [3 /*break*/, 6];
@@ -152,7 +185,7 @@ var useFetch = function (url, config, deps) {
152
185
  }
153
186
  return [3 /*break*/, 9];
154
187
  case 7:
155
- err_1 = _b.sent();
188
+ err_1 = _d.sent();
156
189
  if (isMounted.current) {
157
190
  setError(err_1);
158
191
  setData(null);
@@ -0,0 +1,94 @@
1
+ /**
2
+ * useModuleEntityV2
3
+ *
4
+ * Summary
5
+ * - A convenience hook that manages common module/entity operations: list, get-by-id,
6
+ * create/update, and delete. It composes `useFetch` for HTTP calls and `useDebounce`
7
+ * for debouncing search queries.
8
+ *
9
+ * Main features
10
+ * - List: performs a GET to `listUrl` with `listParams`. The hook listens to
11
+ * `searchQuery` (debounced) and `listDeps` to re-run the list fetch.
12
+ * - Get by ID: performs a GET to `unitByIdUrl` with `byIdParams` and returns
13
+ * `byIdFetchNow`, `byIdLoading`, and `byIdError`.
14
+ * - Create/Update: performs a PUT to `unitUrl` with a JSON body `updateParams`.
15
+ * On successful create/update the hook triggers a coalesced list refresh.
16
+ * - Delete: performs a DELETE to `unitUrl` with a JSON body `deleteParams` and
17
+ * triggers a coalesced list refresh when the operation succeeds.
18
+ * - Refresh batching: `refreshList(delay)` coalesces multiple rapid updates/deletes
19
+ * using a short timeout (default 300ms) to avoid unnecessary list reloads.
20
+ *
21
+ * Parameters (object)
22
+ * - `byIdCallback(data)`, `byIdDeps`, `byIdParams`
23
+ * - `deleteCallback(data)`, `deleteDeps`, `deleteParams`
24
+ * - `listCallback(data)`, `listDeps`, `listParams`, `listUrl`
25
+ * - `searchQuery` (string) — debounced before influencing the list fetch
26
+ * - `unitByIdUrl`, `unitUrl`
27
+ * - `updateCallback(data)`, `updateDeps`, `updateParams`
28
+ *
29
+ * Return values
30
+ * - `byIdFetchNow(url?, config?)`, `byIdLoading`, `byIdError`
31
+ * - `listFetchNow(url?, config?)`, `listLoading`, `listError`
32
+ * - `updateFetchNow(url?, config?)`, `updateLoading`, `updateError`
33
+ * - `deleteFetchNow(url?, config?)`, `deleteLoading`, `deleteError`
34
+ *
35
+ * Behavior notes
36
+ * - All callbacks receive an object `{ data, error, status, ok }` from `useFetch`.
37
+ * - Callbacks are wrapped so that any errors they throw are swallowed; this
38
+ * ensures the hook's refresh logic still runs reliably.
39
+ * - `refreshList()` calls `listFetchNow(undefined, { method: 'POST', params: listParams })`
40
+ * to explicitly re-query the list endpoint with the current `listParams`.
41
+ * - Network calls are delegated to `useFetch`; callers can call the returned
42
+ * `*FetchNow` functions directly with an override URL or config.
43
+ *
44
+ * Example
45
+ * const { listFetchNow, updateFetchNow } = useModuleEntityV2({
46
+ * listUrl: '/items',
47
+ * listParams: { page: 1 },
48
+ * listCallback: (res) => console.log(res),
49
+ * unitUrl: '/items',
50
+ * updateCallback: () => {},
51
+ * updateParams: {}
52
+ * });
53
+ */
54
+ import { FetchConfig } from './use-fetch';
55
+ export interface CallbackParams {
56
+ data: any;
57
+ error: any;
58
+ status?: number;
59
+ ok?: boolean;
60
+ }
61
+ interface Params {
62
+ byIdCallback: (d: CallbackParams) => void;
63
+ byIdDeps?: Array<any> | Array<string>;
64
+ byIdParams: object;
65
+ deleteCallback?: (d: CallbackParams) => void;
66
+ deleteDeps?: Array<any> | Array<string>;
67
+ deleteParams?: object;
68
+ listCallback: (d: CallbackParams) => void;
69
+ listDeps?: Array<any> | Array<string>;
70
+ listParams: object;
71
+ listUrl: string;
72
+ searchQuery: string;
73
+ unitByIdUrl: string;
74
+ unitUrl: string;
75
+ updateCallback: (d: CallbackParams) => void;
76
+ updateDeps?: Array<any> | Array<string>;
77
+ updateParams: object;
78
+ }
79
+ interface Return {
80
+ byIdError?: Error;
81
+ byIdFetchNow: (url?: string, config?: FetchConfig) => void;
82
+ byIdLoading: boolean;
83
+ deleteError?: Error;
84
+ deleteFetchNow?: (url?: string, config?: FetchConfig) => void;
85
+ deleteLoading: boolean;
86
+ listError?: Error;
87
+ listFetchNow: (url?: string, config?: FetchConfig) => void;
88
+ listLoading: boolean;
89
+ updateError?: Error;
90
+ updateFetchNow: (url?: string, config?: FetchConfig) => void;
91
+ updateLoading: boolean;
92
+ }
93
+ export declare const useModuleEntityV2: ({ byIdCallback, byIdDeps, byIdParams, deleteCallback, deleteDeps, deleteParams, listCallback, listDeps, listParams, listUrl, searchQuery, unitByIdUrl, unitUrl, updateCallback, updateDeps, updateParams, }: Params) => Return;
94
+ export {};
@@ -0,0 +1,176 @@
1
+ "use strict";
2
+ /**
3
+ * useModuleEntityV2
4
+ *
5
+ * Summary
6
+ * - A convenience hook that manages common module/entity operations: list, get-by-id,
7
+ * create/update, and delete. It composes `useFetch` for HTTP calls and `useDebounce`
8
+ * for debouncing search queries.
9
+ *
10
+ * Main features
11
+ * - List: performs a GET to `listUrl` with `listParams`. The hook listens to
12
+ * `searchQuery` (debounced) and `listDeps` to re-run the list fetch.
13
+ * - Get by ID: performs a GET to `unitByIdUrl` with `byIdParams` and returns
14
+ * `byIdFetchNow`, `byIdLoading`, and `byIdError`.
15
+ * - Create/Update: performs a PUT to `unitUrl` with a JSON body `updateParams`.
16
+ * On successful create/update the hook triggers a coalesced list refresh.
17
+ * - Delete: performs a DELETE to `unitUrl` with a JSON body `deleteParams` and
18
+ * triggers a coalesced list refresh when the operation succeeds.
19
+ * - Refresh batching: `refreshList(delay)` coalesces multiple rapid updates/deletes
20
+ * using a short timeout (default 300ms) to avoid unnecessary list reloads.
21
+ *
22
+ * Parameters (object)
23
+ * - `byIdCallback(data)`, `byIdDeps`, `byIdParams`
24
+ * - `deleteCallback(data)`, `deleteDeps`, `deleteParams`
25
+ * - `listCallback(data)`, `listDeps`, `listParams`, `listUrl`
26
+ * - `searchQuery` (string) — debounced before influencing the list fetch
27
+ * - `unitByIdUrl`, `unitUrl`
28
+ * - `updateCallback(data)`, `updateDeps`, `updateParams`
29
+ *
30
+ * Return values
31
+ * - `byIdFetchNow(url?, config?)`, `byIdLoading`, `byIdError`
32
+ * - `listFetchNow(url?, config?)`, `listLoading`, `listError`
33
+ * - `updateFetchNow(url?, config?)`, `updateLoading`, `updateError`
34
+ * - `deleteFetchNow(url?, config?)`, `deleteLoading`, `deleteError`
35
+ *
36
+ * Behavior notes
37
+ * - All callbacks receive an object `{ data, error, status, ok }` from `useFetch`.
38
+ * - Callbacks are wrapped so that any errors they throw are swallowed; this
39
+ * ensures the hook's refresh logic still runs reliably.
40
+ * - `refreshList()` calls `listFetchNow(undefined, { method: 'POST', params: listParams })`
41
+ * to explicitly re-query the list endpoint with the current `listParams`.
42
+ * - Network calls are delegated to `useFetch`; callers can call the returned
43
+ * `*FetchNow` functions directly with an override URL or config.
44
+ *
45
+ * Example
46
+ * const { listFetchNow, updateFetchNow } = useModuleEntityV2({
47
+ * listUrl: '/items',
48
+ * listParams: { page: 1 },
49
+ * listCallback: (res) => console.log(res),
50
+ * unitUrl: '/items',
51
+ * updateCallback: () => {},
52
+ * updateParams: {}
53
+ * });
54
+ */
55
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
56
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
57
+ if (ar || !(i in from)) {
58
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
59
+ ar[i] = from[i];
60
+ }
61
+ }
62
+ return to.concat(ar || Array.prototype.slice.call(from));
63
+ };
64
+ Object.defineProperty(exports, "__esModule", { value: true });
65
+ exports.useModuleEntityV2 = void 0;
66
+ var react_1 = require("react");
67
+ var constants_1 = require("../constants");
68
+ var use_fetch_1 = require("./use-fetch");
69
+ var use_debounce_1 = require("./use-debounce");
70
+ var useModuleEntityV2 = function (_a) {
71
+ var byIdCallback = _a.byIdCallback, _b = _a.byIdDeps, byIdDeps = _b === void 0 ? [] : _b, byIdParams = _a.byIdParams, deleteCallback = _a.deleteCallback, _c = _a.deleteDeps, deleteDeps = _c === void 0 ? [] : _c, deleteParams = _a.deleteParams, listCallback = _a.listCallback, _d = _a.listDeps, listDeps = _d === void 0 ? [] : _d, listParams = _a.listParams, listUrl = _a.listUrl, searchQuery = _a.searchQuery, unitByIdUrl = _a.unitByIdUrl, unitUrl = _a.unitUrl, updateCallback = _a.updateCallback, _e = _a.updateDeps, updateDeps = _e === void 0 ? [] : _e, updateParams = _a.updateParams;
72
+ var debouncedQuery = (0, use_debounce_1.useDebounce)(searchQuery, 800);
73
+ // debounced list refresh to batch multiple updates/deletes
74
+ var refreshTimerRef = (0, react_1.useRef)(null);
75
+ (0, react_1.useEffect)(function () { return function () {
76
+ if (refreshTimerRef.current) {
77
+ globalThis.clearTimeout(refreshTimerRef.current);
78
+ refreshTimerRef.current = null;
79
+ }
80
+ }; }, []);
81
+ // list
82
+ var _f = (0, use_fetch_1.useFetch)(listUrl, {
83
+ method: constants_1.API_METHODS.GET,
84
+ params: listParams,
85
+ callback: listCallback,
86
+ }, __spreadArray([debouncedQuery, listParams], listDeps, true)), listError = _f.error, listFetchNow = _f.fetchNow, listLoading = _f.loading;
87
+ var refreshList = function (delay) {
88
+ if (delay === void 0) { delay = 300; }
89
+ if (refreshTimerRef.current) {
90
+ globalThis.clearTimeout(refreshTimerRef.current);
91
+ }
92
+ refreshTimerRef.current = globalThis.setTimeout(function () {
93
+ try {
94
+ // pass current list params explicitly so the fetch uses the latest values
95
+ listFetchNow(undefined, {
96
+ method: constants_1.API_METHODS.POST,
97
+ params: listParams,
98
+ });
99
+ }
100
+ catch (_a) {
101
+ // noop
102
+ }
103
+ refreshTimerRef.current = null;
104
+ }, delay);
105
+ };
106
+ // create / edit
107
+ var _g = (0, use_fetch_1.useFetch)(unitUrl, {
108
+ method: constants_1.API_METHODS.PUT,
109
+ body: JSON.stringify(updateParams),
110
+ callback: function (d) {
111
+ if (updateCallback) {
112
+ try {
113
+ updateCallback(d);
114
+ }
115
+ catch (_a) {
116
+ // swallow callback errors to ensure list refresh still runs
117
+ // caller's callback is responsible for its own error handling
118
+ }
119
+ }
120
+ // refresh the list after update/create only when the operation succeeded
121
+ try {
122
+ if (d && d.ok) {
123
+ refreshList();
124
+ }
125
+ }
126
+ catch (_b) {
127
+ // noop
128
+ }
129
+ },
130
+ }, __spreadArray([], updateDeps, true)), updateError = _g.error, updateLoading = _g.loading, updateFetchNow = _g.fetchNow;
131
+ // by id
132
+ var _h = (0, use_fetch_1.useFetch)(unitByIdUrl, {
133
+ method: constants_1.API_METHODS.GET,
134
+ params: byIdParams,
135
+ callback: byIdCallback,
136
+ }, __spreadArray([], byIdDeps, true)), byIdError = _h.error, byIdLoading = _h.loading, byIdFetchNow = _h.fetchNow;
137
+ // delete
138
+ var _j = (0, use_fetch_1.useFetch)(unitUrl, {
139
+ method: constants_1.API_METHODS.DELETE,
140
+ body: JSON.stringify(deleteParams),
141
+ callback: function (d) {
142
+ if (deleteCallback) {
143
+ try {
144
+ deleteCallback(d);
145
+ }
146
+ catch (_a) {
147
+ // swallow callback errors to ensure list refresh still runs
148
+ }
149
+ }
150
+ // refresh the list after delete only when the operation succeeded
151
+ try {
152
+ if (d && d.ok) {
153
+ refreshList();
154
+ }
155
+ }
156
+ catch (_b) {
157
+ // noop
158
+ }
159
+ },
160
+ }, __spreadArray([], deleteDeps, true)), deleteError = _j.error, deleteLoading = _j.loading, deleteFetchNow = _j.fetchNow;
161
+ return {
162
+ byIdError: byIdError,
163
+ byIdFetchNow: byIdFetchNow,
164
+ byIdLoading: byIdLoading,
165
+ deleteError: deleteError,
166
+ deleteFetchNow: deleteFetchNow,
167
+ deleteLoading: deleteLoading,
168
+ listError: listError,
169
+ listFetchNow: listFetchNow,
170
+ listLoading: listLoading,
171
+ updateError: updateError,
172
+ updateFetchNow: updateFetchNow,
173
+ updateLoading: updateLoading,
174
+ };
175
+ };
176
+ exports.useModuleEntityV2 = useModuleEntityV2;
@@ -1,3 +1,57 @@
1
+ /**
2
+ * useModuleEntity
3
+ *
4
+ * Summary
5
+ * - A convenience hook that manages common module/entity operations: list, get-by-id,
6
+ * create/update, and delete. It composes `useFetch` for HTTP calls and `useDebounce`
7
+ * for debouncing search queries.
8
+ *
9
+ * Main features
10
+ * - List: performs a POST to `listUrl` with a JSON body `listParams` and re-runs
11
+ * when `searchQuery` (debounced) or `listDeps` change.
12
+ * - Get by ID: performs a POST to `unitByIdUrl` with `byIdParams` in the JSON body
13
+ * and exposes `byIdFetchNow`, `byIdLoading`, and `byIdError`.
14
+ * - Create/Update: performs a POST to `unitUrl` with a JSON body `updateParams`.
15
+ * On successful create/update the hook triggers a coalesced list refresh.
16
+ * - Delete: performs a DELETE to `unitUrl` with a JSON body `deleteParams` and
17
+ * triggers a coalesced list refresh when the operation succeeds.
18
+ * - Refresh batching: `refreshList(delay)` coalesces multiple rapid updates/deletes
19
+ * using a short timeout (default 300ms) to avoid unnecessary list reloads.
20
+ *
21
+ * Parameters (object)
22
+ * - `byIdCallback(data)`, `byIdDeps`, `byIdParams`
23
+ * - `deleteCallback(data)`, `deleteDeps`, `deleteParams`
24
+ * - `listCallback(data)`, `listDeps`, `listParams`, `listUrl`
25
+ * - `searchQuery` (string) — debounced before influencing the list fetch
26
+ * - `unitByIdUrl`, `unitUrl`
27
+ * - `updateCallback(data)`, `updateDeps`, `updateParams`
28
+ *
29
+ * Return values
30
+ * - `byIdFetchNow(url?, config?)`, `byIdLoading`, `byIdError`
31
+ * - `listFetchNow(url?, config?)`, `listLoading`, `listError`
32
+ * - `updateFetchNow(url?, config?)`, `updateLoading`, `updateError`
33
+ * - `deleteFetchNow(url?, config?)`, `deleteLoading`, `deleteError`
34
+ *
35
+ * Behavior notes
36
+ * - All requests that accept parameters send them in the JSON request body (stringified).
37
+ * - All callbacks receive an object `{ data, error, status, ok }` from `useFetch`.
38
+ * - Callbacks are wrapped so thrown errors are swallowed to ensure refresh logic
39
+ * still runs reliably.
40
+ * - `refreshList()` calls `listFetchNow(undefined, { method: 'POST', body: JSON.stringify(listParams) })`
41
+ * to explicitly re-query the list endpoint with the current `listParams`.
42
+ * - Network calls are delegated to `useFetch`; callers can invoke the returned
43
+ * `*FetchNow` functions directly with an override URL or config.
44
+ *
45
+ * Example
46
+ * const { listFetchNow, updateFetchNow } = useModuleEntity({
47
+ * listUrl: '/items',
48
+ * listParams: { page: 1 },
49
+ * listCallback: (res) => console.log(res),
50
+ * unitUrl: '/items',
51
+ * updateCallback: () => {},
52
+ * updateParams: {}
53
+ * });
54
+ */
1
55
  import { FetchConfig } from './use-fetch';
2
56
  export interface CallbackParams {
3
57
  data: any;
@@ -1,4 +1,58 @@
1
1
  "use strict";
2
+ /**
3
+ * useModuleEntity
4
+ *
5
+ * Summary
6
+ * - A convenience hook that manages common module/entity operations: list, get-by-id,
7
+ * create/update, and delete. It composes `useFetch` for HTTP calls and `useDebounce`
8
+ * for debouncing search queries.
9
+ *
10
+ * Main features
11
+ * - List: performs a POST to `listUrl` with a JSON body `listParams` and re-runs
12
+ * when `searchQuery` (debounced) or `listDeps` change.
13
+ * - Get by ID: performs a POST to `unitByIdUrl` with `byIdParams` in the JSON body
14
+ * and exposes `byIdFetchNow`, `byIdLoading`, and `byIdError`.
15
+ * - Create/Update: performs a POST to `unitUrl` with a JSON body `updateParams`.
16
+ * On successful create/update the hook triggers a coalesced list refresh.
17
+ * - Delete: performs a DELETE to `unitUrl` with a JSON body `deleteParams` and
18
+ * triggers a coalesced list refresh when the operation succeeds.
19
+ * - Refresh batching: `refreshList(delay)` coalesces multiple rapid updates/deletes
20
+ * using a short timeout (default 300ms) to avoid unnecessary list reloads.
21
+ *
22
+ * Parameters (object)
23
+ * - `byIdCallback(data)`, `byIdDeps`, `byIdParams`
24
+ * - `deleteCallback(data)`, `deleteDeps`, `deleteParams`
25
+ * - `listCallback(data)`, `listDeps`, `listParams`, `listUrl`
26
+ * - `searchQuery` (string) — debounced before influencing the list fetch
27
+ * - `unitByIdUrl`, `unitUrl`
28
+ * - `updateCallback(data)`, `updateDeps`, `updateParams`
29
+ *
30
+ * Return values
31
+ * - `byIdFetchNow(url?, config?)`, `byIdLoading`, `byIdError`
32
+ * - `listFetchNow(url?, config?)`, `listLoading`, `listError`
33
+ * - `updateFetchNow(url?, config?)`, `updateLoading`, `updateError`
34
+ * - `deleteFetchNow(url?, config?)`, `deleteLoading`, `deleteError`
35
+ *
36
+ * Behavior notes
37
+ * - All requests that accept parameters send them in the JSON request body (stringified).
38
+ * - All callbacks receive an object `{ data, error, status, ok }` from `useFetch`.
39
+ * - Callbacks are wrapped so thrown errors are swallowed to ensure refresh logic
40
+ * still runs reliably.
41
+ * - `refreshList()` calls `listFetchNow(undefined, { method: 'POST', body: JSON.stringify(listParams) })`
42
+ * to explicitly re-query the list endpoint with the current `listParams`.
43
+ * - Network calls are delegated to `useFetch`; callers can invoke the returned
44
+ * `*FetchNow` functions directly with an override URL or config.
45
+ *
46
+ * Example
47
+ * const { listFetchNow, updateFetchNow } = useModuleEntity({
48
+ * listUrl: '/items',
49
+ * listParams: { page: 1 },
50
+ * listCallback: (res) => console.log(res),
51
+ * unitUrl: '/items',
52
+ * updateCallback: () => {},
53
+ * updateParams: {}
54
+ * });
55
+ */
2
56
  var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
57
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
58
  if (ar || !(i in from)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-pakistan/util-functions",
3
- "version": "1.25.2",
3
+ "version": "1.25.4",
4
4
  "description": "A library of all util functions",
5
5
  "main": "index.js",
6
6
  "scripts": {