Skip to content

Commit 7160fd9

Browse files
committed
optimisations #1272
1 parent 5212be4 commit 7160fd9

File tree

2 files changed

+239
-62
lines changed

2 files changed

+239
-62
lines changed

src/api/systems.tsx

Lines changed: 105 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -95,18 +95,74 @@ export interface SystemTree extends Partial<System> {
9595
subsystems?: SystemTree[];
9696
}
9797

98-
const getSystemTree = async (parent_id: string): Promise<SystemTree[]> => {
99-
// Fetch the systems at the current level
98+
const getSystemTree = async (
99+
parent_id: string,
100+
maxSubsystems: number, // Total max subsystems allowed
101+
maxDepth?: number,
102+
currentDepth: number = 0, // Default value
103+
subsystemsCutOffPoint?: number, // Total cutoff point
104+
totalSubsystems: { count: number } = { count: 0 }, // Shared counter object
105+
catalogueItemCache: Map<string, CatalogueItem> = new Map() // Shared cache for catalogue items
106+
): Promise<SystemTree[]> => {
107+
// Stop recursion if currentDepth exceeds maxDepth
108+
if (maxDepth !== undefined && currentDepth >= maxDepth) {
109+
return [];
110+
}
100111

112+
// Fetch the root system
101113
const rootSystem = await getSystem(parent_id);
102114

115+
// Fetch systems at the current level
103116
const systems = await getSystems(parent_id || 'null');
104117

118+
// Increment the total count of subsystems
119+
totalSubsystems.count += systems.length;
120+
121+
// Throw an AxiosError if the total count exceeds maxSubsystems
122+
if (maxSubsystems !== undefined && totalSubsystems.count > maxSubsystems) {
123+
throw new AxiosError(
124+
`Total subsystems exceeded the maximum allowed limit of ${maxSubsystems}. Current count: ${totalSubsystems.count}`,
125+
'SubsystemLimitExceeded',
126+
undefined,
127+
null,
128+
{
129+
status: 400,
130+
statusText: 'Bad Request',
131+
headers: {},
132+
// @ts-expect-error: not needed
133+
config: {},
134+
data: {
135+
message: `Subsystem limit exceeded. Max: ${maxSubsystems}, Current: ${totalSubsystems.count}`,
136+
},
137+
}
138+
);
139+
}
140+
141+
// Stop recursion if totalSubsystems count exceeds the cutoff point
142+
if (
143+
subsystemsCutOffPoint !== undefined &&
144+
totalSubsystems.count > subsystemsCutOffPoint
145+
) {
146+
return systems.map((system) => ({
147+
...system,
148+
subsystems: [],
149+
catalogueItems: [],
150+
}));
151+
}
152+
105153
// Fetch subsystems and catalogue items for each system recursively
106154
const systemsWithTree: SystemTree[] = await Promise.all(
107155
systems.map(async (system) => {
108-
// Fetch subsystems recursively
109-
const subsystems = await getSystemTree(system.id);
156+
// Fetch subsystems recursively, increasing the depth
157+
const subsystems = await getSystemTree(
158+
system.id,
159+
maxSubsystems,
160+
maxDepth,
161+
currentDepth + 1,
162+
subsystemsCutOffPoint,
163+
totalSubsystems,
164+
catalogueItemCache
165+
);
110166

111167
// Fetch all items for the current system
112168
const items = await getItems(system.id);
@@ -118,7 +174,15 @@ const getSystemTree = async (parent_id: string): Promise<SystemTree[]> => {
118174

119175
const catalogueItems: SystemTree['catalogueItems'] = await Promise.all(
120176
Array.from(catalogueItemIdSet).map(async (id) => {
121-
const catalogueItem = await getCatalogueItem(id);
177+
// Check if the item exists in the cache
178+
if (!catalogueItemCache.has(id)) {
179+
// If not, fetch and store it in the cache
180+
const fetchedCatalogueItem = await getCatalogueItem(id);
181+
catalogueItemCache.set(id, fetchedCatalogueItem);
182+
}
183+
184+
// Retrieve the item from the cache
185+
const catalogueItem = catalogueItemCache.get(id)!;
122186
const categoryItems = items.filter(
123187
(item) => item.catalogue_item_id === id
124188
);
@@ -131,7 +195,6 @@ const getSystemTree = async (parent_id: string): Promise<SystemTree[]> => {
131195
);
132196

133197
// Handle the case when there are no systems (leaf nodes or empty levels)
134-
135198
const items = await getItems(parent_id);
136199

137200
// Group items into catalogue categories and fetch catalogue item details
@@ -141,23 +204,54 @@ const getSystemTree = async (parent_id: string): Promise<SystemTree[]> => {
141204

142205
const catalogueItems: SystemTree['catalogueItems'] = await Promise.all(
143206
Array.from(catalogueItemIdSet).map(async (id) => {
144-
const catalogueItem = await getCatalogueItem(id);
207+
// Check if the item exists in the cache
208+
if (!catalogueItemCache.has(id)) {
209+
// If not, fetch and store it in the cache
210+
const fetchedCatalogueItem = await getCatalogueItem(id);
211+
catalogueItemCache.set(id, fetchedCatalogueItem);
212+
}
213+
214+
// Retrieve the item from the cache
215+
const catalogueItem = catalogueItemCache.get(id)!;
145216
const categoryItems = items.filter(
146217
(item) => item.catalogue_item_id === id
147218
);
148219
return { ...catalogueItem, itemsQuantity: categoryItems.length };
149220
})
150221
);
151222

152-
return [{ ...rootSystem, catalogueItems, subsystems: systemsWithTree }];
223+
return [
224+
{
225+
...rootSystem,
226+
catalogueItems,
227+
subsystems: systemsWithTree,
228+
},
229+
];
153230
};
154231

155232
export const useGetSystemsTree = (
156-
parent_id?: string | null
233+
parent_id?: string | null,
234+
maxDepth?: number,
235+
subsystemsCutOffPoint?: number, // Add cutoff point as a parameter
236+
maxSubsystems?: number
157237
): UseQueryResult<SystemTree[], AxiosError> => {
158238
return useQuery({
159-
queryKey: ['SystemsTree', parent_id],
160-
queryFn: () => getSystemTree(parent_id ?? ''),
239+
queryKey: [
240+
'SystemsTree',
241+
parent_id,
242+
maxSubsystems,
243+
maxDepth,
244+
subsystemsCutOffPoint,
245+
],
246+
queryFn: () =>
247+
getSystemTree(
248+
parent_id ?? '',
249+
maxSubsystems ?? 150,
250+
maxDepth,
251+
0,
252+
subsystemsCutOffPoint
253+
),
254+
staleTime: 1000 * 60 * 5,
161255
});
162256
};
163257

0 commit comments

Comments
 (0)