@zeniai/client-epic-state 5.0.24 → 5.0.25-beta0ND

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.
Files changed (26) hide show
  1. package/lib/esm/index.js +2 -1
  2. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +6 -2
  3. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +7 -2
  4. package/lib/esm/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +5 -5
  5. package/lib/esm/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +7 -3
  6. package/lib/esm/view/expenseAutomationView/selectors/missingReceiptsSelector.js +2 -0
  7. package/lib/esm/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +42 -0
  8. package/lib/esm/view/reportUIOptions/reportUIOptionsReducer.js +1 -1
  9. package/lib/esm/view/spendManagement/zeniAccounts/zeniAccountList/zeniAccountListSelector.js +3 -1
  10. package/lib/index.d.ts +2 -1
  11. package/lib/index.js +28 -26
  12. package/lib/tsconfig.typecheck.tsbuildinfo +1 -1
  13. package/lib/view/expenseAutomationView/epics/missingReceipts/fetchCompletedTransactionsEpic.js +6 -2
  14. package/lib/view/expenseAutomationView/epics/missingReceipts/searchTransactionsForManualMatchEpic.js +7 -2
  15. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.d.ts +6 -4
  16. package/lib/view/expenseAutomationView/epics/missingReceipts/watchBulkUploadBatchStatusEpic.js +4 -4
  17. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.d.ts +7 -7
  18. package/lib/view/expenseAutomationView/reducers/missingReceiptsViewReducer.js +7 -3
  19. package/lib/view/expenseAutomationView/selectorTypes/missingReceiptsSelectorTypes.d.ts +4 -2
  20. package/lib/view/expenseAutomationView/selectors/missingReceiptsSelector.js +2 -0
  21. package/lib/view/expenseAutomationView/types/missingReceiptsViewState.d.ts +2 -2
  22. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.d.ts +15 -1
  23. package/lib/view/profitAndLossClassesView/profitAndLossHorizontalEnrichment.js +43 -0
  24. package/lib/view/reportUIOptions/reportUIOptionsReducer.js +1 -1
  25. package/lib/view/spendManagement/zeniAccounts/zeniAccountList/zeniAccountListSelector.js +3 -1
  26. package/package.json +1 -1
@@ -33,11 +33,15 @@ const fetchCompletedTransactionsEpic = (actions$, state$, zeniAPI) => actions$.p
33
33
  const queryPayload = {
34
34
  start_date: period.start,
35
35
  end_date: period.end,
36
- sort_by: sortKey,
37
- sort_order: sortOrder === 'ascending' ? 'asc' : 'desc',
38
36
  page_token: action.payload.pageToken ?? null,
39
37
  page_size: 25,
40
38
  };
39
+ if (sortKey != null) {
40
+ queryPayload.sort_by = sortKey;
41
+ }
42
+ if (sortOrder != null) {
43
+ queryPayload.sort_order = sortOrder === 'ascending' ? 'asc' : 'desc';
44
+ }
41
45
  if (completedSubTab !== 'all') {
42
46
  queryPayload.match_type = completedSubTab;
43
47
  }
