@peak-ai/canvas 1.4.21 → 1.4.22
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/.babelrc +14 -0
- package/.eslintcache +1 -0
- package/.eslintignore +5 -0
- package/.eslintrc.js +29 -0
- package/{GrapesjsCanvas.js → dist/GrapesjsCanvas.js} +3 -2
- package/dist/GrapesjsCanvas.js.map +1 -0
- package/dist/package.json +62 -0
- package/{plugins → dist/plugins}/helpers/render-components.js +1 -1
- package/dist/plugins/helpers/render-components.js.map +1 -0
- package/dist/shadcn/components/ui/error-wrapper.js +2 -0
- package/dist/shadcn/components/ui/error-wrapper.js.map +1 -0
- package/package.json +45 -7
- package/scripts/build.ts +120 -0
- package/src/GrapesjsCanvas.tsx +494 -0
- package/src/constants/index.ts +25 -0
- package/src/declaration.d.ts +1 -0
- package/src/helpers/compiled-table.css +2429 -0
- package/src/helpers/css.ts +2667 -0
- package/src/helpers/date-picker.ts +807 -0
- package/src/helpers/filter-placeholder.ts +18 -0
- package/src/helpers/index.ts +13 -0
- package/src/helpers/merge-json.ts +106 -0
- package/src/index.styles.ts +58 -0
- package/src/index.ts +9 -0
- package/src/plugins/grapejs-plugin.tsx +196 -0
- package/src/plugins/helpers/custom-modal.tsx +123 -0
- package/src/plugins/helpers/data-table.tsx +300 -0
- package/src/plugins/helpers/extra.tsx +164 -0
- package/src/plugins/helpers/query-cache-context.tsx +154 -0
- package/src/plugins/helpers/query-cache-singleton.ts +176 -0
- package/src/plugins/helpers/query-cache-utils.ts +226 -0
- package/src/plugins/helpers/query-details-modal.tsx +400 -0
- package/src/plugins/helpers/query-heading-formatter.ts +24 -0
- package/src/plugins/helpers/query-loading-modal.tsx +94 -0
- package/src/plugins/helpers/render-components.tsx +1450 -0
- package/src/plugins/helpers/styled-info-button.tsx +504 -0
- package/src/public/canvas.css +42 -0
- package/src/public/components-css/table/table-output.css +2436 -0
- package/src/public/components-css/table/table.css +30 -0
- package/src/public/output.css +2465 -0
- package/src/public/table.css +135 -0
- package/src/shadcn/components/icons/AiAvatarIcon.tsx +47 -0
- package/src/shadcn/components/icons/Co_driver Expanding button copy.svg +21 -0
- package/src/shadcn/components/icons/ai-avatar.svg +7 -0
- package/src/shadcn/components/icons/thinking.gif +0 -0
- package/src/shadcn/components/ui/button.tsx +132 -0
- package/src/shadcn/components/ui/card.tsx +92 -0
- package/src/shadcn/components/ui/chart.tsx +324 -0
- package/src/shadcn/components/ui/checkbox.tsx +27 -0
- package/src/shadcn/components/ui/component-wrapper.tsx +61 -0
- package/src/shadcn/components/ui/date-filter.tsx +816 -0
- package/src/shadcn/components/ui/error-container.tsx +125 -0
- package/src/shadcn/components/ui/error-wrapper.tsx +99 -0
- package/src/shadcn/components/ui/filter.tsx +368 -0
- package/src/shadcn/components/ui/hover-card.tsx +36 -0
- package/src/shadcn/components/ui/input.tsx +20 -0
- package/src/shadcn/components/ui/label.tsx +24 -0
- package/src/shadcn/components/ui/pagination.tsx +213 -0
- package/src/shadcn/components/ui/scroll-area.tsx +59 -0
- package/src/shadcn/components/ui/search.tsx +150 -0
- package/src/shadcn/components/ui/separator.tsx +26 -0
- package/src/shadcn/components/ui/skeleton.tsx +69 -0
- package/src/shadcn/components/ui/table.tsx +196 -0
- package/src/shadcn/components/ui/tabs.tsx +55 -0
- package/src/shadcn/components/ui/textarea.tsx +18 -0
- package/src/shadcn/components/ui/tooltip.tsx +87 -0
- package/src/shadcn/utils.ts +6 -0
- package/src/types/grapesjs-tailwind.d.ts +61 -0
- package/src/types/images.d.ts +1 -0
- package/tailwind.config.js +5 -0
- package/tooling/tailwind-compiler/index.js +99 -0
- package/tooling/tailwind-compiler/package.json +11 -0
- package/tooling/tailwind-compiler/yarn.lock +123 -0
- package/tsconfig.build.json +15 -0
- package/tsconfig.json +8 -0
- package/GrapesjsCanvas.js.map +0 -1
- package/plugins/helpers/render-components.js.map +0 -1
- package/shadcn/components/ui/error-wrapper.js +0 -2
- package/shadcn/components/ui/error-wrapper.js.map +0 -1
- /package/{GrapesjsCanvas.d.ts → dist/GrapesjsCanvas.d.ts} +0 -0
- /package/{constants → dist/constants}/index.d.ts +0 -0
- /package/{constants → dist/constants}/index.js +0 -0
- /package/{constants → dist/constants}/index.js.map +0 -0
- /package/{declaration.d.js → dist/declaration.d.js} +0 -0
- /package/{declaration.d.js.map → dist/declaration.d.js.map} +0 -0
- /package/{helpers → dist/helpers}/compiled-table.css +0 -0
- /package/{helpers → dist/helpers}/css.d.ts +0 -0
- /package/{helpers → dist/helpers}/css.js +0 -0
- /package/{helpers → dist/helpers}/css.js.map +0 -0
- /package/{helpers → dist/helpers}/date-picker.d.ts +0 -0
- /package/{helpers → dist/helpers}/date-picker.js +0 -0
- /package/{helpers → dist/helpers}/date-picker.js.map +0 -0
- /package/{helpers → dist/helpers}/filter-placeholder.d.ts +0 -0
- /package/{helpers → dist/helpers}/filter-placeholder.js +0 -0
- /package/{helpers → dist/helpers}/filter-placeholder.js.map +0 -0
- /package/{helpers → dist/helpers}/index.d.ts +0 -0
- /package/{helpers → dist/helpers}/index.js +0 -0
- /package/{helpers → dist/helpers}/index.js.map +0 -0
- /package/{helpers → dist/helpers}/merge-json.d.ts +0 -0
- /package/{helpers → dist/helpers}/merge-json.js +0 -0
- /package/{helpers → dist/helpers}/merge-json.js.map +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{index.js → dist/index.js} +0 -0
- /package/{index.js.map → dist/index.js.map} +0 -0
- /package/{index.styles.d.ts → dist/index.styles.d.ts} +0 -0
- /package/{index.styles.js → dist/index.styles.js} +0 -0
- /package/{index.styles.js.map → dist/index.styles.js.map} +0 -0
- /package/{plugins → dist/plugins}/grapejs-plugin.d.ts +0 -0
- /package/{plugins → dist/plugins}/grapejs-plugin.js +0 -0
- /package/{plugins → dist/plugins}/grapejs-plugin.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/custom-modal.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/custom-modal.js +0 -0
- /package/{plugins → dist/plugins}/helpers/custom-modal.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/data-table.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/data-table.js +0 -0
- /package/{plugins → dist/plugins}/helpers/data-table.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/extra.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/extra.js +0 -0
- /package/{plugins → dist/plugins}/helpers/extra.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-context.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-context.js +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-context.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-singleton.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-singleton.js +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-singleton.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-utils.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-utils.js +0 -0
- /package/{plugins → dist/plugins}/helpers/query-cache-utils.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/query-details-modal.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/query-details-modal.js +0 -0
- /package/{plugins → dist/plugins}/helpers/query-details-modal.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/query-heading-formatter.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/query-heading-formatter.js +0 -0
- /package/{plugins → dist/plugins}/helpers/query-heading-formatter.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/query-loading-modal.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/query-loading-modal.js +0 -0
- /package/{plugins → dist/plugins}/helpers/query-loading-modal.js.map +0 -0
- /package/{plugins → dist/plugins}/helpers/render-components.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/styled-info-button.d.ts +0 -0
- /package/{plugins → dist/plugins}/helpers/styled-info-button.js +0 -0
- /package/{plugins → dist/plugins}/helpers/styled-info-button.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/icons/AiAvatarIcon.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/icons/AiAvatarIcon.js +0 -0
- /package/{shadcn → dist/shadcn}/components/icons/AiAvatarIcon.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/icons/thinking.gif +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/button.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/button.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/button.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/card.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/card.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/card.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/chart.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/chart.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/chart.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/checkbox.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/checkbox.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/checkbox.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/component-wrapper.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/component-wrapper.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/component-wrapper.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/date-filter.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/date-filter.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/date-filter.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/error-container.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/error-container.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/error-container.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/error-wrapper.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/filter.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/filter.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/filter.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/hover-card.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/hover-card.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/hover-card.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/input.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/input.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/input.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/label.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/label.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/label.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/pagination.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/pagination.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/pagination.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/scroll-area.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/scroll-area.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/scroll-area.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/search.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/search.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/search.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/separator.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/separator.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/separator.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/skeleton.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/skeleton.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/skeleton.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/table.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/table.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/table.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/tabs.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/tabs.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/tabs.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/textarea.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/textarea.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/textarea.js.map +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/tooltip.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/tooltip.js +0 -0
- /package/{shadcn → dist/shadcn}/components/ui/tooltip.js.map +0 -0
- /package/{shadcn → dist/shadcn}/utils.d.ts +0 -0
- /package/{shadcn → dist/shadcn}/utils.js +0 -0
- /package/{shadcn → dist/shadcn}/utils.js.map +0 -0
- /package/{types → dist/types}/grapesjs-tailwind.d.js +0 -0
- /package/{types → dist/types}/grapesjs-tailwind.d.js.map +0 -0
- /package/{types → dist/types}/images.d.js +0 -0
- /package/{types → dist/types}/images.d.js.map +0 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import {
|
|
2
|
+
QueryCacheEntry,
|
|
3
|
+
InteractionType,
|
|
4
|
+
InteractionState,
|
|
5
|
+
createInteractionKey
|
|
6
|
+
} from './query-cache-utils';
|
|
7
|
+
|
|
8
|
+
class QueryCacheManager {
|
|
9
|
+
private cache: Map<string, Map<string, QueryCacheEntry>> = new Map();
|
|
10
|
+
private totalEntries = 0;
|
|
11
|
+
private maxCacheSize = 100;
|
|
12
|
+
private maxCacheAge: number = 5 * 60 * 1000; // 5 minutes
|
|
13
|
+
|
|
14
|
+
constructor(maxCacheSize = 100, maxCacheAge = 5 * 60 * 1000) {
|
|
15
|
+
this.maxCacheSize = maxCacheSize;
|
|
16
|
+
this.maxCacheAge = maxCacheAge;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
getCachedQuery(
|
|
20
|
+
componentId: string,
|
|
21
|
+
interactionType: InteractionType,
|
|
22
|
+
state: InteractionState
|
|
23
|
+
): QueryCacheEntry | null {
|
|
24
|
+
const componentCache = this.cache.get(componentId);
|
|
25
|
+
|
|
26
|
+
if (!componentCache) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const key = createInteractionKey(interactionType, state);
|
|
31
|
+
const entry = componentCache.get(key);
|
|
32
|
+
|
|
33
|
+
if (!entry) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const now = Date.now();
|
|
38
|
+
|
|
39
|
+
if (now - entry.timestamp > this.maxCacheAge) {
|
|
40
|
+
componentCache.delete(key);
|
|
41
|
+
this.totalEntries -= 1;
|
|
42
|
+
|
|
43
|
+
if (componentCache.size === 0) {
|
|
44
|
+
this.cache.delete(componentId);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return entry;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
setCachedQuery(
|
|
54
|
+
componentId: string,
|
|
55
|
+
interactionType: InteractionType,
|
|
56
|
+
state: InteractionState,
|
|
57
|
+
entry: QueryCacheEntry
|
|
58
|
+
): void {
|
|
59
|
+
let componentCache = this.cache.get(componentId);
|
|
60
|
+
|
|
61
|
+
if (!componentCache) {
|
|
62
|
+
componentCache = new Map();
|
|
63
|
+
this.cache.set(componentId, componentCache);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const key = createInteractionKey(interactionType, state);
|
|
67
|
+
const isNewEntry = !componentCache.has(key);
|
|
68
|
+
|
|
69
|
+
componentCache.set(key, {
|
|
70
|
+
...entry,
|
|
71
|
+
timestamp: Date.now(),
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
if (isNewEntry) {
|
|
75
|
+
this.totalEntries += 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (this.totalEntries > this.maxCacheSize) {
|
|
79
|
+
this.cleanupCache();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
invalidateComponent(componentId: string): void {
|
|
84
|
+
const componentCache = this.cache.get(componentId);
|
|
85
|
+
|
|
86
|
+
if (componentCache) {
|
|
87
|
+
this.totalEntries -= componentCache.size;
|
|
88
|
+
this.cache.delete(componentId);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
invalidateAll(): void {
|
|
93
|
+
this.cache.clear();
|
|
94
|
+
this.totalEntries = 0;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
isCached(
|
|
98
|
+
componentId: string,
|
|
99
|
+
interactionType: InteractionType,
|
|
100
|
+
state: InteractionState
|
|
101
|
+
): boolean {
|
|
102
|
+
return this.getCachedQuery(componentId, interactionType, state) !== null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
private cleanupCache(): void {
|
|
106
|
+
const now = Date.now();
|
|
107
|
+
const allEntries: Array<{ componentId: string; key: string; timestamp: number }> = [];
|
|
108
|
+
|
|
109
|
+
for (const [componentId, componentCache] of this.cache.entries()) {
|
|
110
|
+
for (const [key, entry] of componentCache.entries()) {
|
|
111
|
+
if (now - entry.timestamp > this.maxCacheAge) {
|
|
112
|
+
componentCache.delete(key);
|
|
113
|
+
this.totalEntries -= 1;
|
|
114
|
+
} else {
|
|
115
|
+
allEntries.push({ componentId, key, timestamp: entry.timestamp });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if (componentCache.size === 0) {
|
|
120
|
+
this.cache.delete(componentId);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (allEntries.length > this.maxCacheSize) {
|
|
125
|
+
allEntries.sort((a, b) => a.timestamp - b.timestamp);
|
|
126
|
+
|
|
127
|
+
const entriesToRemove = allEntries.slice(0, allEntries.length - this.maxCacheSize);
|
|
128
|
+
|
|
129
|
+
for (const { componentId, key } of entriesToRemove) {
|
|
130
|
+
const componentCache = this.cache.get(componentId);
|
|
131
|
+
|
|
132
|
+
if (componentCache) {
|
|
133
|
+
componentCache.delete(key);
|
|
134
|
+
this.totalEntries -= 1;
|
|
135
|
+
|
|
136
|
+
// Remove empty component caches
|
|
137
|
+
if (componentCache.size === 0) {
|
|
138
|
+
this.cache.delete(componentId);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
private getTotalCacheSize(): number {
|
|
146
|
+
return this.totalEntries;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
getStats(): { componentCount: number; maxAge: number; maxSize: number; size: number } {
|
|
150
|
+
return {
|
|
151
|
+
componentCount: this.cache.size,
|
|
152
|
+
maxAge: this.maxCacheAge,
|
|
153
|
+
maxSize: this.maxCacheSize,
|
|
154
|
+
size: this.getTotalCacheSize(),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
let globalCacheInstance: QueryCacheManager | null = null;
|
|
160
|
+
|
|
161
|
+
export function getGlobalQueryCache(): QueryCacheManager {
|
|
162
|
+
if (!globalCacheInstance) {
|
|
163
|
+
globalCacheInstance = new QueryCacheManager();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return globalCacheInstance;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function resetGlobalQueryCache(): void {
|
|
170
|
+
globalCacheInstance = null;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function configureGlobalQueryCache(maxCacheSize = 100, maxCacheAge = 5 * 60 * 1000): void {
|
|
174
|
+
globalCacheInstance = new QueryCacheManager(maxCacheSize, maxCacheAge);
|
|
175
|
+
}
|
|
176
|
+
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
|
|
2
|
+
export type InteractionType = 'semanticLayerQuery' | 'tableButton';
|
|
3
|
+
|
|
4
|
+
export type InteractionState = {
|
|
5
|
+
[key: string]: unknown;
|
|
6
|
+
bodyContent?: unknown;
|
|
7
|
+
chartData?: unknown;
|
|
8
|
+
chartDataFingerprint?: string;
|
|
9
|
+
chartDataLength?: number;
|
|
10
|
+
dataFingerprint?: string;
|
|
11
|
+
dataLength?: number;
|
|
12
|
+
error?: unknown;
|
|
13
|
+
filterValue?: unknown;
|
|
14
|
+
filters?: Record<string, unknown>;
|
|
15
|
+
footerContent?: unknown;
|
|
16
|
+
headerContent?: unknown;
|
|
17
|
+
isMissing?: unknown;
|
|
18
|
+
pageNumber?: number;
|
|
19
|
+
pageSize?: number;
|
|
20
|
+
searchQuery?: string;
|
|
21
|
+
searchValue?: string;
|
|
22
|
+
sortColumn?: string | null;
|
|
23
|
+
sortDirection?: 'asc' | 'desc' | null;
|
|
24
|
+
summaryText?: unknown;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
export type QueryCacheEntry = {
|
|
28
|
+
queryHeadings: string[];
|
|
29
|
+
sqlQuery: string | string[];
|
|
30
|
+
tableButtonExplanations: Array<{
|
|
31
|
+
action: string;
|
|
32
|
+
buttonClassName?: string;
|
|
33
|
+
buttonStyle?: Record<string, unknown>;
|
|
34
|
+
explanation: string;
|
|
35
|
+
formFields?: Record<string, unknown>;
|
|
36
|
+
jsonBody?: unknown;
|
|
37
|
+
operationDescription?: string;
|
|
38
|
+
operationSummary?: string;
|
|
39
|
+
requestUrl?: string;
|
|
40
|
+
}>;
|
|
41
|
+
timestamp: number;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export type CacheKey = {
|
|
45
|
+
componentId: string;
|
|
46
|
+
interactionType: InteractionType;
|
|
47
|
+
state: InteractionState;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export function createCacheKey(
|
|
51
|
+
componentId: string,
|
|
52
|
+
interactionType: InteractionType,
|
|
53
|
+
interactionState: InteractionState
|
|
54
|
+
): string {
|
|
55
|
+
const sortedState = sortObjectKeys(interactionState);
|
|
56
|
+
|
|
57
|
+
try {
|
|
58
|
+
const stateString = JSON.stringify(sortedState);
|
|
59
|
+
|
|
60
|
+
return `${componentId}::${interactionType}::${stateString}`;
|
|
61
|
+
} catch (error) {
|
|
62
|
+
// eslint-disable-next-line no-console
|
|
63
|
+
console.warn('Failed to serialize interaction state:', error);
|
|
64
|
+
|
|
65
|
+
return `${componentId}::${interactionType}::${Date.now()}::${Math.random()}`;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function createInteractionKey(
|
|
70
|
+
interactionType: InteractionType,
|
|
71
|
+
interactionState: InteractionState
|
|
72
|
+
): string {
|
|
73
|
+
const sortedState = sortObjectKeys(interactionState);
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const stateString = JSON.stringify(sortedState);
|
|
77
|
+
|
|
78
|
+
return `${interactionType}::${stateString}`;
|
|
79
|
+
} catch (error) {
|
|
80
|
+
// eslint-disable-next-line no-console
|
|
81
|
+
console.warn('Failed to serialize interaction state:', error);
|
|
82
|
+
|
|
83
|
+
return `${interactionType}::${Date.now()}::${Math.random()}`;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function sortObjectKeys(obj: unknown): unknown {
|
|
88
|
+
if (obj === null || obj === undefined) {
|
|
89
|
+
return obj;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (Array.isArray(obj)) {
|
|
93
|
+
return obj.map(item => sortObjectKeys(item));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (typeof obj === 'object') {
|
|
97
|
+
const sorted: Record<string, unknown> = {};
|
|
98
|
+
const keys = Object.keys(obj as Record<string, unknown>).sort();
|
|
99
|
+
|
|
100
|
+
for (const key of keys) {
|
|
101
|
+
sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return sorted;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return obj;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function extractInteractionState(componentProps: Record<string, unknown>): InteractionState {
|
|
111
|
+
const state: InteractionState = {};
|
|
112
|
+
|
|
113
|
+
if ('pagination' in componentProps && typeof componentProps.pagination === 'object' && componentProps.pagination) {
|
|
114
|
+
const pagination = componentProps.pagination as Record<string, unknown>;
|
|
115
|
+
|
|
116
|
+
if ('pageNumber' in pagination && typeof pagination.pageNumber === 'number') {
|
|
117
|
+
state.pageNumber = pagination.pageNumber;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if ('pageSize' in pagination && typeof pagination.pageSize === 'number') {
|
|
121
|
+
state.pageSize = pagination.pageSize;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if ('sortColumn' in componentProps) {
|
|
126
|
+
state.sortColumn = componentProps.sortColumn as string | null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
if ('sortDirection' in componentProps) {
|
|
130
|
+
state.sortDirection = componentProps.sortDirection as 'asc' | 'desc' | null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if ('filters' in componentProps && typeof componentProps.filters === 'object') {
|
|
134
|
+
state.filters = componentProps.filters as Record<string, unknown>;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if ('value' in componentProps) {
|
|
138
|
+
state.filterValue = componentProps.value as unknown;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
if ('searchQuery' in componentProps && typeof componentProps.searchQuery === 'string') {
|
|
142
|
+
state.searchQuery = componentProps.searchQuery;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if ('searchValue' in componentProps && typeof componentProps.searchValue === 'string') {
|
|
146
|
+
state.searchValue = componentProps.searchValue;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
if ('data' in componentProps) {
|
|
150
|
+
const data = componentProps.data;
|
|
151
|
+
|
|
152
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
153
|
+
state.dataLength = data.length;
|
|
154
|
+
const firstRow = data[0];
|
|
155
|
+
const lastRow = data[data.length - 1];
|
|
156
|
+
|
|
157
|
+
if (firstRow && typeof firstRow === 'object') {
|
|
158
|
+
try {
|
|
159
|
+
state.dataFingerprint = JSON.stringify({
|
|
160
|
+
firstId: (firstRow as Record<string, unknown>).id || Object.values(firstRow)[0],
|
|
161
|
+
lastId: lastRow && typeof lastRow === 'object'
|
|
162
|
+
? ((lastRow as Record<string, unknown>).id || Object.values(lastRow)[0])
|
|
163
|
+
: null,
|
|
164
|
+
length: data.length
|
|
165
|
+
});
|
|
166
|
+
} catch (error) {
|
|
167
|
+
// eslint-disable-next-line no-console
|
|
168
|
+
console.warn('Failed to serialize data fingerprint:', error);
|
|
169
|
+
state.dataFingerprint = `fallback_${data.length}_${Date.now()}`;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
} else if (data && typeof data === 'object' && (data as Record<string, unknown>).name === '__peak_placeholder') {
|
|
173
|
+
state.dataFingerprint = '__peak_placeholder';
|
|
174
|
+
} else {
|
|
175
|
+
state.dataFingerprint = 'empty';
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if ('bodyContent' in componentProps) {
|
|
180
|
+
state.bodyContent = componentProps.bodyContent as unknown;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if ('headerContent' in componentProps) {
|
|
184
|
+
state.headerContent = componentProps.headerContent as unknown;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if ('footerContent' in componentProps) {
|
|
188
|
+
state.footerContent = componentProps.footerContent as unknown;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
if ('chartData' in componentProps) {
|
|
192
|
+
const chartData = componentProps.chartData;
|
|
193
|
+
|
|
194
|
+
if (Array.isArray(chartData)) {
|
|
195
|
+
state.chartDataLength = chartData.length;
|
|
196
|
+
|
|
197
|
+
try {
|
|
198
|
+
state.chartDataFingerprint = JSON.stringify(chartData);
|
|
199
|
+
} catch (error) {
|
|
200
|
+
// eslint-disable-next-line no-console
|
|
201
|
+
console.warn('Failed to serialize chart data fingerprint:', error);
|
|
202
|
+
state.chartDataFingerprint = `fallback_${chartData.length}_${Date.now()}`;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if ('summaryText' in componentProps) {
|
|
208
|
+
state.summaryText = componentProps.summaryText as unknown;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if ('error' in componentProps) {
|
|
212
|
+
state.error = componentProps.error as unknown;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
if ('isMissing' in componentProps) {
|
|
216
|
+
state.isMissing = componentProps.isMissing as unknown;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
return state;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export function areStatesEqual(state1: InteractionState, state2: InteractionState): boolean {
|
|
223
|
+
return createCacheKey('test', 'semanticLayerQuery', state1) ===
|
|
224
|
+
createCacheKey('test', 'semanticLayerQuery', state2);
|
|
225
|
+
}
|
|
226
|
+
|