@react-pakistan/util-functions 1.25.38 → 1.25.40

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.
@@ -5,15 +5,7 @@
5
5
  * Generates tables, forms, drawers, and other common UI patterns.
6
6
  */
7
7
  import React, { FC } from 'react';
8
- type COMPONENT_TYPE = string;
9
- interface HeaderAction {
10
- [key: string]: any;
11
- }
12
- interface TableColumn {
13
- label: string;
14
- width?: string | number;
15
- [key: string]: any;
16
- }
8
+ import { COMPONENT_TYPE, HeaderAction, TableColumn } from '@appcorp/shadcn/components/enhanced-table';
17
9
  export declare const DRAWER_TYPES: {
18
10
  FORM_DRAWER: string;
19
11
  FILTER_DRAWER: string;
@@ -42,38 +42,14 @@ var __importStar = (this && this.__importStar) || (function () {
42
42
  Object.defineProperty(exports, "__esModule", { value: true });
43
43
  exports.createGenericModulePage = exports.GenericDrawer = exports.GenericTable = exports.DRAWER_TYPES = void 0;
44
44
  var react_1 = __importStar(require("react"));
45
+ var next_intl_1 = require("next-intl");
45
46
  var general_1 = require("../general");
46
47
  var use_rtl_1 = require("../hooks/use-rtl");
47
- // Local constants to avoid static imports from @appcorp/shadcn
48
- var DRAWER_FOOTER_COMPONENT_TYPE = {
49
- FORM_DRAWER: 'FORM_DRAWER',
50
- VIEW_DRAWER: 'VIEW_DRAWER',
51
- FILTER_DRAWER: 'FILTER_DRAWER',
52
- MORE_ACTIONS_DRAWER: 'MORE_ACTIONS_DRAWER',
53
- };
54
- // Helper to either lazy-load a component/value or require it synchronously in tests
55
- var isTestEnv = typeof process !== 'undefined' && !!process.env.JEST_WORKER_ID;
56
- var lazyOrSync = function (path, name, isComponent) {
57
- if (isComponent === void 0) { isComponent = true; }
58
- if (isTestEnv) {
59
- // eslint-disable-next-line @typescript-eslint/no-require-imports
60
- var mod = require(path);
61
- return mod[name];
62
- }
63
- if (isComponent) {
64
- return react_1.default.lazy(function () {
65
- return Promise.resolve("".concat(/* @vite-ignore */ path)).then(function (s) { return __importStar(require(s)); }).then(function (m) { return ({ default: m[name] }); });
66
- });
67
- }
68
- // For non-components (constants, enums), lazy-load the module and return the value
69
- return Promise.resolve("".concat(/* @vite-ignore */ path)).then(function (s) { return __importStar(require(s)); }).then(function (m) { return m[name]; });
70
- };
71
- // Lazy-load components
72
- var EnhancedTable = lazyOrSync('@appcorp/shadcn/components/enhanced-table', 'EnhancedTable');
73
- var Toaster = lazyOrSync('@appcorp/shadcn/components/ui/sonner', 'Toaster');
74
- var DrawerGeneric = lazyOrSync('@appcorp/shadcn/components/drawer-generic', 'DrawerGeneric');
75
- var EnhancedDrawerHeader = lazyOrSync('@appcorp/shadcn/components/enhanced-drawer-header', 'EnhancedDrawerHeader');
76
- var EnhancedDrawerFooter = lazyOrSync('@appcorp/shadcn/components/enhanced-drawer-footer', 'EnhancedDrawerFooter');
48
+ var enhanced_table_1 = require("@appcorp/shadcn/components/enhanced-table");
49
+ var sonner_1 = require("@appcorp/shadcn/components/ui/sonner");
50
+ var drawer_generic_1 = require("@appcorp/shadcn/components/drawer-generic");
51
+ var enhanced_drawer_header_1 = require("@appcorp/shadcn/components/enhanced-drawer-header");
52
+ var enhanced_drawer_footer_1 = require("@appcorp/shadcn/components/enhanced-drawer-footer");
77
53
  // ============================================================================
78
54
  // CONSTANTS
79
55
  // ============================================================================
@@ -85,18 +61,7 @@ exports.DRAWER_TYPES = {
85
61
  };
86
62
  var GenericTable = function (_a) {
87
63
  var config = _a.config, context = _a.context, tableBodyCols = _a.tableBodyCols, headerActions = _a.headerActions, rowActions = _a.rowActions;
88
- // get a useTranslations hook if available, otherwise a fallback translator
89
- var maybeUseTranslations = (function () {
90
- try {
91
- // eslint-disable-next-line @typescript-eslint/no-require-imports
92
- var useTranslations = require('next-intl').useTranslations;
93
- return useTranslations;
94
- }
95
- catch (_a) {
96
- return function (_ns) { return function (key) { return key; }; };
97
- }
98
- })();
99
- var t = maybeUseTranslations(config.moduleName);
64
+ var t = (0, next_intl_1.useTranslations)(config.moduleName);
100
65
  var isRTL = (0, use_rtl_1.useRTL)();
101
66
  var tableHeadItems = (0, react_1.useMemo)(function () {
102
67
  return config.tableColumns.map(function (col) { return ({
@@ -108,26 +73,15 @@ var GenericTable = function (_a) {
108
73
  // Build header actions from context or props
109
74
  var allHeaderActions = (0, react_1.useMemo)(function () { return headerActions || context.headerActions || []; }, [headerActions, context.headerActions]);
110
75
  return (react_1.default.createElement("div", { className: "space-y-4 ".concat(isRTL ? 'rtl' : 'ltr'), dir: isRTL ? 'rtl' : 'ltr' },
111
- react_1.default.createElement(react_1.default.Suspense, { fallback: null },
112
- react_1.default.createElement(EnhancedTable, { currentPage: Number(context.state.currentPage), handleNextOnClick: context.handlePageChange, handleOnSelect: context.handlePageLimitChange, handlePreviousOnClick: function () {
113
- return context.handlePageChange(context.state.currentPage - 1);
114
- }, handleSearchInput: context.handleSearch, headerActions: allHeaderActions, isNextDisabled: (0, general_1.isNextButtonDisabled)(context.state.currentPage, totalPages), isPreviousDisabled: (0, general_1.isPreviousButtonDisabled)(context.state.currentPage), listOptions: (0, general_1.getAvailablePageLimits)(context.state.count), loading: context.listLoading, nodeSelectKey: "pageLimit", pageLimit: context.state.pageLimit, rowActions: rowActions || context.rowActions || [], searchDisabled: false, searchEnabled: true, searchId: "".concat(config.moduleName.toLowerCase(), "-search"), searchPlaceholder: t(config.searchPlaceholder), searchValue: context.state.searchQuery, tableBodyCols: tableBodyCols, tableBodyRows: context.state.items, tableDescription: t(config.tableDescription), tableHeadItems: tableHeadItems, tableHeading: t(config.tableTitle), totalPages: Number(totalPages) }))));
76
+ react_1.default.createElement(enhanced_table_1.EnhancedTable, { currentPage: Number(context.state.currentPage), handleNextOnClick: context.handlePageChange, handleOnSelect: context.handlePageLimitChange, handlePreviousOnClick: function () {
77
+ return context.handlePageChange(context.state.currentPage - 1);
78
+ }, handleSearchInput: context.handleSearch, headerActions: allHeaderActions, isNextDisabled: (0, general_1.isNextButtonDisabled)(context.state.currentPage, totalPages), isPreviousDisabled: (0, general_1.isPreviousButtonDisabled)(context.state.currentPage), listOptions: (0, general_1.getAvailablePageLimits)(context.state.count), loading: context.listLoading, nodeSelectKey: "pageLimit", pageLimit: context.state.pageLimit, rowActions: rowActions || context.rowActions || [], searchDisabled: false, searchEnabled: true, searchId: "".concat(config.moduleName.toLowerCase(), "-search"), searchPlaceholder: t(config.searchPlaceholder), searchValue: context.state.searchQuery, tableBodyCols: tableBodyCols, tableBodyRows: context.state.items, tableDescription: t(config.tableDescription), tableHeadItems: tableHeadItems, tableHeading: t(config.tableTitle), totalPages: Number(totalPages) })));
115
79
  };
116
80
  exports.GenericTable = GenericTable;
117
81
  var GenericDrawer = function (_a) {
118
82
  var _b, _c, _d, _e, _f, _g;
119
83
  var config = _a.config, context = _a.context, formContent = _a.formContent, viewContent = _a.viewContent, filterContent = _a.filterContent, moreActionsContent = _a.moreActionsContent;
120
- var maybeUseTranslations = (function () {
121
- try {
122
- // eslint-disable-next-line @typescript-eslint/no-require-imports
123
- var useTranslations = require('next-intl').useTranslations;
124
- return useTranslations;
125
- }
126
- catch (_a) {
127
- return function (_ns) { return function (key) { return key; }; };
128
- }
129
- })();
130
- var t = maybeUseTranslations(config.moduleName);
84
+ var t = (0, next_intl_1.useTranslations)(config.moduleName);
131
85
  var isRTL = (0, use_rtl_1.useRTL)();
132
86
  var closeDrawer = context.closeDrawer || context.handleCloseDrawer;
133
87
  var _h = context.state, disableSaveButton = _h.disableSaveButton, drawer = _h.drawer;
@@ -141,16 +95,15 @@ var GenericDrawer = function (_a) {
141
95
  ? t(config.drawerDescription)
142
96
  : '';
143
97
  var errors = (_b = context.state.errors) !== null && _b !== void 0 ? _b : {};
144
- var formHeader = isFormDrawer ? (react_1.default.createElement(EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
145
- var viewHeader = isViewDrawer ? (react_1.default.createElement(EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
146
- var filterHeader = isFilterDrawer ? (react_1.default.createElement(EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
147
- var moreActionsHeader = isMoreActionsDrawer ? (react_1.default.createElement(EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
148
- var formFooter = isFormDrawer ? (react_1.default.createElement(EnhancedDrawerFooter, { applyFilters: function () { }, clearFilters: function () { }, closeDrawer: closeDrawer, disableSaveButton: disableSaveButton, drawerType: DRAWER_FOOTER_COMPONENT_TYPE.FORM_DRAWER, errors: errors, handleSubmit: context.handleSubmit, updateLoading: (_c = context.updateLoading) !== null && _c !== void 0 ? _c : false })) : null;
149
- var viewFooter = isViewDrawer ? (react_1.default.createElement(EnhancedDrawerFooter, { applyFilters: function () { }, clearFilters: function () { }, closeDrawer: closeDrawer, disableSaveButton: false, drawerType: DRAWER_FOOTER_COMPONENT_TYPE.VIEW_DRAWER, errors: errors, handleSubmit: function () { }, updateLoading: false })) : null;
150
- var filterFooter = isFilterDrawer ? (react_1.default.createElement(EnhancedDrawerFooter, { applyFilters: (_d = context.applyFilters) !== null && _d !== void 0 ? _d : (function () { }), clearFilters: (_e = context.clearFilters) !== null && _e !== void 0 ? _e : (function () { }), closeDrawer: closeDrawer, disableSaveButton: false, drawerType: DRAWER_FOOTER_COMPONENT_TYPE.FILTER_DRAWER, errors: errors, handleSubmit: (_f = context.handleSubmit) !== null && _f !== void 0 ? _f : (function () { }), updateLoading: false })) : null;
151
- var moreActionsFooter = isMoreActionsDrawer ? (react_1.default.createElement(EnhancedDrawerFooter, { applyFilters: function () { }, clearFilters: function () { }, closeDrawer: closeDrawer, disableSaveButton: false, drawerType: DRAWER_FOOTER_COMPONENT_TYPE.MORE_ACTIONS_DRAWER, errors: errors, handleSubmit: function () { }, updateLoading: false })) : null;
152
- return (react_1.default.createElement(react_1.default.Suspense, { fallback: null },
153
- react_1.default.createElement(DrawerGeneric, { direction: isRTL ? 'left' : 'right', filterDrawer: isFilterDrawer ? filterContent : null, filterDrawerFooter: filterFooter, filterDrawerHeader: filterHeader, formDrawer: isFormDrawer ? formContent : null, formDrawerFooter: formFooter, formDrawerHeader: formHeader, moreActionsDrawer: isMoreActionsDrawer ? moreActionsContent : null, moreActionsDrawerFooter: moreActionsFooter, moreActionsDrawerHeader: moreActionsHeader, onOpenChange: function (open) { return !open && closeDrawer(); }, open: isOpen, viewDrawer: isViewDrawer ? viewContent : null, viewDrawerFooter: viewFooter, viewDrawerHeader: viewHeader, width: (_g = config.size) !== null && _g !== void 0 ? _g : 'small' })));
98
+ var formHeader = isFormDrawer ? (react_1.default.createElement(enhanced_drawer_header_1.EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
99
+ var viewHeader = isViewDrawer ? (react_1.default.createElement(enhanced_drawer_header_1.EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
100
+ var filterHeader = isFilterDrawer ? (react_1.default.createElement(enhanced_drawer_header_1.EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
101
+ var moreActionsHeader = isMoreActionsDrawer ? (react_1.default.createElement(enhanced_drawer_header_1.EnhancedDrawerHeader, { title: drawerTitle, description: drawerDescription })) : null;
102
+ var formFooter = isFormDrawer ? (react_1.default.createElement(enhanced_drawer_footer_1.EnhancedDrawerFooter, { applyFilters: function () { }, clearFilters: function () { }, closeDrawer: closeDrawer, disableSaveButton: disableSaveButton, drawerType: enhanced_drawer_footer_1.DRAWER_FOOTER_COMPONENT_TYPE.FORM_DRAWER, errors: errors, handleSubmit: context.handleSubmit, updateLoading: (_c = context.updateLoading) !== null && _c !== void 0 ? _c : false })) : null;
103
+ var viewFooter = isViewDrawer ? (react_1.default.createElement(enhanced_drawer_footer_1.EnhancedDrawerFooter, { applyFilters: function () { }, clearFilters: function () { }, closeDrawer: closeDrawer, disableSaveButton: false, drawerType: enhanced_drawer_footer_1.DRAWER_FOOTER_COMPONENT_TYPE.VIEW_DRAWER, errors: errors, handleSubmit: function () { }, updateLoading: false })) : null;
104
+ var filterFooter = isFilterDrawer ? (react_1.default.createElement(enhanced_drawer_footer_1.EnhancedDrawerFooter, { applyFilters: (_d = context.applyFilters) !== null && _d !== void 0 ? _d : (function () { }), clearFilters: (_e = context.clearFilters) !== null && _e !== void 0 ? _e : (function () { }), closeDrawer: closeDrawer, disableSaveButton: false, drawerType: enhanced_drawer_footer_1.DRAWER_FOOTER_COMPONENT_TYPE.FILTER_DRAWER, errors: errors, handleSubmit: (_f = context.handleSubmit) !== null && _f !== void 0 ? _f : (function () { }), updateLoading: false })) : null;
105
+ var moreActionsFooter = isMoreActionsDrawer ? (react_1.default.createElement(enhanced_drawer_footer_1.EnhancedDrawerFooter, { applyFilters: function () { }, clearFilters: function () { }, closeDrawer: closeDrawer, disableSaveButton: false, drawerType: enhanced_drawer_footer_1.DRAWER_FOOTER_COMPONENT_TYPE.MORE_ACTIONS_DRAWER, errors: errors, handleSubmit: function () { }, updateLoading: false })) : null;
106
+ return (react_1.default.createElement(drawer_generic_1.DrawerGeneric, { direction: isRTL ? 'left' : 'right', filterDrawer: isFilterDrawer ? filterContent : null, filterDrawerFooter: filterFooter, filterDrawerHeader: filterHeader, formDrawer: isFormDrawer ? formContent : null, formDrawerFooter: formFooter, formDrawerHeader: formHeader, moreActionsDrawer: isMoreActionsDrawer ? moreActionsContent : null, moreActionsDrawerFooter: moreActionsFooter, moreActionsDrawerHeader: moreActionsHeader, onOpenChange: function (open) { return !open && closeDrawer(); }, open: isOpen, viewDrawer: isViewDrawer ? viewContent : null, viewDrawerFooter: viewFooter, viewDrawerHeader: viewHeader, width: (_g = config.size) !== null && _g !== void 0 ? _g : 'small' }));
154
107
  };
155
108
  exports.GenericDrawer = GenericDrawer;
156
109
  var createGenericModulePage = function (config) {
@@ -159,8 +112,7 @@ var createGenericModulePage = function (config) {
159
112
  return (react_1.default.createElement("div", { className: "space-y-6" },
160
113
  react_1.default.createElement(exports.GenericTable, { config: config, context: context, tableBodyCols: tableBodyCols, headerActions: headerActions, rowActions: rowActions, iconMap: iconMap }),
161
114
  react_1.default.createElement(exports.GenericDrawer, { config: config, context: context, formContent: config.formContent, viewContent: config.viewContent, filterContent: config.filterContent, moreActionsContent: config.moreActionsContent }),
162
- react_1.default.createElement(react_1.default.Suspense, { fallback: null },
163
- react_1.default.createElement(Toaster, null))));
115
+ react_1.default.createElement(sonner_1.Toaster, null)));
164
116
  };
165
117
  return GenericModulePage;
166
118
  };
@@ -1,11 +1,13 @@
1
1
  import { API_METHODS } from '../constants/api-methods';
2
+ export type FetchDataParamValue = string | number | boolean | null | undefined;
2
3
  export interface FetchDataParams {
3
4
  url: string;
4
5
  method?: API_METHODS;
5
6
  body?: string;
6
7
  headers?: Record<string, string>;
8
+ params?: Record<string, FetchDataParamValue>;
7
9
  }
8
- export declare const fetchData: ({ url, method, body, headers, }: FetchDataParams) => Promise<{
10
+ export declare const fetchData: ({ url, method, body, headers, params, }: FetchDataParams) => Promise<{
9
11
  data: any | undefined;
10
12
  error: Error | undefined;
11
13
  }>;
@@ -49,14 +49,29 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
49
49
  Object.defineProperty(exports, "__esModule", { value: true });
50
50
  exports.fetchData = void 0;
51
51
  var api_methods_1 = require("../constants/api-methods");
52
+ var buildUrl = function (url, params) {
53
+ if (!params)
54
+ return url;
55
+ var filteredEntries = Object.entries(params).filter(function (entry) {
56
+ return entry[1] !== null && entry[1] !== undefined;
57
+ });
58
+ if (filteredEntries.length === 0)
59
+ return url;
60
+ var searchParams = new URLSearchParams(filteredEntries.map(function (_a) {
61
+ var key = _a[0], value = _a[1];
62
+ return [key, String(value)];
63
+ }));
64
+ var separator = url.includes('?') ? '&' : '?';
65
+ return "".concat(url).concat(separator).concat(searchParams.toString());
66
+ };
52
67
  var fetchData = function (_a) { return __awaiter(void 0, [_a], void 0, function (_b) {
53
68
  var data, error, res, err_1;
54
- var url = _b.url, _c = _b.method, method = _c === void 0 ? api_methods_1.API_METHODS.GET : _c, body = _b.body, headers = _b.headers;
69
+ var url = _b.url, _c = _b.method, method = _c === void 0 ? api_methods_1.API_METHODS.GET : _c, body = _b.body, headers = _b.headers, params = _b.params;
55
70
  return __generator(this, function (_d) {
56
71
  switch (_d.label) {
57
72
  case 0:
58
73
  _d.trys.push([0, 3, , 4]);
59
- return [4 /*yield*/, fetch(url, __assign(__assign({ method: method }, (headers ? { headers: headers } : {})), (method !== api_methods_1.API_METHODS.GET && body && { body: body })))];
74
+ return [4 /*yield*/, fetch(buildUrl(url, params), __assign(__assign({ method: method }, (headers ? { headers: headers } : {})), (method !== api_methods_1.API_METHODS.GET && body && { body: body })))];
60
75
  case 1:
61
76
  res = _d.sent();
62
77
  return [4 /*yield*/, res.json()];
@@ -132,6 +132,27 @@ export declare const getCachedSingleItemSync: <T>(cacheKey: string, expirationMs
132
132
  * const workspace = await getCachedSingleItem<WorkspaceBE>(config, { subdomain: 'school1' });
133
133
  */
134
134
  export declare const getCachedSingleItem: <T>(config: CacheConfig, params?: Record<string, string>, headers?: Record<string, string>) => Promise<T | null>;
135
+ /**
136
+ * Get cached data but fall back to the API when sync cache is empty.
137
+ *
138
+ * This helper first performs a quick synchronous cache check via
139
+ * `getCachedDataSync`. If that returns an empty result it will call
140
+ * the async `getCachedData` to fetch fresh data from the API and return
141
+ * the result. Use this when callers want a fast-path cache read but also
142
+ * need the ability to recall the API transparently when cache is missing.
143
+ */
144
+ export declare const getCachedDataWithFallback: <T>(config: CacheConfig, params?: Record<string, unknown>, headers?: Record<string, string>) => Promise<ListResponse<T>>;
145
+ /**
146
+ * Async variant to get a single item by ID with API fallback.
147
+ *
148
+ * Unlike `getCachedItemById` (sync), this function will call the API
149
+ * (via `getCachedDataWithFallback`) when the item is not available in
150
+ * the local cache. Requires a full `CacheConfig` so the API URL is
151
+ * available for fetching.
152
+ */
153
+ export declare const getCachedItemByIdAsync: <T extends {
154
+ id: string;
155
+ }>(config: CacheConfig, itemId: string, params?: Record<string, unknown>, headers?: Record<string, string>) => Promise<T | null>;
135
156
  /**
136
157
  * Invalidate (remove) cache for a module
137
158
  * Useful after create/update/delete operations
@@ -72,7 +72,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
72
72
  }
73
73
  };
74
74
  Object.defineProperty(exports, "__esModule", { value: true });
75
- exports.isCacheStale = exports.preloadCache = exports.invalidateCache = exports.getCachedSingleItem = exports.getCachedSingleItemSync = exports.getCachedItemById = exports.getCachedData = exports.getCachedDataSync = void 0;
75
+ exports.isCacheStale = exports.preloadCache = exports.invalidateCache = exports.getCachedItemByIdAsync = exports.getCachedDataWithFallback = exports.getCachedSingleItem = exports.getCachedSingleItemSync = exports.getCachedItemById = exports.getCachedData = exports.getCachedDataSync = void 0;
76
76
  var constants_1 = require("../constants");
77
77
  var fetch_data_1 = require("./fetch-data");
78
78
  var local_storage_1 = require("../local-storage");
@@ -508,6 +508,86 @@ var getCachedSingleItem = function (config, params, headers) { return __awaiter(
508
508
  });
509
509
  }); };
510
510
  exports.getCachedSingleItem = getCachedSingleItem;
511
+ /**
512
+ * Get cached data but fall back to the API when sync cache is empty.
513
+ *
514
+ * This helper first performs a quick synchronous cache check via
515
+ * `getCachedDataSync`. If that returns an empty result it will call
516
+ * the async `getCachedData` to fetch fresh data from the API and return
517
+ * the result. Use this when callers want a fast-path cache read but also
518
+ * need the ability to recall the API transparently when cache is missing.
519
+ */
520
+ var getCachedDataWithFallback = function (config, params, headers) { return __awaiter(void 0, void 0, void 0, function () {
521
+ var expirationMs, sync, error_3;
522
+ var _a;
523
+ return __generator(this, function (_b) {
524
+ switch (_b.label) {
525
+ case 0:
526
+ expirationMs = (_a = config.expirationMs) !== null && _a !== void 0 ? _a : constants_1.ONE_DAY_IN_MS;
527
+ _b.label = 1;
528
+ case 1:
529
+ _b.trys.push([1, 3, , 4]);
530
+ sync = (0, exports.getCachedDataSync)(config.cacheKey, expirationMs);
531
+ if (sync &&
532
+ sync.count > 0 &&
533
+ Array.isArray(sync.items) &&
534
+ sync.items.length > 0) {
535
+ return [2 /*return*/, sync];
536
+ }
537
+ return [4 /*yield*/, (0, exports.getCachedData)({ config: config, params: params, headers: headers })];
538
+ case 2:
539
+ // Sync cache empty — fetch from API and return result
540
+ return [2 /*return*/, _b.sent()];
541
+ case 3:
542
+ error_3 = _b.sent();
543
+ console.error("Error in getCachedDataWithFallback for ".concat(config.cacheKey, ":"), error_3);
544
+ return [2 /*return*/, { count: 0, items: [] }];
545
+ case 4: return [2 /*return*/];
546
+ }
547
+ });
548
+ }); };
549
+ exports.getCachedDataWithFallback = getCachedDataWithFallback;
550
+ /**
551
+ * Async variant to get a single item by ID with API fallback.
552
+ *
553
+ * Unlike `getCachedItemById` (sync), this function will call the API
554
+ * (via `getCachedDataWithFallback`) when the item is not available in
555
+ * the local cache. Requires a full `CacheConfig` so the API URL is
556
+ * available for fetching.
557
+ */
558
+ var getCachedItemByIdAsync = function (config, itemId, params, headers) { return __awaiter(void 0, void 0, void 0, function () {
559
+ var raw, found, list, error_4;
560
+ return __generator(this, function (_a) {
561
+ switch (_a.label) {
562
+ case 0:
563
+ if (!itemId)
564
+ return [2 /*return*/, null];
565
+ _a.label = 1;
566
+ case 1:
567
+ _a.trys.push([1, 3, , 4]);
568
+ raw = (0, local_storage_1.getStorageValue)(config.cacheKey);
569
+ if (isCachedArrayShape(raw)) {
570
+ found = raw.items.find(function (i) { return i.id === itemId; });
571
+ if (found)
572
+ return [2 /*return*/, found];
573
+ }
574
+ if (isCachedMapShape(raw)) {
575
+ if (raw.items && raw.items[itemId])
576
+ return [2 /*return*/, raw.items[itemId]];
577
+ }
578
+ return [4 /*yield*/, (0, exports.getCachedDataWithFallback)(config, params, headers)];
579
+ case 2:
580
+ list = _a.sent();
581
+ return [2 /*return*/, list.items.find(function (i) { return i.id === itemId; }) || null];
582
+ case 3:
583
+ error_4 = _a.sent();
584
+ console.error("Error in getCachedItemByIdAsync for ".concat(config.cacheKey, ":"), error_4);
585
+ return [2 /*return*/, null];
586
+ case 4: return [2 /*return*/];
587
+ }
588
+ });
589
+ }); };
590
+ exports.getCachedItemByIdAsync = getCachedItemByIdAsync;
511
591
  // ============================================================================
512
592
  // CACHE UTILITIES
513
593
  // ============================================================================
package/index.d.ts CHANGED
@@ -23,7 +23,6 @@ export * from './api/stellar-solutions/quote-invoice';
23
23
  export * from './api/stellar-solutions/tax';
24
24
  export * from './api/stellar-solutions/type';
25
25
  export * from './constants';
26
- export * from './factory';
27
26
  export * from './general';
28
27
  export * from './hooks';
29
28
  export * from './local-storage';
package/index.js CHANGED
@@ -39,7 +39,6 @@ __exportStar(require("./api/stellar-solutions/quote-invoice"), exports);
39
39
  __exportStar(require("./api/stellar-solutions/tax"), exports);
40
40
  __exportStar(require("./api/stellar-solutions/type"), exports);
41
41
  __exportStar(require("./constants"), exports);
42
- __exportStar(require("./factory"), exports);
43
42
  __exportStar(require("./general"), exports);
44
43
  __exportStar(require("./hooks"), exports);
45
44
  __exportStar(require("./local-storage"), exports);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-pakistan/util-functions",
3
- "version": "1.25.38",
3
+ "version": "1.25.40",
4
4
  "description": "A library of all util functions",
5
5
  "main": "index.js",
6
6
  "scripts": {