@@ -35,12 +35,17 @@ const searchTransactionsForManualMatchEpic = (actions$, state$, zeniAPI) => {
35
35
  const state = state$.value;
36
36
  const { expenseAutomationMissingReceiptsViewState: { bulkUpload: { manualSearch, sortKey, sortOrder }, }, } = state;
37
37
  const { end, start } = (0, rollingCalendarDateRangeInclusive_1.rollingCalendarDateRangeInclusive)(MANUAL_SEARCH_TRANSACTION_DATE_RANGE_DAYS);
38
+ // Manual search is independent of the Completed tab's optional sort: when the
39
+ // bulk upload sort is neutral (no user-applied sort), fall back to date/desc so
40
+ // search results stay deterministic for the matching UX.
41
+ const manualSearchSortKey = sortKey ?? 'date';
42
+ const manualSearchSortOrder = sortOrder ?? 'descending';
38
43
  const queryParam = {
39
44
  start_date: start,
40
45
  end_date: end,
41
46
  auto_categorized: exports.MANUAL_TRANSACTION_SEARCH_AUTO_CATEGORIZED,
42
- sort_by: (0, transactionsViewState_1.toTransactionsSortKey)(sortKey),
43
- sort_order: sortOrder === 'ascending' ? 'asc' : 'desc',
47
+ sort_by: (0, transactionsViewState_1.toTransactionsSortKey)(manualSearchSortKey),
48
+ sort_order: manualSearchSortOrder === 'ascending' ? 'asc' : 'desc',
44
49
  page_token: pageToken ?? null,
45
50
  page_size: manualSearch.pageSize,
46
51
  search_text: query,
@@ -4,11 +4,13 @@ import { openSnackbar } from '../../../../entity/snackbar/snackbarReducer';
4
4
  import { updateTransactions } from '../../../../entity/transaction/transactionReducer';
5
5
  import { RootState } from '../../../../reducer';
6
6
  import { ZeniAPI } from '../../../../zeniAPI';
7
- import { bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, pusherBatchStatusUpdate, requestMissingReceiptsTabNavigation, restoreBulkUploadMatchingState } from '../../reducers/missingReceiptsViewReducer';
8
- export type ActionType = ReturnType<typeof bulkUploadReceiptsSuccess> | ReturnType<typeof restoreBulkUploadMatchingState> | ReturnType<typeof pusherBatchStatusUpdate> | ReturnType<typeof fetchBulkUploadBatchDetails> | ReturnType<typeof fetchBulkUploadBatchDetailsSuccess> | ReturnType<typeof fetchBulkUploadBatches> | ReturnType<typeof requestMissingReceiptsTabNavigation> | ReturnType<typeof updateTransactions> | ReturnType<typeof clearBulkUpload> | ReturnType<typeof openSnackbar> | ReturnType<typeof bulkUploadAutomatchingTimedOut>;
7
+ import { bulkUploadAutomatchingTimedOut, bulkUploadReceiptsSuccess, clearBulkUpload, fetchBulkUploadBatchDetails, fetchBulkUploadBatchDetailsSuccess, fetchBulkUploadBatches, pusherBatchStatusUpdate, restoreBulkUploadMatchingState } from '../../reducers/missingReceiptsViewReducer';
8
+ export type ActionType = ReturnType<typeof bulkUploadReceiptsSuccess> | ReturnType<typeof restoreBulkUploadMatchingState> | ReturnType<typeof pusherBatchStatusUpdate> | ReturnType<typeof fetchBulkUploadBatchDetails> | ReturnType<typeof fetchBulkUploadBatchDetailsSuccess> | ReturnType<typeof fetchBulkUploadBatches> | ReturnType<typeof updateTransactions> | ReturnType<typeof clearBulkUpload> | ReturnType<typeof openSnackbar> | ReturnType<typeof bulkUploadAutomatchingTimedOut>;
9
9
  /**
10
- * On Pusher batch completion: refresh batch list (then fetchMultipleBatchDetailsEpic runs),
11
- * and request switching to the Unmatched tab. Debounced to reduce duplicate refreshes.
10
+ * On Pusher batch completion: refresh batch list (then fetchMultipleBatchDetailsEpic runs).
11
+ * Debounced to reduce duplicate refreshes. The post-match tab decision
12
+ * (Unmatched vs Completed) is made client-side in `ExpenseAutomationPage` once fresh
13
+ * batch details land -- do not dispatch `requestMissingReceiptsTabNavigation` here.
12
14
  */
13
15
  export declare const pusherBatchStatusCompletionEpic: (actions$: ActionsObservable<ActionType>) => Observable<ActionType>;
14
16
  /**
@@ -15,15 +15,16 @@ const FALLBACK_FIRST_DELAY_MS = 30000;
15
15
  const RESTORE_FIRST_DELAY_MS = 5000;
16
16
  const FALLBACK_POLL_INTERVAL_MS = 10000;
17
17
  /**
18
- * On Pusher batch completion: refresh batch list (then fetchMultipleBatchDetailsEpic runs),
19
- * and request switching to the Unmatched tab. Debounced to reduce duplicate refreshes.
18
+ * On Pusher batch completion: refresh batch list (then fetchMultipleBatchDetailsEpic runs).
19
+ * Debounced to reduce duplicate refreshes. The post-match tab decision
20
+ * (Unmatched vs Completed) is made client-side in `ExpenseAutomationPage` once fresh
21
+ * batch details land -- do not dispatch `requestMissingReceiptsTabNavigation` here.
20
22
  */
21
23
  const pusherBatchStatusCompletionEpic = (actions$) => actions$.pipe((0, operators_1.filter)(missingReceiptsViewReducer_1.pusherBatchStatusUpdate.match), (0, operators_1.filter)((action) => action.payload.status === 'completed'), (0, operators_1.debounceTime)(300), (0, operators_1.mergeMap)(() => (0, rxjs_1.from)([
22
24
  (0, missingReceiptsViewReducer_1.fetchBulkUploadBatches)({
23
25
  cacheOverride: true,
24
26
  invalidateBatchDetailsCache: true,
25
27
  }),
26
- (0, missingReceiptsViewReducer_1.requestMissingReceiptsTabNavigation)({ tab: 'unmatched' }),
27
28
  ])));
28
29
  exports.pusherBatchStatusCompletionEpic = pusherBatchStatusCompletionEpic;
29
30
  /**
@@ -81,7 +82,6 @@ const pollBulkUploadBatchStatusEpic = (actions$, _state$, zeniAPI) => actions$.p
81
82
  }
82
83
  actions.push((0, missingReceiptsViewReducer_1.fetchBulkUploadBatchDetailsSuccess)((0, missingReceiptsPayload_1.toBatchDetails)(response.data, zeniAPI.apiEndPoints.fileMicroServiceBaseUrl)));
83
84
  actions.push((0, missingReceiptsViewReducer_1.fetchBulkUploadBatches)({ cacheOverride: true }));
84
- actions.push((0, missingReceiptsViewReducer_1.requestMissingReceiptsTabNavigation)({ tab: 'unmatched' }));
85
85
  return (0, rxjs_1.from)(actions);
86
86
  }
87
87
  }
@@ -7,7 +7,7 @@ import { TransactionPayload } from '../../../entity/transaction/payloadTypes/tra
7
7
  import { SupportedTransactionPayload } from '../../../entity/transaction/transactionState';
8
8
  import { ZeniAPIStatus } from '../../../responsePayload';
9
9
  import { type BatchDetails, type BatchListItem, type BatchStatus, type BulkUploadResultsTab, type BulkUploadSortKey, type BulkUploadState, type CompletedSubTab, type ManualSearchResult, type MissingReceiptsViewState, type MissingReceiptsViewUIState } from '../types/missingReceiptsViewState';
10
- export declare const getCompletedTransactionsCacheKey: (periodId: MonthYearPeriodId, sortKey: BulkUploadSortKey, sortOrder: SortOrder, subTab: CompletedSubTab) => string;
10
+ export declare const getCompletedTransactionsCacheKey: (periodId: MonthYearPeriodId, sortKey: BulkUploadSortKey | undefined, sortOrder: SortOrder | undefined, subTab: CompletedSubTab) => string;
11
11
  export declare const initialBulkUploadState: BulkUploadState;
12
12
  export declare const initialState: MissingReceiptsViewState;
13
13
  /** Epic trigger only; batch-details fetch is handled in epics. */
@@ -85,8 +85,8 @@ export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCrea
85
85
  }, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchSuccess">, confirmBulkUploadMatchFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
86
86
  error: ZeniAPIStatus;
87
87
  }, "expenseAutomationMissingReceiptsView/confirmBulkUploadMatchFailure">, setBulkUploadResultsTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"completed" | "unmatched", "expenseAutomationMissingReceiptsView/setBulkUploadResultsTab">, setBulkUploadCompletedSubTab: import("@reduxjs/toolkit").ActionCreatorWithPayload<"all" | "manual" | "ai_accountant", "expenseAutomationMissingReceiptsView/setBulkUploadCompletedSubTab">, setBulkUploadSortConfig: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
