@seed-ship/mcp-ui-solid 1.0.3 → 1.0.6
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/CHANGELOG.md +38 -0
- package/dist/components/GenerativeUIErrorBoundary.cjs +104 -0
- package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -0
- package/dist/components/GenerativeUIErrorBoundary.js +104 -0
- package/dist/components/GenerativeUIErrorBoundary.js.map +1 -0
- package/dist/components/StreamingUIRenderer.cjs +269 -0
- package/dist/components/StreamingUIRenderer.cjs.map +1 -0
- package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
- package/dist/components/StreamingUIRenderer.js +269 -0
- package/dist/components/StreamingUIRenderer.js.map +1 -0
- package/dist/components/UIResourceRenderer.cjs +343 -0
- package/dist/components/UIResourceRenderer.cjs.map +1 -0
- package/dist/components/UIResourceRenderer.d.ts.map +1 -1
- package/dist/components/UIResourceRenderer.js +343 -0
- package/dist/components/UIResourceRenderer.js.map +1 -0
- package/dist/components.cjs +8 -1
- package/dist/components.cjs.map +1 -1
- package/dist/components.js +6 -4
- package/dist/components.js.map +1 -1
- package/dist/hooks/useStreamingUI.cjs +230 -0
- package/dist/hooks/useStreamingUI.cjs.map +1 -0
- package/dist/hooks/useStreamingUI.js +230 -0
- package/dist/hooks/useStreamingUI.js.map +1 -0
- package/dist/hooks.cjs +4 -1
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.js +2 -2
- package/dist/index.cjs +16 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +14 -293
- package/dist/index.js.map +1 -1
- package/dist/services/component-registry.cjs +295 -0
- package/dist/services/component-registry.cjs.map +1 -0
- package/dist/services/component-registry.js +295 -0
- package/dist/services/component-registry.js.map +1 -0
- package/dist/services/validation.cjs +253 -0
- package/dist/services/validation.cjs.map +1 -0
- package/dist/services/validation.js +253 -0
- package/dist/services/validation.js.map +1 -0
- package/dist/utils/logger.cjs +31 -0
- package/dist/utils/logger.cjs.map +1 -0
- package/dist/utils/logger.js +31 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +6 -5
- package/dist/StreamingUIRenderer-DQ1WoVV6.cjs +0 -5
- package/dist/StreamingUIRenderer-DQ1WoVV6.cjs.map +0 -1
- package/dist/StreamingUIRenderer-oyg_cKKl.js +0 -757
- package/dist/StreamingUIRenderer-oyg_cKKl.js.map +0 -1
- package/dist/useStreamingUI-BL0nh13E.js +0 -187
- package/dist/useStreamingUI-BL0nh13E.js.map +0 -1
- package/dist/useStreamingUI-CXmvpRhz.cjs +0 -3
- package/dist/useStreamingUI-CXmvpRhz.cjs.map +0 -1
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
const DEFAULT_RESOURCE_LIMITS = {
|
|
2
|
+
maxDataPoints: 1e3,
|
|
3
|
+
maxTableRows: 100,
|
|
4
|
+
maxPayloadSize: 50 * 1024,
|
|
5
|
+
// 50KB
|
|
6
|
+
renderTimeout: 5e3
|
|
7
|
+
// 5 seconds
|
|
8
|
+
};
|
|
9
|
+
function validateGridPosition(position) {
|
|
10
|
+
const errors = [];
|
|
11
|
+
if (position.colStart < 1 || position.colStart > 12) {
|
|
12
|
+
errors.push({
|
|
13
|
+
path: "position.colStart",
|
|
14
|
+
message: "Column start must be between 1 and 12",
|
|
15
|
+
code: "INVALID_GRID_COL_START"
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
if (position.colSpan < 1 || position.colSpan > 12) {
|
|
19
|
+
errors.push({
|
|
20
|
+
path: "position.colSpan",
|
|
21
|
+
message: "Column span must be between 1 and 12",
|
|
22
|
+
code: "INVALID_GRID_COL_SPAN"
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
if (position.colStart + position.colSpan - 1 > 12) {
|
|
26
|
+
errors.push({
|
|
27
|
+
path: "position",
|
|
28
|
+
message: "Column start + span exceeds grid width (12)",
|
|
29
|
+
code: "GRID_OVERFLOW"
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
if (position.rowStart !== void 0 && position.rowStart < 1) {
|
|
33
|
+
errors.push({
|
|
34
|
+
path: "position.rowStart",
|
|
35
|
+
message: "Row start must be >= 1",
|
|
36
|
+
code: "INVALID_GRID_ROW_START"
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
if (position.rowSpan !== void 0 && position.rowSpan < 1) {
|
|
40
|
+
errors.push({
|
|
41
|
+
path: "position.rowSpan",
|
|
42
|
+
message: "Row span must be >= 1",
|
|
43
|
+
code: "INVALID_GRID_ROW_SPAN"
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
valid: errors.length === 0,
|
|
48
|
+
errors: errors.length > 0 ? errors : void 0
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function validateChartComponent(params, limits = DEFAULT_RESOURCE_LIMITS) {
|
|
52
|
+
const errors = [];
|
|
53
|
+
const totalDataPoints = params.data.datasets.reduce(
|
|
54
|
+
(sum, dataset) => sum + dataset.data.length,
|
|
55
|
+
0
|
|
56
|
+
);
|
|
57
|
+
if (totalDataPoints > limits.maxDataPoints) {
|
|
58
|
+
errors.push({
|
|
59
|
+
path: "params.data",
|
|
60
|
+
message: `Chart exceeds max data points: ${totalDataPoints} > ${limits.maxDataPoints}`,
|
|
61
|
+
code: "RESOURCE_LIMIT_EXCEEDED"
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const expectedLength = params.data.labels.length;
|
|
65
|
+
for (const [index, dataset] of params.data.datasets.entries()) {
|
|
66
|
+
if (dataset.data.length !== expectedLength) {
|
|
67
|
+
errors.push({
|
|
68
|
+
path: `params.data.datasets[${index}]`,
|
|
69
|
+
message: `Dataset length mismatch: expected ${expectedLength}, got ${dataset.data.length}`,
|
|
70
|
+
code: "DATA_LENGTH_MISMATCH"
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const [index, dataset] of params.data.datasets.entries()) {
|
|
75
|
+
for (const [dataIndex, value] of dataset.data.entries()) {
|
|
76
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
77
|
+
errors.push({
|
|
78
|
+
path: `params.data.datasets[${index}].data[${dataIndex}]`,
|
|
79
|
+
message: `Invalid data value: ${value} (must be finite number)`,
|
|
80
|
+
code: "INVALID_DATA_TYPE"
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
valid: errors.length === 0,
|
|
87
|
+
errors: errors.length > 0 ? errors : void 0
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function validateTableComponent(params, limits = DEFAULT_RESOURCE_LIMITS) {
|
|
91
|
+
const errors = [];
|
|
92
|
+
if (params.rows.length > limits.maxTableRows) {
|
|
93
|
+
errors.push({
|
|
94
|
+
path: "params.rows",
|
|
95
|
+
message: `Table exceeds max rows: ${params.rows.length} > ${limits.maxTableRows}`,
|
|
96
|
+
code: "RESOURCE_LIMIT_EXCEEDED"
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (params.columns.length === 0) {
|
|
100
|
+
errors.push({
|
|
101
|
+
path: "params.columns",
|
|
102
|
+
message: "Table must have at least one column",
|
|
103
|
+
code: "EMPTY_COLUMNS"
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const columnKeys = /* @__PURE__ */ new Set();
|
|
107
|
+
for (const [index, column] of params.columns.entries()) {
|
|
108
|
+
if (columnKeys.has(column.key)) {
|
|
109
|
+
errors.push({
|
|
110
|
+
path: `params.columns[${index}]`,
|
|
111
|
+
message: `Duplicate column key: ${column.key}`,
|
|
112
|
+
code: "DUPLICATE_COLUMN_KEY"
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
columnKeys.add(column.key);
|
|
116
|
+
}
|
|
117
|
+
for (const [rowIndex, row] of params.rows.entries()) {
|
|
118
|
+
for (const column of params.columns) {
|
|
119
|
+
if (!(column.key in row)) {
|
|
120
|
+
errors.push({
|
|
121
|
+
path: `params.rows[${rowIndex}]`,
|
|
122
|
+
message: `Missing column key: ${column.key}`,
|
|
123
|
+
code: "MISSING_COLUMN_DATA"
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
return {
|
|
129
|
+
valid: errors.length === 0,
|
|
130
|
+
errors: errors.length > 0 ? errors : void 0
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
function validatePayloadSize(component, limits = DEFAULT_RESOURCE_LIMITS) {
|
|
134
|
+
const payloadSize = JSON.stringify(component).length;
|
|
135
|
+
if (payloadSize > limits.maxPayloadSize) {
|
|
136
|
+
return {
|
|
137
|
+
valid: false,
|
|
138
|
+
errors: [
|
|
139
|
+
{
|
|
140
|
+
path: "component",
|
|
141
|
+
message: `Payload size exceeds limit: ${payloadSize} > ${limits.maxPayloadSize} bytes`,
|
|
142
|
+
code: "PAYLOAD_TOO_LARGE"
|
|
143
|
+
}
|
|
144
|
+
]
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
return { valid: true };
|
|
148
|
+
}
|
|
149
|
+
function validateComponent(component, limits = DEFAULT_RESOURCE_LIMITS) {
|
|
150
|
+
const errors = [];
|
|
151
|
+
const gridResult = validateGridPosition(component.position);
|
|
152
|
+
if (!gridResult.valid) {
|
|
153
|
+
errors.push(...gridResult.errors || []);
|
|
154
|
+
}
|
|
155
|
+
const sizeResult = validatePayloadSize(component, limits);
|
|
156
|
+
if (!sizeResult.valid) {
|
|
157
|
+
errors.push(...sizeResult.errors || []);
|
|
158
|
+
}
|
|
159
|
+
switch (component.type) {
|
|
160
|
+
case "chart":
|
|
161
|
+
const chartResult = validateChartComponent(component.params, limits);
|
|
162
|
+
if (!chartResult.valid) {
|
|
163
|
+
errors.push(...chartResult.errors || []);
|
|
164
|
+
}
|
|
165
|
+
break;
|
|
166
|
+
case "table":
|
|
167
|
+
const tableResult = validateTableComponent(component.params, limits);
|
|
168
|
+
if (!tableResult.valid) {
|
|
169
|
+
errors.push(...tableResult.errors || []);
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
case "metric":
|
|
173
|
+
const metricParams = component.params;
|
|
174
|
+
if (!metricParams.title || !metricParams.value) {
|
|
175
|
+
errors.push({
|
|
176
|
+
path: "params",
|
|
177
|
+
message: "Metric must have title and value",
|
|
178
|
+
code: "INVALID_METRIC"
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
break;
|
|
182
|
+
case "text":
|
|
183
|
+
const textParams = component.params;
|
|
184
|
+
if (!textParams.content) {
|
|
185
|
+
errors.push({
|
|
186
|
+
path: "params",
|
|
187
|
+
message: "Text component must have content",
|
|
188
|
+
code: "INVALID_TEXT"
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
break;
|
|
192
|
+
default:
|
|
193
|
+
errors.push({
|
|
194
|
+
path: "type",
|
|
195
|
+
message: `Unknown component type: ${component.type}`,
|
|
196
|
+
code: "UNKNOWN_COMPONENT_TYPE"
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
valid: errors.length === 0,
|
|
201
|
+
errors: errors.length > 0 ? errors : void 0
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
function validateLayout(layout, limits = DEFAULT_RESOURCE_LIMITS) {
|
|
205
|
+
var _a;
|
|
206
|
+
const errors = [];
|
|
207
|
+
if (layout.components.length === 0) {
|
|
208
|
+
errors.push({
|
|
209
|
+
path: "components",
|
|
210
|
+
message: "Layout must have at least one component",
|
|
211
|
+
code: "EMPTY_LAYOUT"
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
if (layout.components.length > 12) {
|
|
215
|
+
errors.push({
|
|
216
|
+
path: "components",
|
|
217
|
+
message: `Layout exceeds max components: ${layout.components.length} > 12`,
|
|
218
|
+
code: "TOO_MANY_COMPONENTS"
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
for (const [index, component] of layout.components.entries()) {
|
|
222
|
+
const result = validateComponent(component, limits);
|
|
223
|
+
if (!result.valid) {
|
|
224
|
+
errors.push(
|
|
225
|
+
...((_a = result.errors) == null ? void 0 : _a.map((error) => ({
|
|
226
|
+
...error,
|
|
227
|
+
path: `components[${index}].${error.path}`
|
|
228
|
+
}))) || []
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
if (layout.grid.columns !== 12) {
|
|
233
|
+
errors.push({
|
|
234
|
+
path: "grid.columns",
|
|
235
|
+
message: "Grid must have 12 columns (Bootstrap-like)",
|
|
236
|
+
code: "INVALID_GRID_COLUMNS"
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
valid: errors.length === 0,
|
|
241
|
+
errors: errors.length > 0 ? errors : void 0
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
export {
|
|
245
|
+
DEFAULT_RESOURCE_LIMITS,
|
|
246
|
+
validateChartComponent,
|
|
247
|
+
validateComponent,
|
|
248
|
+
validateGridPosition,
|
|
249
|
+
validateLayout,
|
|
250
|
+
validatePayloadSize,
|
|
251
|
+
validateTableComponent
|
|
252
|
+
};
|
|
253
|
+
//# sourceMappingURL=validation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.js","sources":["../../src/services/validation.ts"],"sourcesContent":["/**\n * Component Validation Service\n * Phase 0: Resource Limits & Schema Validation\n *\n * Validates LLM-generated components against:\n * - JSON schema\n * - Resource limits (data points, payload size, grid bounds)\n * - Security constraints (domain whitelist, XSS prevention)\n */\n\nimport type {\n UIComponent,\n UILayout,\n ValidationResult,\n ResourceLimits,\n ChartComponentParams,\n TableComponentParams,\n} from '../types'\n\n/**\n * Default resource limits (configurable via env)\n */\nexport const DEFAULT_RESOURCE_LIMITS: ResourceLimits = {\n maxDataPoints: 1000,\n maxTableRows: 100,\n maxPayloadSize: 50 * 1024, // 50KB\n renderTimeout: 5000, // 5 seconds\n}\n\n/**\n * Allowed iframe domains (whitelist)\n * Must match CSP frame-src directive\n */\nconst ALLOWED_IFRAME_DOMAINS = [\n 'quickchart.io',\n 'www.quickchart.io',\n 'deposium.com',\n 'deposium.vip',\n 'localhost',\n]\n\n/**\n * Validate grid position bounds (1-12 columns)\n */\nexport function validateGridPosition(position: UIComponent['position']): ValidationResult {\n const errors: ValidationResult['errors'] = []\n\n if (position.colStart < 1 || position.colStart > 12) {\n errors.push({\n path: 'position.colStart',\n message: 'Column start must be between 1 and 12',\n code: 'INVALID_GRID_COL_START',\n })\n }\n\n if (position.colSpan < 1 || position.colSpan > 12) {\n errors.push({\n path: 'position.colSpan',\n message: 'Column span must be between 1 and 12',\n code: 'INVALID_GRID_COL_SPAN',\n })\n }\n\n if (position.colStart + position.colSpan - 1 > 12) {\n errors.push({\n path: 'position',\n message: 'Column start + span exceeds grid width (12)',\n code: 'GRID_OVERFLOW',\n })\n }\n\n if (position.rowStart !== undefined && position.rowStart < 1) {\n errors.push({\n path: 'position.rowStart',\n message: 'Row start must be >= 1',\n code: 'INVALID_GRID_ROW_START',\n })\n }\n\n if (position.rowSpan !== undefined && position.rowSpan < 1) {\n errors.push({\n path: 'position.rowSpan',\n message: 'Row span must be >= 1',\n code: 'INVALID_GRID_ROW_SPAN',\n })\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n }\n}\n\n/**\n * Validate chart component against resource limits\n */\nexport function validateChartComponent(\n params: ChartComponentParams,\n limits: ResourceLimits = DEFAULT_RESOURCE_LIMITS\n): ValidationResult {\n const errors: ValidationResult['errors'] = []\n\n // Validate data points count\n const totalDataPoints = params.data.datasets.reduce(\n (sum, dataset) => sum + dataset.data.length,\n 0\n )\n\n if (totalDataPoints > limits.maxDataPoints) {\n errors.push({\n path: 'params.data',\n message: `Chart exceeds max data points: ${totalDataPoints} > ${limits.maxDataPoints}`,\n code: 'RESOURCE_LIMIT_EXCEEDED',\n })\n }\n\n // Validate labels match dataset length\n const expectedLength = params.data.labels.length\n for (const [index, dataset] of params.data.datasets.entries()) {\n if (dataset.data.length !== expectedLength) {\n errors.push({\n path: `params.data.datasets[${index}]`,\n message: `Dataset length mismatch: expected ${expectedLength}, got ${dataset.data.length}`,\n code: 'DATA_LENGTH_MISMATCH',\n })\n }\n }\n\n // Validate numeric data\n for (const [index, dataset] of params.data.datasets.entries()) {\n for (const [dataIndex, value] of dataset.data.entries()) {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n errors.push({\n path: `params.data.datasets[${index}].data[${dataIndex}]`,\n message: `Invalid data value: ${value} (must be finite number)`,\n code: 'INVALID_DATA_TYPE',\n })\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n }\n}\n\n/**\n * Validate table component against resource limits\n */\nexport function validateTableComponent(\n params: TableComponentParams,\n limits: ResourceLimits = DEFAULT_RESOURCE_LIMITS\n): ValidationResult {\n const errors: ValidationResult['errors'] = []\n\n // Validate row count\n if (params.rows.length > limits.maxTableRows) {\n errors.push({\n path: 'params.rows',\n message: `Table exceeds max rows: ${params.rows.length} > ${limits.maxTableRows}`,\n code: 'RESOURCE_LIMIT_EXCEEDED',\n })\n }\n\n // Validate columns\n if (params.columns.length === 0) {\n errors.push({\n path: 'params.columns',\n message: 'Table must have at least one column',\n code: 'EMPTY_COLUMNS',\n })\n }\n\n // Validate column keys are unique\n const columnKeys = new Set<string>()\n for (const [index, column] of params.columns.entries()) {\n if (columnKeys.has(column.key)) {\n errors.push({\n path: `params.columns[${index}]`,\n message: `Duplicate column key: ${column.key}`,\n code: 'DUPLICATE_COLUMN_KEY',\n })\n }\n columnKeys.add(column.key)\n }\n\n // Validate rows have valid data for defined columns\n for (const [rowIndex, row] of params.rows.entries()) {\n for (const column of params.columns) {\n if (!(column.key in row)) {\n errors.push({\n path: `params.rows[${rowIndex}]`,\n message: `Missing column key: ${column.key}`,\n code: 'MISSING_COLUMN_DATA',\n })\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n }\n}\n\n/**\n * Validate payload size\n */\nexport function validatePayloadSize(\n component: UIComponent,\n limits: ResourceLimits = DEFAULT_RESOURCE_LIMITS\n): ValidationResult {\n const payloadSize = JSON.stringify(component).length\n\n if (payloadSize > limits.maxPayloadSize) {\n return {\n valid: false,\n errors: [\n {\n path: 'component',\n message: `Payload size exceeds limit: ${payloadSize} > ${limits.maxPayloadSize} bytes`,\n code: 'PAYLOAD_TOO_LARGE',\n },\n ],\n }\n }\n\n return { valid: true }\n}\n\n/**\n * Sanitize string to prevent XSS\n * Basic implementation - DOMPurify used at render time\n */\nexport function sanitizeString(input: string): string {\n return input\n .replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '')\n .replace(/on\\w+=\"[^\"]*\"/gi, '')\n .replace(/javascript:/gi, '')\n}\n\n/**\n * Validate iframe domain against whitelist\n */\nexport function validateIframeDomain(url: string): ValidationResult {\n try {\n const parsedUrl = new URL(url)\n const domain = parsedUrl.hostname\n\n const isAllowed = ALLOWED_IFRAME_DOMAINS.some(\n (allowed) => domain === allowed || domain.endsWith(`.${allowed}`) || allowed === 'localhost'\n )\n\n if (!isAllowed) {\n return {\n valid: false,\n errors: [\n {\n path: 'url',\n message: `Domain not whitelisted: ${domain}`,\n code: 'DOMAIN_NOT_WHITELISTED',\n },\n ],\n }\n }\n\n return { valid: true }\n } catch (error) {\n return {\n valid: false,\n errors: [\n {\n path: 'url',\n message: 'Invalid URL format',\n code: 'INVALID_URL',\n },\n ],\n }\n }\n}\n\n/**\n * Validate entire component\n */\nexport function validateComponent(\n component: UIComponent,\n limits: ResourceLimits = DEFAULT_RESOURCE_LIMITS\n): ValidationResult {\n const errors: ValidationResult['errors'] = []\n\n // Validate grid position\n const gridResult = validateGridPosition(component.position)\n if (!gridResult.valid) {\n errors.push(...(gridResult.errors || []))\n }\n\n // Validate payload size\n const sizeResult = validatePayloadSize(component, limits)\n if (!sizeResult.valid) {\n errors.push(...(sizeResult.errors || []))\n }\n\n // Type-specific validation\n switch (component.type) {\n case 'chart':\n const chartResult = validateChartComponent(component.params as ChartComponentParams, limits)\n if (!chartResult.valid) {\n errors.push(...(chartResult.errors || []))\n }\n break\n\n case 'table':\n const tableResult = validateTableComponent(component.params as TableComponentParams, limits)\n if (!tableResult.valid) {\n errors.push(...(tableResult.errors || []))\n }\n break\n\n case 'metric':\n // Basic validation for metrics\n const metricParams = component.params as any\n if (!metricParams.title || !metricParams.value) {\n errors.push({\n path: 'params',\n message: 'Metric must have title and value',\n code: 'INVALID_METRIC',\n })\n }\n break\n\n case 'text':\n // Basic validation for text\n const textParams = component.params as any\n if (!textParams.content) {\n errors.push({\n path: 'params',\n message: 'Text component must have content',\n code: 'INVALID_TEXT',\n })\n }\n break\n\n default:\n errors.push({\n path: 'type',\n message: `Unknown component type: ${component.type}`,\n code: 'UNKNOWN_COMPONENT_TYPE',\n })\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n }\n}\n\n/**\n * Validate entire layout\n */\nexport function validateLayout(\n layout: UILayout,\n limits: ResourceLimits = DEFAULT_RESOURCE_LIMITS\n): ValidationResult {\n const errors: ValidationResult['errors'] = []\n\n // Validate component count\n if (layout.components.length === 0) {\n errors.push({\n path: 'components',\n message: 'Layout must have at least one component',\n code: 'EMPTY_LAYOUT',\n })\n }\n\n if (layout.components.length > 12) {\n errors.push({\n path: 'components',\n message: `Layout exceeds max components: ${layout.components.length} > 12`,\n code: 'TOO_MANY_COMPONENTS',\n })\n }\n\n // Validate each component\n for (const [index, component] of layout.components.entries()) {\n const result = validateComponent(component, limits)\n if (!result.valid) {\n errors.push(\n ...(result.errors?.map((error) => ({\n ...error,\n path: `components[${index}].${error.path}`,\n })) || [])\n )\n }\n }\n\n // Validate grid configuration\n if (layout.grid.columns !== 12) {\n errors.push({\n path: 'grid.columns',\n message: 'Grid must have 12 columns (Bootstrap-like)',\n code: 'INVALID_GRID_COLUMNS',\n })\n }\n\n return {\n valid: errors.length === 0,\n errors: errors.length > 0 ? errors : undefined,\n }\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const isDev = typeof process !== "undefined" && process.env.NODE_ENV !== "production";
|
|
4
|
+
function formatLogMessage(feature, message, context) {
|
|
5
|
+
const contextStr = context ? ` ${JSON.stringify(context)}` : "";
|
|
6
|
+
return `[@seed-ship/mcp-ui-solid:${feature}] ${message}${contextStr}`;
|
|
7
|
+
}
|
|
8
|
+
function createLogger(feature) {
|
|
9
|
+
return {
|
|
10
|
+
info(message, context) {
|
|
11
|
+
if (isDev) {
|
|
12
|
+
console.info(formatLogMessage(feature, message, context));
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
warn(message, context) {
|
|
16
|
+
if (isDev) {
|
|
17
|
+
console.warn(formatLogMessage(feature, message, context));
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
error(message, context) {
|
|
21
|
+
console.error(formatLogMessage(feature, message, context));
|
|
22
|
+
},
|
|
23
|
+
debug(message, context) {
|
|
24
|
+
if (isDev) {
|
|
25
|
+
console.debug(formatLogMessage(feature, message, context));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
exports.createLogger = createLogger;
|
|
31
|
+
//# sourceMappingURL=logger.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.cjs","sources":["../../src/utils/logger.ts"],"sourcesContent":["/**\n * Simple internal logger utility\n *\n * Provides basic logging functionality for the package.\n * Consumers can disable logging by setting NODE_ENV=production\n * or by implementing their own logging solution.\n */\n\nconst isDev = typeof process !== 'undefined' && process.env.NODE_ENV !== 'production'\n\nexport interface Logger {\n info(message: string, context?: Record<string, unknown>): void\n warn(message: string, context?: Record<string, unknown>): void\n error(message: string, context?: Record<string, unknown>): void\n debug(message: string, context?: Record<string, unknown>): void\n}\n\nfunction formatLogMessage(\n feature: string,\n message: string,\n context?: Record<string, unknown>\n): string {\n const contextStr = context ? ` ${JSON.stringify(context)}` : ''\n return `[@seed-ship/mcp-ui-solid:${feature}] ${message}${contextStr}`\n}\n\n/**\n * Creates a feature-scoped logger\n *\n * @param feature - Feature name for log prefixing\n * @returns Logger instance\n *\n * @example\n * ```typescript\n * const logger = createLogger('my-component')\n * logger.info('Component mounted', { componentId: '123' })\n * ```\n */\nexport function createLogger(feature: string): Logger {\n return {\n info(message: string, context?: Record<string, unknown>) {\n if (isDev) {\n console.info(formatLogMessage(feature, message, context))\n }\n },\n\n warn(message: string, context?: Record<string, unknown>) {\n if (isDev) {\n console.warn(formatLogMessage(feature, message, context))\n }\n },\n\n error(message: string, context?: Record<string, unknown>) {\n // Always log errors, even in production\n console.error(formatLogMessage(feature, message, context))\n },\n\n debug(message: string, context?: Record<string, unknown>) {\n if (isDev) {\n console.debug(formatLogMessage(feature, message, context))\n }\n },\n }\n}\n\n/**\n * No-op logger for testing or when logging is disabled\n */\nexport const noopLogger: Logger = {\n info: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n}\n"],"names":[],"mappings":";;AAQA,MAAM,QAAQ,OAAO,YAAY,eAAe,QAAQ,IAAI,aAAa;AASzE,SAAS,iBACP,SACA,SACA,SACQ;AACR,QAAM,aAAa,UAAU,IAAI,KAAK,UAAU,OAAO,CAAC,KAAK;AAC7D,SAAO,4BAA4B,OAAO,KAAK,OAAO,GAAG,UAAU;AACrE;AAcO,SAAS,aAAa,SAAyB;AACpD,SAAO;AAAA,IACL,KAAK,SAAiB,SAAmC;AACvD,UAAI,OAAO;AACT,gBAAQ,KAAK,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,KAAK,SAAiB,SAAmC;AACvD,UAAI,OAAO;AACT,gBAAQ,KAAK,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,MAAM,SAAiB,SAAmC;AAExD,cAAQ,MAAM,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,IAC3D;AAAA,IAEA,MAAM,SAAiB,SAAmC;AACxD,UAAI,OAAO;AACT,gBAAQ,MAAM,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EAAA;AAEJ;;"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const isDev = typeof process !== "undefined" && process.env.NODE_ENV !== "production";
|
|
2
|
+
function formatLogMessage(feature, message, context) {
|
|
3
|
+
const contextStr = context ? ` ${JSON.stringify(context)}` : "";
|
|
4
|
+
return `[@seed-ship/mcp-ui-solid:${feature}] ${message}${contextStr}`;
|
|
5
|
+
}
|
|
6
|
+
function createLogger(feature) {
|
|
7
|
+
return {
|
|
8
|
+
info(message, context) {
|
|
9
|
+
if (isDev) {
|
|
10
|
+
console.info(formatLogMessage(feature, message, context));
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
warn(message, context) {
|
|
14
|
+
if (isDev) {
|
|
15
|
+
console.warn(formatLogMessage(feature, message, context));
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
error(message, context) {
|
|
19
|
+
console.error(formatLogMessage(feature, message, context));
|
|
20
|
+
},
|
|
21
|
+
debug(message, context) {
|
|
22
|
+
if (isDev) {
|
|
23
|
+
console.debug(formatLogMessage(feature, message, context));
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
export {
|
|
29
|
+
createLogger
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sources":["../../src/utils/logger.ts"],"sourcesContent":["/**\n * Simple internal logger utility\n *\n * Provides basic logging functionality for the package.\n * Consumers can disable logging by setting NODE_ENV=production\n * or by implementing their own logging solution.\n */\n\nconst isDev = typeof process !== 'undefined' && process.env.NODE_ENV !== 'production'\n\nexport interface Logger {\n info(message: string, context?: Record<string, unknown>): void\n warn(message: string, context?: Record<string, unknown>): void\n error(message: string, context?: Record<string, unknown>): void\n debug(message: string, context?: Record<string, unknown>): void\n}\n\nfunction formatLogMessage(\n feature: string,\n message: string,\n context?: Record<string, unknown>\n): string {\n const contextStr = context ? ` ${JSON.stringify(context)}` : ''\n return `[@seed-ship/mcp-ui-solid:${feature}] ${message}${contextStr}`\n}\n\n/**\n * Creates a feature-scoped logger\n *\n * @param feature - Feature name for log prefixing\n * @returns Logger instance\n *\n * @example\n * ```typescript\n * const logger = createLogger('my-component')\n * logger.info('Component mounted', { componentId: '123' })\n * ```\n */\nexport function createLogger(feature: string): Logger {\n return {\n info(message: string, context?: Record<string, unknown>) {\n if (isDev) {\n console.info(formatLogMessage(feature, message, context))\n }\n },\n\n warn(message: string, context?: Record<string, unknown>) {\n if (isDev) {\n console.warn(formatLogMessage(feature, message, context))\n }\n },\n\n error(message: string, context?: Record<string, unknown>) {\n // Always log errors, even in production\n console.error(formatLogMessage(feature, message, context))\n },\n\n debug(message: string, context?: Record<string, unknown>) {\n if (isDev) {\n console.debug(formatLogMessage(feature, message, context))\n }\n },\n }\n}\n\n/**\n * No-op logger for testing or when logging is disabled\n */\nexport const noopLogger: Logger = {\n info: () => {},\n warn: () => {},\n error: () => {},\n debug: () => {},\n}\n"],"names":[],"mappings":"AAQA,MAAM,QAAQ,OAAO,YAAY,eAAe,QAAQ,IAAI,aAAa;AASzE,SAAS,iBACP,SACA,SACA,SACQ;AACR,QAAM,aAAa,UAAU,IAAI,KAAK,UAAU,OAAO,CAAC,KAAK;AAC7D,SAAO,4BAA4B,OAAO,KAAK,OAAO,GAAG,UAAU;AACrE;AAcO,SAAS,aAAa,SAAyB;AACpD,SAAO;AAAA,IACL,KAAK,SAAiB,SAAmC;AACvD,UAAI,OAAO;AACT,gBAAQ,KAAK,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,KAAK,SAAiB,SAAmC;AACvD,UAAI,OAAO;AACT,gBAAQ,KAAK,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,MAC1D;AAAA,IACF;AAAA,IAEA,MAAM,SAAiB,SAAmC;AAExD,cAAQ,MAAM,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,IAC3D;AAAA,IAEA,MAAM,SAAiB,SAAmC;AACxD,UAAI,OAAO;AACT,gBAAQ,MAAM,iBAAiB,SAAS,SAAS,OAAO,CAAC;AAAA,MAC3D;AAAA,IACF;AAAA,EAAA;AAEJ;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-ship/mcp-ui-solid",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "SolidJS components for rendering MCP-generated UI resources",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"CHANGELOG.md"
|
|
35
35
|
],
|
|
36
36
|
"peerDependencies": {
|
|
37
|
-
"solid-js": "^1.
|
|
37
|
+
"solid-js": "^1.9.0"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
40
|
"zod": "^3.22.4"
|
|
@@ -47,10 +47,11 @@
|
|
|
47
47
|
"@vitest/ui": "^4.0.9",
|
|
48
48
|
"eslint": "^8.56.0",
|
|
49
49
|
"jsdom": "^27.2.0",
|
|
50
|
+
"solid-js": "^1.9.10",
|
|
50
51
|
"typescript": "^5.3.3",
|
|
51
|
-
"vite": "^
|
|
52
|
-
"vite-plugin-solid": "^2.8
|
|
53
|
-
"vitest": "^
|
|
52
|
+
"vite": "^6.3.6",
|
|
53
|
+
"vite-plugin-solid": "^2.11.8",
|
|
54
|
+
"vitest": "^4.0.8"
|
|
54
55
|
},
|
|
55
56
|
"keywords": [
|
|
56
57
|
"mcp",
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
"use strict";const e=require("solid-js/web"),d=require("solid-js"),A=require("./useStreamingUI-CXmvpRhz.cjs"),_={maxDataPoints:1e3,maxTableRows:100,maxPayloadSize:50*1024,renderTimeout:5e3};function V(t){const r=[];return(t.colStart<1||t.colStart>12)&&r.push({path:"position.colStart",message:"Column start must be between 1 and 12",code:"INVALID_GRID_COL_START"}),(t.colSpan<1||t.colSpan>12)&&r.push({path:"position.colSpan",message:"Column span must be between 1 and 12",code:"INVALID_GRID_COL_SPAN"}),t.colStart+t.colSpan-1>12&&r.push({path:"position",message:"Column start + span exceeds grid width (12)",code:"GRID_OVERFLOW"}),t.rowStart!==void 0&&t.rowStart<1&&r.push({path:"position.rowStart",message:"Row start must be >= 1",code:"INVALID_GRID_ROW_START"}),t.rowSpan!==void 0&&t.rowSpan<1&&r.push({path:"position.rowSpan",message:"Row span must be >= 1",code:"INVALID_GRID_ROW_SPAN"}),{valid:r.length===0,errors:r.length>0?r:void 0}}function Y(t,r=_){const n=[],i=t.data.datasets.reduce((l,a)=>l+a.data.length,0);i>r.maxDataPoints&&n.push({path:"params.data",message:`Chart exceeds max data points: ${i} > ${r.maxDataPoints}`,code:"RESOURCE_LIMIT_EXCEEDED"});const o=t.data.labels.length;for(const[l,a]of t.data.datasets.entries())a.data.length!==o&&n.push({path:`params.data.datasets[${l}]`,message:`Dataset length mismatch: expected ${o}, got ${a.data.length}`,code:"DATA_LENGTH_MISMATCH"});for(const[l,a]of t.data.datasets.entries())for(const[s,c]of a.data.entries())(typeof c!="number"||!Number.isFinite(c))&&n.push({path:`params.data.datasets[${l}].data[${s}]`,message:`Invalid data value: ${c} (must be finite number)`,code:"INVALID_DATA_TYPE"});return{valid:n.length===0,errors:n.length>0?n:void 0}}function j(t,r=_){const n=[];t.rows.length>r.maxTableRows&&n.push({path:"params.rows",message:`Table exceeds max rows: ${t.rows.length} > ${r.maxTableRows}`,code:"RESOURCE_LIMIT_EXCEEDED"}),t.columns.length===0&&n.push({path:"params.columns",message:"Table must have at least one column",code:"EMPTY_COLUMNS"});const i=new Set;for(const[o,l]of t.columns.entries())i.has(l.key)&&n.push({path:`params.columns[${o}]`,message:`Duplicate column key: ${l.key}`,code:"DUPLICATE_COLUMN_KEY"}),i.add(l.key);for(const[o,l]of t.rows.entries())for(const a of t.columns)a.key in l||n.push({path:`params.rows[${o}]`,message:`Missing column key: ${a.key}`,code:"MISSING_COLUMN_DATA"});return{valid:n.length===0,errors:n.length>0?n:void 0}}function B(t,r=_){const n=JSON.stringify(t).length;return n>r.maxPayloadSize?{valid:!1,errors:[{path:"component",message:`Payload size exceeds limit: ${n} > ${r.maxPayloadSize} bytes`,code:"PAYLOAD_TOO_LARGE"}]}:{valid:!0}}function b(t,r=_){const n=[],i=V(t.position);i.valid||n.push(...i.errors||[]);const o=B(t,r);switch(o.valid||n.push(...o.errors||[]),t.type){case"chart":const l=Y(t.params,r);l.valid||n.push(...l.errors||[]);break;case"table":const a=j(t.params,r);a.valid||n.push(...a.errors||[]);break;case"metric":const s=t.params;(!s.title||!s.value)&&n.push({path:"params",message:"Metric must have title and value",code:"INVALID_METRIC"});break;case"text":t.params.content||n.push({path:"params",message:"Text component must have content",code:"INVALID_TEXT"});break;default:n.push({path:"type",message:`Unknown component type: ${t.type}`,code:"UNKNOWN_COMPONENT_TYPE"})}return{valid:n.length===0,errors:n.length>0?n:void 0}}function q(t,r=_){var i;const n=[];t.components.length===0&&n.push({path:"components",message:"Layout must have at least one component",code:"EMPTY_LAYOUT"}),t.components.length>12&&n.push({path:"components",message:`Layout exceeds max components: ${t.components.length} > 12`,code:"TOO_MANY_COMPONENTS"});for(const[o,l]of t.components.entries()){const a=b(l,r);a.valid||n.push(...((i=a.errors)==null?void 0:i.map(s=>({...s,path:`components[${o}].${s.path}`})))||[])}return t.grid.columns!==12&&n.push({path:"grid.columns",message:"Grid must have 12 columns (Bootstrap-like)",code:"INVALID_GRID_COLUMNS"}),{valid:n.length===0,errors:n.length>0?n:void 0}}var K=e.template('<p class="text-xs text-yellow-600 dark:text-yellow-400 mt-2 font-mono">'),W=e.template('<button class="mt-3 text-xs font-medium text-yellow-800 dark:text-yellow-200 hover:text-yellow-900 dark:hover:text-yellow-100 underline">Retry Rendering'),H=e.template('<div class="w-full h-full bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-4"><div class="flex items-start gap-3"><div class=flex-shrink-0><svg class="w-5 h-5 text-yellow-600 dark:text-yellow-400"fill=none stroke=currentColor viewBox="0 0 24 24"><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"></path></svg></div><div class="flex-1 min-w-0"><p class="text-sm font-medium text-yellow-900 dark:text-yellow-100">Component Failed to Render</p><p class="text-xs text-yellow-700 dark:text-yellow-300 mt-1">Type: <!> | ID: <!>...');const P=A.createLogger("generative-ui");function J(t){return(()=>{var r=H(),n=r.firstChild,i=n.firstChild,o=i.nextSibling,l=o.firstChild,a=l.nextSibling,s=a.firstChild,c=s.nextSibling,g=c.nextSibling,m=g.nextSibling;return m.nextSibling,e.insert(a,()=>t.componentType,c),e.insert(a,()=>t.componentId.slice(0,8),m),e.insert(o,e.createComponent(d.Show,{get when(){return!1},get children(){var u=K();return e.insert(u,()=>t.error.message),u}}),null),e.insert(o,e.createComponent(d.Show,{get when(){return t.allowRetry},get children(){var u=W();return e.addEventListener(u,"click",t.onRetry,!0),u}}),null),r})()}const S=t=>{const[r,n]=d.createSignal(0),[i]=d.createSignal(performance.now()),o=a=>{var m;const c=performance.now()-i(),g={componentId:t.componentId,componentType:t.componentType,errorMessage:a.message,errorStack:a.stack,renderDuration:c,retryCount:r(),timestamp:new Date().toISOString(),userAgent:navigator.userAgent,viewport:{width:window.innerWidth,height:window.innerHeight}};P.error(`Component render failed: ${t.componentType}`,g),(m=t.onError)==null||m.call(t,{type:"render",message:a.message,componentId:t.componentId,details:g})},l=()=>{const a=r()+1;P.info(`Retrying component render: ${t.componentType}`,{componentId:t.componentId,retryCount:a}),n(a)};return e.createComponent(d.ErrorBoundary,{fallback:a=>(o(a),t.fallback?t.fallback(a,t.allowRetry?l:void 0):e.createComponent(J,{error:a,get componentId(){return t.componentId},get componentType(){return t.componentType},get allowRetry(){return t.allowRetry},onRetry:l})),get children(){return r(),e.memo(()=>t.children)}})};e.delegateEvents(["click"]);var X=e.template('<div class="absolute inset-0 flex items-center justify-center"><div class="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600">'),Q=e.template('<div class="absolute inset-0 flex items-center justify-center p-4"><div class=text-center><p class="text-red-600 dark:text-red-400 text-sm font-medium">Chart Error</p><p class="text-gray-600 dark:text-gray-400 text-xs mt-1">'),N=e.template('<h3 class="text-sm font-semibold text-gray-900 dark:text-white mb-3">'),Z=e.template('<div class="w-full h-full p-4"><div class="w-full h-full"><img alt="Chart visualization"class="w-full h-auto max-h-[300px] object-contain">'),ee=e.template('<div class="relative w-full h-full min-h-[300px] bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden">'),te=e.template('<div class="mt-3 flex items-center justify-between text-xs text-gray-500 dark:text-gray-400"><span>Showing <!> - <!> of '),re=e.template('<div class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 overflow-hidden"><div class=p-4><div class=overflow-x-auto><table class="min-w-full divide-y divide-gray-200 dark:divide-gray-700"><thead class="bg-gray-50 dark:bg-gray-900"><tr></tr></thead><tbody class="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">'),ne=e.template('<th scope=col class="px-4 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">'),ae=e.template('<tr class="hover:bg-gray-50 dark:hover:bg-gray-700 transition-colors">'),le=e.template('<td class="px-4 py-3 text-sm text-gray-900 dark:text-gray-100 whitespace-nowrap">'),oe=e.template('<span class="ml-2 text-sm font-medium text-gray-500 dark:text-gray-400">'),ie=e.template('<div class="mt-3 flex items-center"><span> <!>%'),se=e.template('<p class="mt-2 text-xs text-gray-500 dark:text-gray-400">'),de=e.template('<div class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><div class="flex flex-col h-full justify-between"><div><p class="text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide"></p><div class="mt-2 flex items-baseline"><p class="text-2xl font-semibold text-gray-900 dark:text-white">'),ce=e.template('<div class="w-full h-full bg-white dark:bg-gray-800 rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-4"><div>'),me=e.template('<div class="w-full h-full bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4"><p class="text-sm font-medium text-red-900 dark:text-red-100">Validation Error</p><p class="text-xs text-red-700 dark:text-red-300 mt-1">'),ue=e.template('<div><div class="grid gap-4">'),ge=e.template("<div>");function he(t){const[r,n]=d.createSignal(),[i,o]=d.createSignal(!0),[l,a]=d.createSignal();return d.onMount(()=>{const s=t.component.params,c={type:s.type,data:s.data,options:{...s.options,responsive:!0,maintainAspectRatio:!1}},m=`https://quickchart.io/chart?c=${encodeURIComponent(JSON.stringify(c))}&width=500&height=300&devicePixelRatio=2`;n(m),o(!1)}),(()=>{var s=ee();return e.insert(s,e.createComponent(d.Show,{get when(){return i()},get children(){return X()}}),null),e.insert(s,e.createComponent(d.Show,{get when(){return l()},get children(){var c=Q(),g=c.firstChild,m=g.firstChild,u=m.nextSibling;return e.insert(u,l),c}}),null),e.insert(s,e.createComponent(d.Show,{get when(){return e.memo(()=>!!r())()&&!l()},get children(){var c=Z(),g=c.firstChild,m=g.firstChild;return e.insert(c,e.createComponent(d.Show,{get when(){return t.component.params.title},get children(){var u=N();return e.insert(u,()=>t.component.params.title),u}}),g),m.addEventListener("error",()=>{var u;a("Failed to load chart"),(u=t.onError)==null||u.call(t,{type:"render",message:"Chart rendering failed",componentId:t.component.id})}),e.effect(()=>e.setAttribute(m,"src",r())),c}}),null),s})()}function pe(t){const r=t.component.params;return(()=>{var n=re(),i=n.firstChild,o=i.firstChild,l=o.firstChild,a=l.firstChild,s=a.firstChild,c=a.nextSibling;return e.insert(i,e.createComponent(d.Show,{get when(){return r.title},get children(){var g=N();return e.insert(g,()=>r.title),g}}),o),e.insert(s,e.createComponent(d.For,{get each(){return r.columns},children:g=>(()=>{var m=ne();return e.insert(m,()=>g.label),e.effect(u=>e.style(m,g.width?{width:g.width}:{},u)),m})()})),e.insert(c,e.createComponent(d.For,{get each(){return r.rows.slice(0,_.maxTableRows)},children:g=>(()=>{var m=ae();return e.insert(m,e.createComponent(d.For,{get each(){return r.columns},children:u=>(()=>{var x=le();return e.insert(x,()=>g[u.key]||"-"),x})()})),m})()})),e.insert(i,e.createComponent(d.Show,{get when(){return r.pagination},get children(){var g=te(),m=g.firstChild,u=m.firstChild,x=u.nextSibling,h=x.nextSibling,v=h.nextSibling;return v.nextSibling,e.insert(m,()=>r.pagination.currentPage*r.pagination.pageSize+1,x),e.insert(m,()=>Math.min((r.pagination.currentPage+1)*r.pagination.pageSize,r.pagination.totalRows),v),e.insert(m,()=>r.pagination.totalRows,null),g}}),null),n})()}function ve(t){const r=t.component.params;return(()=>{var n=de(),i=n.firstChild,o=i.firstChild,l=o.firstChild,a=l.nextSibling,s=a.firstChild;return e.insert(l,()=>r.title),e.insert(s,()=>r.value),e.insert(a,e.createComponent(d.Show,{get when(){return r.unit},get children(){var c=oe();return e.insert(c,()=>r.unit),c}}),null),e.insert(i,e.createComponent(d.Show,{get when(){return r.trend},get children(){var c=ie(),g=c.firstChild,m=g.firstChild,u=m.nextSibling;return u.nextSibling,e.insert(g,(()=>{var x=e.memo(()=>r.trend.direction==="up");return()=>(x()||r.trend.direction==="down","�")})(),m),e.insert(g,()=>Math.abs(r.trend.value),u),e.effect(()=>e.className(g,`text-sm font-medium ${r.trend.direction==="up"?"text-green-600 dark:text-green-400":r.trend.direction==="down"?"text-red-600 dark:text-red-400":"text-gray-600 dark:text-gray-400"}`)),c}}),null),e.insert(i,e.createComponent(d.Show,{get when(){return r.subtitle},get children(){var c=se();return e.insert(c,()=>r.subtitle),c}}),null),n})()}function fe(t){const r=t.component.params;return(()=>{var n=ce(),i=n.firstChild;return e.effect(o=>{var l=`prose prose-sm dark:prose-invert max-w-none ${r.className||""}`,a=r.content;return l!==o.e&&e.className(i,o.e=l),a!==o.t&&(i.innerHTML=o.t=a),o},{e:void 0,t:void 0}),n})()}function xe(t){var n;const r=b(t.component);return r.valid?e.createComponent(S,{get componentId(){return t.component.id},get componentType(){return t.component.type},get onError(){return t.onError},allowRetry:!0,get children(){return[e.createComponent(d.Show,{get when(){return t.component.type==="chart"},get children(){return e.createComponent(he,{get component(){return t.component},get onError(){return t.onError}})}}),e.createComponent(d.Show,{get when(){return t.component.type==="table"},get children(){return e.createComponent(pe,{get component(){return t.component},get onError(){return t.onError}})}}),e.createComponent(d.Show,{get when(){return t.component.type==="metric"},get children(){return e.createComponent(ve,{get component(){return t.component}})}}),e.createComponent(d.Show,{get when(){return t.component.type==="text"},get children(){return e.createComponent(fe,{get component(){return t.component}})}})]}}):((n=t.onError)==null||n.call(t,{type:"validation",message:"Component validation failed",componentId:t.component.id,details:r.errors}),(()=>{var i=me(),o=i.firstChild,l=o.nextSibling;return e.insert(l,()=>{var a,s;return((s=(a=r.errors)==null?void 0:a[0])==null?void 0:s.message)||"Unknown validation error"}),i})())}const $e=t=>{const r=()=>"type"in t.content?{id:"single-component",components:[t.content],grid:{columns:12,gap:"1rem"}}:t.content,n=i=>{const{colStart:o,colSpan:l,rowStart:a,rowSpan:s=1}=i.position;return{"grid-column":`${o} / span ${l}`,"grid-row":a?`${a} / span ${s}`:"auto"}};return(()=>{var i=ue(),o=i.firstChild;return e.insert(o,e.createComponent(d.For,{get each(){return r().components},children:l=>(()=>{var a=ge();return e.insert(a,e.createComponent(xe,{component:l,get onError(){return t.onError}})),e.effect(s=>e.style(a,n(l),s)),a})()})),e.effect(l=>{var a=`w-full ${t.class||""}`,s=`repeat(${r().grid.columns}, 1fr)`,c=r().grid.gap;return a!==l.e&&e.className(i,l.e=a),s!==l.t&&e.setStyleProperty(o,"grid-template-columns",l.t=s),c!==l.a&&e.setStyleProperty(o,"gap",l.a=c),l},{e:void 0,t:void 0,a:void 0}),i})()};var ye=e.template('<div class="w-full bg-error-subtle border border-border-error rounded-lg p-4"><p class="text-sm font-medium text-error-primary">Validation Error</p><p class="text-xs text-text-secondary mt-1">'),we=e.template('<h3 class="text-sm font-semibold text-text-primary">'),_e=e.template('<span class="text-sm text-text-secondary">'),be=e.template('<div class=mt-2><p class="text-2xl font-semibold text-text-primary">'),Ce=e.template('<div class="w-full bg-surface-secondary border border-border-subtle rounded-lg p-4"><div class="flex items-center gap-2 mb-2"><span class="text-xs font-medium text-text-tertiary uppercase"></span></div><div class="mt-3 text-xs text-text-tertiary">Component ID: <!>...'),Se=e.template('<span class="text-sm text-text-secondary"> / '),ke=e.template('<div class=mt-2><div class="h-1 w-full overflow-hidden rounded-full bg-surface-tertiary"><div class="animate-progress-indeterminate h-full w-1/3 bg-brand-primary">'),Ie=e.template('<div class="mb-4 rounded-lg border border-border-subtle bg-surface-secondary p-4"><div class="mb-2 flex items-center justify-between"><span class="text-sm font-medium text-text-primary"></span></div><div class="h-2 w-full overflow-hidden rounded-full bg-surface-tertiary"><div class="h-full bg-brand-primary transition-all duration-300 ease-out">'),Re=e.template('<button type=button class="mt-3 rounded-md bg-error-primary px-3 py-1.5 text-sm font-medium text-white hover:bg-error-hover">Retry'),Ee=e.template('<div class="mb-4 rounded-lg border border-border-error bg-error-subtle p-4"><div class="mb-2 flex items-center gap-2"><svg class="h-5 w-5 text-error-primary"fill=none viewBox="0 0 24 24"stroke=currentColor><path stroke-linecap=round stroke-linejoin=round stroke-width=2 d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg><span class="font-medium text-error-primary"></span></div><p class="text-sm text-text-secondary">'),Te=e.template('<div><div class="font-medium text-text-primary">Cost</div><div>$'),Le=e.template('<div><div class="font-medium text-text-primary">Cached</div><div class=text-success-primary>Yes'),De=e.template('<div class="mt-6 rounded-lg border border-border-subtle bg-surface-secondary p-4 text-sm text-text-secondary"><div class="grid grid-cols-2 gap-4 md:grid-cols-4"><div><div class="font-medium text-text-primary">Provider</div><div></div></div><div><div class="font-medium text-text-primary">Model</div><div></div></div><div><div class="font-medium text-text-primary">Execution Time</div><div>ms</div></div><div><div class="font-medium text-text-primary">TTFB</div><div>ms'),Pe=e.template('<div><div class="grid grid-cols-12 gap-4">'),Ae=e.template("<div>"),Ne=e.template('<div class="col-span-12 md:col-span-6 lg:col-span-4"><div class="animate-pulse rounded-lg border border-border-subtle bg-surface-secondary p-4"><div class="mb-4 h-6 w-1/2 rounded bg-surface-tertiary"></div><div class=space-y-3><div class="h-4 rounded bg-surface-tertiary"></div><div class="h-4 w-5/6 rounded bg-surface-tertiary"></div><div class="h-4 w-4/6 rounded bg-surface-tertiary"></div></div><div class="mt-4 h-32 rounded bg-surface-tertiary">');function Me(t){var i;const r=b(t.component);if(!r.valid)return(i=t.onError)==null||i.call(t,{type:"validation",message:"Component validation failed",componentId:t.component.id,details:r.errors}),(()=>{var o=ye(),l=o.firstChild,a=l.nextSibling;return e.insert(a,()=>{var s,c;return((c=(s=r.errors)==null?void 0:s[0])==null?void 0:c.message)||"Unknown validation error"}),o})();const n=t.component.params;return e.createComponent(S,{get componentId(){return t.component.id},get componentType(){return t.component.type},get onError(){return t.onError},allowRetry:!1,get children(){var o=Ce(),l=o.firstChild,a=l.firstChild,s=l.nextSibling,c=s.firstChild,g=c.nextSibling;return g.nextSibling,e.insert(a,()=>t.component.type),e.insert(o,e.createComponent(d.Show,{get when(){return n==null?void 0:n.title},get children(){var m=we();return e.insert(m,()=>n.title),m}}),s),e.insert(o,e.createComponent(d.Show,{get when(){return e.memo(()=>t.component.type==="metric")()&&(n==null?void 0:n.value)},get children(){var m=be(),u=m.firstChild;return e.insert(u,()=>n.value),e.insert(m,e.createComponent(d.Show,{get when(){return n.unit},get children(){var x=_e();return e.insert(x,()=>n.unit),x}}),null),m}}),s),e.insert(s,()=>t.component.id.slice(0,8),g),o}})}function Ue(t){const{components:r,isLoading:n,isStreaming:i,error:o,progress:l,metadata:a,startStreaming:s}=A.useStreamingUI({query:t.query,spaceIds:t.spaceIds,sessionId:t.sessionId,options:t.options,onComplete:t.onComplete,onError:t.onError,onComponentReceived:t.onComponentReceived}),[c,g]=d.createSignal(new Set),m=u=>{g(x=>new Set([...x,u])),setTimeout(()=>{g(x=>{const h=new Set(x);return h.delete(u),h})},500)};return(()=>{var u=Pe(),x=u.firstChild;return e.insert(u,e.createComponent(d.Show,{get when(){return e.memo(()=>t.showProgress!==!1)()&&(n()||i())},get children(){var h=Ie(),v=h.firstChild,$=v.firstChild,y=v.nextSibling,w=y.firstChild;return e.insert($,()=>l().message),e.insert(v,e.createComponent(d.Show,{get when(){return l().totalCount!==null},get children(){var p=Se(),C=p.firstChild;return e.insert(p,()=>l().receivedCount,C),e.insert(p,()=>l().totalCount,null),p}}),null),e.insert(h,e.createComponent(d.Show,{get when(){return e.memo(()=>l().totalCount===null)()&&i()},get children(){return ke()}}),null),e.effect(p=>e.setStyleProperty(w,"width",l().totalCount!==null?`${l().receivedCount/l().totalCount*100}%`:"0%")),h}}),x),e.insert(u,e.createComponent(d.Show,{get when(){return o()},get children(){var h=Ee(),v=h.firstChild,$=v.firstChild,y=$.nextSibling,w=v.nextSibling;return e.insert(y,()=>{var p;return(p=o())==null?void 0:p.error}),e.insert(w,()=>{var p;return(p=o())==null?void 0:p.message}),e.insert(h,e.createComponent(d.Show,{get when(){var p;return(p=o())==null?void 0:p.recoverable},get children(){var p=Re();return p.$$click=()=>s(),p}}),null),h}}),x),e.insert(x,e.createComponent(d.For,{get each(){return r()},children:h=>(()=>{var v=Ae();return e.use(()=>m(h.id),v),e.insert(v,e.createComponent(Me,{component:h,get onError(){return t.onRenderError}})),e.effect($=>{var y=`
|
|
2
|
-
col-span-${h.position.colSpan}
|
|
3
|
-
${c().has(h.id)?"animate-fade-in-up":""}
|
|
4
|
-
`,w=h.position.colStart,p=h.position.colStart+h.position.colSpan;return y!==$.e&&e.className(v,$.e=y),w!==$.t&&e.setStyleProperty(v,"grid-column-start",$.t=w),p!==$.a&&e.setStyleProperty(v,"grid-column-end",$.a=p),$},{e:void 0,t:void 0,a:void 0}),v})()}),null),e.insert(x,e.createComponent(d.Show,{get when(){return e.memo(()=>!!i())()&&l().totalCount!==null},get children(){return e.createComponent(d.For,{get each(){return Array.from({length:l().totalCount-l().receivedCount})},children:()=>e.createComponent(Oe,{})})}}),null),e.insert(u,e.createComponent(d.Show,{get when(){return e.memo(()=>t.showMetadata!==!1)()&&a()},get children(){var h=De(),v=h.firstChild,$=v.firstChild,y=$.firstChild,w=y.nextSibling,p=$.nextSibling,C=p.firstChild,M=C.nextSibling,k=p.nextSibling,U=k.firstChild,I=U.nextSibling,O=I.firstChild,R=k.nextSibling,F=R.firstChild,E=F.nextSibling,G=E.firstChild;return e.insert(w,()=>{var f;return(f=a())==null?void 0:f.provider}),e.insert(M,()=>{var f;return(f=a())==null?void 0:f.model}),e.insert(I,()=>{var f;return(f=a())==null?void 0:f.executionTimeMs},O),e.insert(v,e.createComponent(d.Show,{get when(){var f;return((f=a())==null?void 0:f.costUSD)!==void 0},get children(){var f=Te(),z=f.firstChild,T=z.nextSibling;return T.firstChild,e.insert(T,()=>{var L,D;return(D=(L=a())==null?void 0:L.costUSD)==null?void 0:D.toFixed(4)},null),f}}),R),e.insert(E,()=>{var f;return(f=a())==null?void 0:f.firstTokenMs},G),e.insert(v,e.createComponent(d.Show,{get when(){var f;return(f=a())==null?void 0:f.cached},get children(){return Le()}}),null),h}}),null),e.effect(()=>e.className(u,`streaming-ui-renderer ${t.class||""}`)),u})()}function Oe(){return Ne()}e.delegateEvents(["click"]);exports.DEFAULT_RESOURCE_LIMITS=_;exports.GenerativeUIErrorBoundary=S;exports.StreamingUIRenderer=Ue;exports.UIResourceRenderer=$e;exports.validateComponent=b;exports.validateLayout=q;
|
|
5
|
-
//# sourceMappingURL=StreamingUIRenderer-DQ1WoVV6.cjs.map
|