@mohsinonxrm/pptb-fetchxml-studio 1.0.0 → 1.0.2
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.
- package/LICENSE +661 -0
- package/README.md +1 -1
- package/dist/assets/index-DD9fzkbz.js +232 -0
- package/dist/index.html +70 -0
- package/index.html +0 -1
- package/npm-shrinkwrap.json +6329 -0
- package/package.json +95 -51
- package/CHANGELOG.md +0 -120
- package/eslint.config.js +0 -23
- package/public/vite.svg +0 -1
- package/src/app/AppShell.tsx +0 -1733
- package/src/assets/20px-Microsoft_Office_Excel_(2025/342/200/223present).svg.png +0 -0
- package/src/assets/react.svg +0 -1
- package/src/features/fetchxml/api/dataverseMetadata.ts +0 -192
- package/src/features/fetchxml/api/excelExport.ts +0 -318
- package/src/features/fetchxml/api/formattedValues.ts +0 -107
- package/src/features/fetchxml/api/pptbClient.ts +0 -2635
- package/src/features/fetchxml/model/displaySettings.ts +0 -18
- package/src/features/fetchxml/model/fetchxml.ts +0 -346
- package/src/features/fetchxml/model/fetchxmlIntellisense.ts +0 -583
- package/src/features/fetchxml/model/fetchxmlParser.ts +0 -708
- package/src/features/fetchxml/model/layoutxml.ts +0 -372
- package/src/features/fetchxml/model/nodes.ts +0 -255
- package/src/features/fetchxml/model/operators.ts +0 -624
- package/src/features/fetchxml/model/treeUtils.ts +0 -174
- package/src/features/fetchxml/state/builderStore.tsx +0 -1160
- package/src/features/fetchxml/state/cache.ts +0 -393
- package/src/features/fetchxml/ui/Dialogs/BulkDeleteDialog.tsx +0 -352
- package/src/features/fetchxml/ui/Dialogs/DeleteConfirmDialog.tsx +0 -396
- package/src/features/fetchxml/ui/Dialogs/SaveViewDialog.tsx +0 -612
- package/src/features/fetchxml/ui/Dialogs/SolutionPicker.tsx +0 -114
- package/src/features/fetchxml/ui/Dialogs/WorkflowPickerDialog.tsx +0 -437
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/AttributeEditor.tsx +0 -214
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ConditionEditor.tsx +0 -533
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FetchOptionsEditor.tsx +0 -296
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/FilterEditor.tsx +0 -106
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/LinkEntityEditor.tsx +0 -433
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/OrderEditor.tsx +0 -161
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel/editors/ValueOfPicker.tsx +0 -194
- package/src/features/fetchxml/ui/LeftPane/PropertiesPanel.tsx +0 -225
- package/src/features/fetchxml/ui/LeftPane/TreeView.tsx +0 -604
- package/src/features/fetchxml/ui/RightPane/AddColumnsPanel.tsx +0 -800
- package/src/features/fetchxml/ui/RightPane/ColumnConfigDialog.tsx +0 -170
- package/src/features/fetchxml/ui/RightPane/DataGridCellRenderers.tsx +0 -356
- package/src/features/fetchxml/ui/RightPane/EditColumnsPanel.tsx +0 -372
- package/src/features/fetchxml/ui/RightPane/FetchXmlEditor.tsx +0 -399
- package/src/features/fetchxml/ui/RightPane/FormattedValueUtils.ts +0 -189
- package/src/features/fetchxml/ui/RightPane/LayoutXmlViewer.tsx +0 -171
- package/src/features/fetchxml/ui/RightPane/PreviewTabs.tsx +0 -471
- package/src/features/fetchxml/ui/RightPane/ResultsCommandBar.tsx +0 -430
- package/src/features/fetchxml/ui/RightPane/ResultsGrid.tsx +0 -983
- package/src/features/fetchxml/ui/RightPane/XmlTextArea.tsx +0 -65
- package/src/features/fetchxml/ui/Settings/SettingsDrawer.tsx +0 -175
- package/src/features/fetchxml/ui/Toolbar/EntitySelector.tsx +0 -788
- package/src/features/fetchxml/ui/Toolbar/LoadViewPicker.tsx +0 -274
- package/src/features/fetchxml/ui/Toolbar/SaveViewButton.tsx +0 -174
- package/src/main.tsx +0 -11
- package/src/shared/components/AttributePicker.tsx +0 -138
- package/src/shared/components/BetweenInputPicker.tsx +0 -120
- package/src/shared/components/BooleanValuePicker.tsx +0 -165
- package/src/shared/components/DateTimeInputPicker.tsx +0 -170
- package/src/shared/components/DynamicValueList.tsx +0 -128
- package/src/shared/components/ExcelIcon.tsx +0 -30
- package/src/shared/components/MultiValuePicker.tsx +0 -178
- package/src/shared/components/NumericInputPicker.tsx +0 -156
- package/src/shared/components/OptionSetValuePicker.tsx +0 -150
- package/src/shared/components/RelationshipPicker.tsx +0 -268
- package/src/shared/contexts/ThemeContext.tsx +0 -19
- package/src/shared/hooks/useAccessMode.ts +0 -77
- package/src/shared/hooks/useLazyMetadata.ts +0 -132
- package/src/shared/hooks/usePptbContext.ts +0 -170
- package/src/shared/hooks/usePublisherFilter.ts +0 -214
- package/src/shared/hooks/useSolutionFilter.ts +0 -162
- package/src/shared/utils/debug.ts +0 -87
- package/tsconfig.app.json +0 -28
- package/tsconfig.json +0 -7
- package/tsconfig.node.json +0 -26
- package/vite.config.ts +0 -7
|
@@ -1,393 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Metadata cache with promise memoization
|
|
3
|
-
* Prevents duplicate API calls for the same entity
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import type {
|
|
7
|
-
EntityMetadata,
|
|
8
|
-
AttributeMetadata,
|
|
9
|
-
RelationshipMetadata,
|
|
10
|
-
Publisher,
|
|
11
|
-
Solution,
|
|
12
|
-
PublisherWithSolutions,
|
|
13
|
-
} from "../api/pptbClient";
|
|
14
|
-
|
|
15
|
-
interface CachedEntityData {
|
|
16
|
-
metadata?: EntityMetadata;
|
|
17
|
-
attributes?: AttributeMetadata[];
|
|
18
|
-
relationships?: {
|
|
19
|
-
oneToMany: RelationshipMetadata[];
|
|
20
|
-
manyToOne: RelationshipMetadata[];
|
|
21
|
-
manyToMany: RelationshipMetadata[];
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
interface CacheEntry<T> {
|
|
26
|
-
data?: T;
|
|
27
|
-
promise?: Promise<T>;
|
|
28
|
-
timestamp: number;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
class MetadataCache {
|
|
32
|
-
private entities: Map<string, CacheEntry<CachedEntityData>> = new Map();
|
|
33
|
-
private allEntitiesCache: CacheEntry<EntityMetadata[]> | null = null;
|
|
34
|
-
private allEntityMetadataCache: CacheEntry<EntityMetadata[]> | null = null; // Global AF-valid entities
|
|
35
|
-
private publishersCache: CacheEntry<Publisher[]> | null = null;
|
|
36
|
-
private publishersWithSolutionsCache: CacheEntry<PublisherWithSolutions[]> | null = null;
|
|
37
|
-
private solutionsCache: Map<string, CacheEntry<Solution[]>> = new Map(); // keyed by sorted publisher IDs
|
|
38
|
-
private filteredEntitiesCache: Map<string, CacheEntry<EntityMetadata[]>> = new Map(); // keyed by sorted solution IDs
|
|
39
|
-
private solutionComponentsCache: Map<string, CacheEntry<string[]>> = new Map(); // Entity names per solution ID
|
|
40
|
-
|
|
41
|
-
// Cache TTL: 5 minutes
|
|
42
|
-
private readonly TTL = 5 * 60 * 1000;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Check if cache entry is stale
|
|
46
|
-
*/
|
|
47
|
-
private isStale(timestamp: number): boolean {
|
|
48
|
-
return Date.now() - timestamp > this.TTL;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Get or create entity cache entry
|
|
53
|
-
*/
|
|
54
|
-
private getEntityEntry(logicalName: string): CacheEntry<CachedEntityData> {
|
|
55
|
-
if (!this.entities.has(logicalName)) {
|
|
56
|
-
this.entities.set(logicalName, {
|
|
57
|
-
data: {},
|
|
58
|
-
timestamp: Date.now(),
|
|
59
|
-
});
|
|
60
|
-
}
|
|
61
|
-
return this.entities.get(logicalName)!;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Get all entities from cache
|
|
66
|
-
*/
|
|
67
|
-
getAllEntities(): EntityMetadata[] | undefined {
|
|
68
|
-
if (!this.allEntitiesCache || this.isStale(this.allEntitiesCache.timestamp)) {
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
return this.allEntitiesCache.data;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* Set all entities in cache
|
|
76
|
-
*/
|
|
77
|
-
setAllEntities(entities: EntityMetadata[]): void {
|
|
78
|
-
this.allEntitiesCache = {
|
|
79
|
-
data: entities,
|
|
80
|
-
timestamp: Date.now(),
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Get in-flight promise for all entities
|
|
86
|
-
*/
|
|
87
|
-
getAllEntitiesPromise(): Promise<EntityMetadata[]> | undefined {
|
|
88
|
-
return this.allEntitiesCache?.promise;
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Set in-flight promise for all entities
|
|
93
|
-
*/
|
|
94
|
-
setAllEntitiesPromise(promise: Promise<EntityMetadata[]>): void {
|
|
95
|
-
if (!this.allEntitiesCache) {
|
|
96
|
-
this.allEntitiesCache = { timestamp: Date.now() };
|
|
97
|
-
}
|
|
98
|
-
this.allEntitiesCache.promise = promise;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Clear in-flight promise for all entities
|
|
103
|
-
*/
|
|
104
|
-
clearAllEntitiesPromise(): void {
|
|
105
|
-
if (this.allEntitiesCache) {
|
|
106
|
-
this.allEntitiesCache.promise = undefined;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Get global entity metadata cache (all AF-valid entities)
|
|
112
|
-
*/
|
|
113
|
-
getAllEntityMetadata(): EntityMetadata[] | undefined {
|
|
114
|
-
if (!this.allEntityMetadataCache || this.isStale(this.allEntityMetadataCache.timestamp)) {
|
|
115
|
-
return undefined;
|
|
116
|
-
}
|
|
117
|
-
return this.allEntityMetadataCache.data;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Set global entity metadata cache
|
|
122
|
-
*/
|
|
123
|
-
setAllEntityMetadata(entities: EntityMetadata[]): void {
|
|
124
|
-
this.allEntityMetadataCache = {
|
|
125
|
-
data: entities,
|
|
126
|
-
timestamp: Date.now(),
|
|
127
|
-
};
|
|
128
|
-
console.log("[Cache] Global entity metadata cached:", entities.length, "entities");
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* Get in-flight promise for global entity metadata
|
|
133
|
-
*/
|
|
134
|
-
getAllEntityMetadataPromise(): Promise<EntityMetadata[]> | undefined {
|
|
135
|
-
return this.allEntityMetadataCache?.promise;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* Set in-flight promise for global entity metadata
|
|
140
|
-
*/
|
|
141
|
-
setAllEntityMetadataPromise(promise: Promise<EntityMetadata[]>): void {
|
|
142
|
-
if (!this.allEntityMetadataCache) {
|
|
143
|
-
this.allEntityMetadataCache = { timestamp: Date.now() };
|
|
144
|
-
}
|
|
145
|
-
this.allEntityMetadataCache.promise = promise;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Clear in-flight promise for global entity metadata
|
|
150
|
-
*/
|
|
151
|
-
clearAllEntityMetadataPromise(): void {
|
|
152
|
-
if (this.allEntityMetadataCache) {
|
|
153
|
-
this.allEntityMetadataCache.promise = undefined;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* Get entity metadata from cache
|
|
159
|
-
*/
|
|
160
|
-
getEntityMetadata(logicalName: string): EntityMetadata | undefined {
|
|
161
|
-
const entry = this.entities.get(logicalName);
|
|
162
|
-
if (!entry || this.isStale(entry.timestamp)) {
|
|
163
|
-
return undefined;
|
|
164
|
-
}
|
|
165
|
-
return entry.data?.metadata;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Set entity metadata in cache
|
|
170
|
-
*/
|
|
171
|
-
setEntityMetadata(logicalName: string, metadata: EntityMetadata): void {
|
|
172
|
-
const entry = this.getEntityEntry(logicalName);
|
|
173
|
-
if (!entry.data) entry.data = {};
|
|
174
|
-
entry.data.metadata = metadata;
|
|
175
|
-
entry.timestamp = Date.now();
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Get entity attributes from cache
|
|
180
|
-
*/
|
|
181
|
-
getEntityAttributes(logicalName: string): AttributeMetadata[] | undefined {
|
|
182
|
-
const entry = this.entities.get(logicalName);
|
|
183
|
-
if (!entry || this.isStale(entry.timestamp)) {
|
|
184
|
-
return undefined;
|
|
185
|
-
}
|
|
186
|
-
return entry.data?.attributes;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Set entity attributes in cache
|
|
191
|
-
*/
|
|
192
|
-
setEntityAttributes(logicalName: string, attributes: AttributeMetadata[]): void {
|
|
193
|
-
const entry = this.getEntityEntry(logicalName);
|
|
194
|
-
if (!entry.data) entry.data = {};
|
|
195
|
-
entry.data.attributes = attributes;
|
|
196
|
-
entry.timestamp = Date.now();
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Get entity relationships from cache
|
|
201
|
-
*/
|
|
202
|
-
getEntityRelationships(logicalName: string):
|
|
203
|
-
| {
|
|
204
|
-
oneToMany: RelationshipMetadata[];
|
|
205
|
-
manyToOne: RelationshipMetadata[];
|
|
206
|
-
manyToMany: RelationshipMetadata[];
|
|
207
|
-
}
|
|
208
|
-
| undefined {
|
|
209
|
-
const entry = this.entities.get(logicalName);
|
|
210
|
-
if (!entry || this.isStale(entry.timestamp)) {
|
|
211
|
-
return undefined;
|
|
212
|
-
}
|
|
213
|
-
return entry.data?.relationships;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Set entity relationships in cache
|
|
218
|
-
*/
|
|
219
|
-
setEntityRelationships(
|
|
220
|
-
logicalName: string,
|
|
221
|
-
relationships: {
|
|
222
|
-
oneToMany: RelationshipMetadata[];
|
|
223
|
-
manyToOne: RelationshipMetadata[];
|
|
224
|
-
manyToMany: RelationshipMetadata[];
|
|
225
|
-
}
|
|
226
|
-
): void {
|
|
227
|
-
const entry = this.getEntityEntry(logicalName);
|
|
228
|
-
if (!entry.data) entry.data = {};
|
|
229
|
-
entry.data.relationships = relationships;
|
|
230
|
-
entry.timestamp = Date.now();
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
/**
|
|
234
|
-
* Check if there's an in-flight request for entity attributes
|
|
235
|
-
*/
|
|
236
|
-
getAttributesPromise(logicalName: string): Promise<AttributeMetadata[]> | undefined {
|
|
237
|
-
const entry = this.entities.get(logicalName);
|
|
238
|
-
return entry?.promise as Promise<AttributeMetadata[]> | undefined;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
/**
|
|
242
|
-
* Set in-flight promise for entity attributes
|
|
243
|
-
*/
|
|
244
|
-
setAttributesPromise(logicalName: string, promise: Promise<AttributeMetadata[]>): void {
|
|
245
|
-
const entry = this.getEntityEntry(logicalName);
|
|
246
|
-
entry.promise = promise as Promise<CachedEntityData>;
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/**
|
|
250
|
-
* Clear in-flight promise for entity attributes
|
|
251
|
-
*/
|
|
252
|
-
clearAttributesPromise(logicalName: string): void {
|
|
253
|
-
const entry = this.entities.get(logicalName);
|
|
254
|
-
if (entry) {
|
|
255
|
-
entry.promise = undefined;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
/**
|
|
260
|
-
* Clear all cache
|
|
261
|
-
*/
|
|
262
|
-
clear(): void {
|
|
263
|
-
this.entities.clear();
|
|
264
|
-
this.allEntitiesCache = null;
|
|
265
|
-
this.publishersCache = null;
|
|
266
|
-
this.solutionsCache.clear();
|
|
267
|
-
this.filteredEntitiesCache.clear();
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
/**
|
|
271
|
-
* Clear cache for specific entity
|
|
272
|
-
*/
|
|
273
|
-
clearEntity(logicalName: string): void {
|
|
274
|
-
this.entities.delete(logicalName);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Get publishers from cache
|
|
279
|
-
*/
|
|
280
|
-
getPublishers(): Publisher[] | undefined {
|
|
281
|
-
if (!this.publishersCache || this.isStale(this.publishersCache.timestamp)) {
|
|
282
|
-
return undefined;
|
|
283
|
-
}
|
|
284
|
-
return this.publishersCache.data;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
/**
|
|
288
|
-
* Set publishers in cache
|
|
289
|
-
*/
|
|
290
|
-
setPublishers(publishers: Publisher[]): void {
|
|
291
|
-
this.publishersCache = {
|
|
292
|
-
data: publishers,
|
|
293
|
-
timestamp: Date.now(),
|
|
294
|
-
};
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Get publishers with solutions from cache (combined response)
|
|
299
|
-
*/
|
|
300
|
-
getPublishersWithSolutions(): PublisherWithSolutions[] | undefined {
|
|
301
|
-
if (
|
|
302
|
-
!this.publishersWithSolutionsCache ||
|
|
303
|
-
this.isStale(this.publishersWithSolutionsCache.timestamp)
|
|
304
|
-
) {
|
|
305
|
-
return undefined;
|
|
306
|
-
}
|
|
307
|
-
return this.publishersWithSolutionsCache.data;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Set publishers with solutions in cache (combined response)
|
|
312
|
-
*/
|
|
313
|
-
setPublishersWithSolutions(publishersWithSolutions: PublisherWithSolutions[]): void {
|
|
314
|
-
this.publishersWithSolutionsCache = {
|
|
315
|
-
data: publishersWithSolutions,
|
|
316
|
-
timestamp: Date.now(),
|
|
317
|
-
};
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
/**
|
|
321
|
-
* Get solutions from cache by publisher IDs
|
|
322
|
-
*/
|
|
323
|
-
getSolutions(publisherIds: string[]): Solution[] | undefined {
|
|
324
|
-
const key = publisherIds.sort().join(",");
|
|
325
|
-
const entry = this.solutionsCache.get(key);
|
|
326
|
-
if (!entry || this.isStale(entry.timestamp)) {
|
|
327
|
-
return undefined;
|
|
328
|
-
}
|
|
329
|
-
return entry.data;
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* Set solutions in cache by publisher IDs
|
|
334
|
-
*/
|
|
335
|
-
setSolutions(publisherIds: string[], solutions: Solution[]): void {
|
|
336
|
-
const key = publisherIds.sort().join(",");
|
|
337
|
-
this.solutionsCache.set(key, {
|
|
338
|
-
data: solutions,
|
|
339
|
-
timestamp: Date.now(),
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
/**
|
|
344
|
-
* Get filtered entities from cache by solution IDs
|
|
345
|
-
*/
|
|
346
|
-
getFilteredEntities(solutionIds: string[]): EntityMetadata[] | undefined {
|
|
347
|
-
const key = solutionIds.sort().join(",");
|
|
348
|
-
const entry = this.filteredEntitiesCache.get(key);
|
|
349
|
-
if (!entry || this.isStale(entry.timestamp)) {
|
|
350
|
-
return undefined;
|
|
351
|
-
}
|
|
352
|
-
return entry.data;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
|
-
/**
|
|
356
|
-
* Set filtered entities in cache by solution IDs
|
|
357
|
-
*/
|
|
358
|
-
setFilteredEntities(solutionIds: string[], entities: EntityMetadata[]): void {
|
|
359
|
-
const key = solutionIds.sort().join(",");
|
|
360
|
-
this.filteredEntitiesCache.set(key, {
|
|
361
|
-
data: entities,
|
|
362
|
-
timestamp: Date.now(),
|
|
363
|
-
});
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
/**
|
|
367
|
-
* Get solution components (entity names) from cache by solution ID
|
|
368
|
-
*/
|
|
369
|
-
getSolutionComponents(solutionId: string): string[] | undefined {
|
|
370
|
-
const entry = this.solutionComponentsCache.get(solutionId);
|
|
371
|
-
if (!entry || this.isStale(entry.timestamp)) {
|
|
372
|
-
return undefined;
|
|
373
|
-
}
|
|
374
|
-
return entry.data;
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
/**
|
|
378
|
-
* Set solution components (entity names) in cache by solution ID
|
|
379
|
-
*/
|
|
380
|
-
setSolutionComponents(solutionId: string, entityNames: string[]): void {
|
|
381
|
-
this.solutionComponentsCache.set(solutionId, {
|
|
382
|
-
data: entityNames,
|
|
383
|
-
timestamp: Date.now(),
|
|
384
|
-
});
|
|
385
|
-
console.log("[Cache] Solution components cached:", {
|
|
386
|
-
solutionId,
|
|
387
|
-
entityCount: entityNames.length,
|
|
388
|
-
});
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// Singleton instance
|
|
393
|
-
export const metadataCache = new MetadataCache();
|