88
- sortKey: BulkUploadSortKey;
89
- sortOrder: SortOrder;
88
+ sortKey: BulkUploadSortKey | undefined;
89
+ sortOrder: SortOrder | undefined;
90
90
  }, "expenseAutomationMissingReceiptsView/setBulkUploadSortConfig">, clearBulkUpload: import("@reduxjs/toolkit").ActionCreatorWithoutPayload<"expenseAutomationMissingReceiptsView/clearBulkUpload">, searchTransactionsForManualMatch: import("@reduxjs/toolkit").ActionCreatorWithPreparedPayload<[query: string, pageToken?: string | null | undefined], {
91
91
  query: string;
92
92
  pageToken: string | undefined;
@@ -105,16 +105,16 @@ export declare const fetchMissingReceipts: import("@reduxjs/toolkit").ActionCrea
105
105
  isInitialLoad: boolean;
106
106
  nextPageToken: string | null;
107
107
  selectedPeriod: MonthYearPeriod;
108
- sortKey: BulkUploadSortKey;
109
- sortOrder: SortOrder;
108
+ sortKey: BulkUploadSortKey | undefined;
109
+ sortOrder: SortOrder | undefined;
110
110
  totalCount: number;
111
111
  transactionIds: ID[];
112
112
  }, "expenseAutomationMissingReceiptsView/fetchCompletedTransactionsSuccess">, fetchCompletedTransactionsFailure: import("@reduxjs/toolkit").ActionCreatorWithPayload<{
113
113
  completedSubTab: CompletedSubTab;
114
114
  error: ZeniAPIStatus;
115
115
  selectedPeriod: MonthYearPeriod;
116
- sortKey: BulkUploadSortKey;
117
- sortOrder: SortOrder;
116
+ sortKey: BulkUploadSortKey | undefined;
117
+ sortOrder: SortOrder | undefined;
118
118
  }, "expenseAutomationMissingReceiptsView/fetchCompletedTransactionsFailure">;
119
119
  declare const _default: import("redux").Reducer<MissingReceiptsViewState>;
120
120
  export default _default;
@@ -5,7 +5,11 @@ exports.fetchCompletedTransactionsFailure = exports.fetchCompletedTransactionsSu
5
5
  const toolkit_1 = require("@reduxjs/toolkit");
6
6
  const timePeriod_1 = require("../../../commonStateTypes/timePeriod");
7
7
  const missingReceiptsViewState_1 = require("../types/missingReceiptsViewState");
8
- const getCompletedTransactionsCacheKey = (periodId, sortKey, sortOrder, subTab) => `completed-${subTab}-${sortKey}-${sortOrder === 'ascending' ? 'asc' : 'desc'}-${periodId}`;
8
+ const getCompletedTransactionsCacheKey = (periodId, sortKey, sortOrder, subTab) => {
9
+ const sortKeyPart = sortKey ?? 'none';
10
+ const sortOrderPart = sortOrder == null ? 'none' : sortOrder === 'ascending' ? 'asc' : 'desc';
11
+ return `completed-${subTab}-${sortKeyPart}-${sortOrderPart}-${periodId}`;
12
+ };
9
13
  exports.getCompletedTransactionsCacheKey = getCompletedTransactionsCacheKey;
10
14
  exports.initialBulkUploadState = {
11
15
  batchDetailsById: {},
@@ -30,8 +34,8 @@ exports.initialBulkUploadState = {
30
34
  totalCount: 0,
31
35
  },
32
36
  phase: 'idle',
33
- sortKey: 'date',
34
- sortOrder: 'descending',
37
+ sortKey: undefined,
38
+ sortOrder: undefined,
35
39
  uploadedFileCount: 0,
36
40
  uploadProgress: 0,
37
41
  uploadStatus: { fetchState: 'Not-Started', error: undefined },
@@ -48,12 +48,14 @@ export interface BulkUploadSelectorData {
48
48
  processed: number;
49
49
  total: number;
50
50
  };
51
- sortKey: BulkUploadSortKey;
52
- sortOrder: SortOrder;
51
+ sortKey: BulkUploadSortKey | undefined;
52
+ sortOrder: SortOrder | undefined;
53
53
  unmatchedFiles: ResolvedBatchFile[];
54
54
  uploadedFileCount: number;
55
55
  uploadProgress: number;
56
56
  uploadStatus: FetchStateAndError;
57
+ /** True iff `batchDetailsById[currentBatchId]` is populated -- signals post-match data is fresh. */
58
+ currentBatchDetailsFetched?: boolean;
57
59
  currentBatchId?: ID;
58
60
  }
59
61
  export interface ResolvedBatchDetails {
@@ -205,6 +205,8 @@ function getExpenseAutomationMissingReceiptsView(state) {
205
205
  batchDetails: resolvedBatchDetails,
206
206
  completedSubTab: bulkUpload.completedSubTab,
207
207
  currentBatchId: bulkUpload.currentBatchId,
208
+ currentBatchDetailsFetched: bulkUpload.currentBatchId != null &&
209
+ bulkUpload.batchDetailsById[bulkUpload.currentBatchId] != null,
208
210
  completedTransactions: {
209
211
  fetchState: completedTransactionsForPeriod?.fetchState ?? {
210
212
  fetchState: 'Not-Started',
@@ -145,8 +145,8 @@ export interface BulkUploadState {
145
145
  manualSearch: ManualSearchState;
146
146
  manualSearchUiResetKey: number;
147
147
  phase: BulkUploadPhase;
148
- sortKey: BulkUploadSortKey;
149
- sortOrder: SortOrder;
148
+ sortKey: BulkUploadSortKey | undefined;
149
+ sortOrder: SortOrder | undefined;
150
150
  uploadedFileCount: number;
151
151
  uploadProgress: number;
152
152
  uploadStatus: FetchStateAndError;
@@ -1,6 +1,20 @@
1
- import { ProfitAndLossByClassHorizontalReport } from './profitAndLossClassesByClassHorizontalSelectorTypes';
1
+ import { COABalance } from '../../commonStateTypes/coaBalance/coaBalance';
2
+ import { HorizontalAccountRow, ProfitAndLossByClassHorizontalReport } from './profitAndLossClassesByClassHorizontalSelectorTypes';
2
3
  /**
3
4
  * Populates `sectionHeaderBalancesSlice`, and per-account `accountReportData`, so the
4
5
  * web layer only maps selector output to tree nodes.
5
6
  */
6
7
  export declare function enrichProfitAndLossByClassHorizontalReport(report: ProfitAndLossByClassHorizontalReport): void;
8
+ /**
9
+ * Sum balances across descendant accounts (recursive).
10
+ *
11
+ * Parent rows in the horizontal pivot only carry their own direct postings
12
+ * (zero for "container" accounts), so callers rendering "Total {parent}" rows
13
+ * must aggregate from descendants to get the real per-class totals.
14
+ *
15
+ * Returns one `COABalance` per class column + total (same shape as the
16
+ * enriched `balancesInTimeframe.balances`), with `amount` summed and `type`
17
+ * set to `default_with_null_balance` for zeros. Returns `[]` when no
18
+ * descendants have enriched data.
19
+ */
20
+ export declare function aggregateHorizontalDescendantBalances(accounts: readonly HorizontalAccountRow[], childIndices: readonly number[], childrenByParent: Readonly<Record<number, readonly number[]>>): COABalance[];
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.enrichProfitAndLossByClassHorizontalReport = enrichProfitAndLossByClassHorizontalReport;
4
+ exports.aggregateHorizontalDescendantBalances = aggregateHorizontalDescendantBalances;
4
5
  const currencyHelper_1 = require("../../commonStateTypes/currencyHelper");
5
6
  const horizontalSectionEmptyBalancesSlice_1 = require("./horizontalSectionEmptyBalancesSlice");
6
7
  const profitAndLossClassesByClassHorizontalSelectorTypes_1 = require("./profitAndLossClassesByClassHorizontalSelectorTypes");
@@ -118,6 +119,48 @@ function buildHorizontalClassColumnBalancesSlice(report, classAmounts, totalAmou
118
119
  },
119
120
  };
120
121
  }
122
+ /**
123
+ * Sum balances across descendant accounts (recursive).
124
+ *
125
+ * Parent rows in the horizontal pivot only carry their own direct postings
126
+ * (zero for "container" accounts), so callers rendering "Total {parent}" rows
127
+ * must aggregate from descendants to get the real per-class totals.
128
+ *
129
+ * Returns one `COABalance` per class column + total (same shape as the
130
+ * enriched `balancesInTimeframe.balances`), with `amount` summed and `type`
131
+ * set to `default_with_null_balance` for zeros. Returns `[]` when no
132
+ * descendants have enriched data.
133
+ */
134
+ function aggregateHorizontalDescendantBalances(accounts, childIndices, childrenByParent) {
135
+ let template;
136
+ const sums = new Map();
137
+ const walk = (idx) => {
138
+ const childRow = accounts[idx];
139
+ const childBalances = childRow?.accountReportData?.balancesInTimeframe.balances;
140
+ if (childBalances != null) {
141
+ if (template == null) {
142
+ template = childBalances;
143
+ }
144
+ childBalances.forEach((b, i) => {
145
+ sums.set(i, (sums.get(i) ?? 0) + (b.balance.amount ?? 0));
146
+ });
147
+ const grandChildren = childrenByParent[idx] ?? [];
148
+ grandChildren.forEach(walk);
149
+ }
150
+ };
151
+ childIndices.forEach(walk);
152
+ if (template == null) {
153
+ return [];
154
+ }
155
+ return template.map((tpl, i) => {
156
+ const amount = sums.get(i) ?? 0;
157
+ return {
158
+ ...tpl,
159
+ balance: { ...tpl.balance, amount },
160
+ type: amount === 0 ? 'default_with_null_balance' : 'default',
161
+ };
162
+ });
163
+ }
121
164
  /**
122
165
  * Parent index per DFS row — O(n). Matches the scan in the former
123
166
  * `findHorizontalAccountParentIndex` (depth &lt;= 2 rows have no parent).
@@ -7,7 +7,7 @@ exports.initialState = {
7
7
  timeframe: 'month',
8
8
  thisPeriod: undefined,
9
9
  balancesOrder: 'ascending_date',
10
- isCompareModeOn: true,
10
+ isCompareModeOn: false,
11
11
  maxNumOfPeriodsToHighlight: 0,
12
12
  compareMode: 'compare_mode_percent',
13
13
  selectedForecast: undefined,
@@ -14,7 +14,9 @@ const getZeniAccountList = (state) => {
14
14
  ...baseDepositAccountsSelectorView,
15
15
  depositAccounts: baseDepositAccountsSelectorView.depositAccounts.map((depositAccount) => ({
16
16
  ...depositAccount,
17
- autoTransferRules: autotransferRulesState.rules.filter((rule) => !rule.isDeleted && rule.sourceBankAccountId === depositAccount.id),
17
+ autoTransferRules: autotransferRulesState.rules.filter((rule) => !rule.isDeleted &&
18
+ rule.isActive &&
19
+ rule.sourceBankAccountId === depositAccount.id),
18
20
  })),
19
21
  };
20
22
  const zeniAccountsConfig = (0, zeniAccountsConfigSelector_1.getZeniAccountsConfigDetail)(state);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zeniai/client-epic-state",
3
- "version": "5.0.24",
3
+ "version": "5.0.25-beta0ND",
4
4
  "description": "Shared module between Web & Mobile containing required abstractions for state management, async network communication. ",
5
5
  "main": "lib/index.js",
6
6
  "module": "lib/esm/index.js",