@seed-ship/mcp-ui-solid 1.0.29 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/dist/components/GenerativeUIErrorBoundary.cjs.map +1 -0
  2. package/dist/components/GenerativeUIErrorBoundary.js.map +1 -0
  3. package/dist/components/StreamingUIRenderer.cjs.map +1 -0
  4. package/dist/components/StreamingUIRenderer.js.map +1 -0
  5. package/dist/{mcp-ui-solid/src/components → components}/UIResourceRenderer.cjs +102 -97
  6. package/dist/components/UIResourceRenderer.cjs.map +1 -0
  7. package/dist/components/UIResourceRenderer.d.ts +0 -11
  8. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  9. package/dist/{mcp-ui-solid/src/components → components}/UIResourceRenderer.js +102 -97
  10. package/dist/components/UIResourceRenderer.js.map +1 -0
  11. package/dist/components.cjs +3 -3
  12. package/dist/components.d.ts +12 -0
  13. package/dist/components.js +3 -3
  14. package/dist/hooks/useStreamingUI.cjs.map +1 -0
  15. package/dist/hooks/useStreamingUI.js.map +1 -0
  16. package/dist/hooks.cjs +1 -1
  17. package/dist/hooks.d.ts +8 -0
  18. package/dist/hooks.js +1 -1
  19. package/dist/index.cjs +6 -6
  20. package/dist/index.js +6 -6
  21. package/dist/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.cjs +1006 -0
  22. package/dist/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.cjs.map +1 -0
  23. package/dist/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.js +1007 -0
  24. package/dist/node_modules/.pnpm/dompurify@3.3.0/node_modules/dompurify/dist/purify.es.js.map +1 -0
  25. package/dist/services/component-registry.cjs.map +1 -0
  26. package/dist/services/component-registry.js.map +1 -0
  27. package/dist/services/validation.cjs.map +1 -0
  28. package/dist/services/validation.js.map +1 -0
  29. package/dist/types.d.ts +265 -0
  30. package/dist/utils/logger.cjs.map +1 -0
  31. package/dist/utils/logger.js.map +1 -0
  32. package/dist/validation.cjs +1 -1
  33. package/dist/validation.js +1 -1
  34. package/package.json +20 -23
  35. package/src/components/ActionRenderer.tsx +33 -0
  36. package/src/components/ArtifactRenderer.tsx +54 -0
  37. package/src/components/CarouselRenderer.tsx +77 -0
  38. package/src/components/FooterRenderer.tsx +66 -0
  39. package/src/components/GenerativeUIErrorBoundary.tsx +259 -0
  40. package/src/components/StreamingUIRenderer.tsx +327 -0
  41. package/src/components/UIResourceRenderer.tsx +573 -0
  42. package/src/components/index.ts +14 -0
  43. package/src/hooks/index.ts +14 -0
  44. package/src/hooks/useStreamingUI.ts +447 -0
  45. package/src/index.test.ts +36 -0
  46. package/src/index.ts +70 -0
  47. package/src/services/component-registry.ts +378 -0
  48. package/src/services/index.ts +9 -0
  49. package/src/services/validation.ts +472 -0
  50. package/src/types/index.ts +320 -0
  51. package/src/types-export.ts +31 -0
  52. package/src/utils/logger.ts +74 -0
  53. package/src/validation.ts +38 -0
  54. package/src/vite-env.d.ts +11 -0
  55. package/tsconfig.json +20 -0
  56. package/tsconfig.tsbuildinfo +1 -0
  57. package/vite.config.ts +52 -0
  58. package/vite.config.ts.timestamp-1763266929437-a71eed80b91318.mjs +45 -0
  59. package/vitest.config.ts +10 -0
  60. package/dist/mcp-ui-solid/src/components/GenerativeUIErrorBoundary.cjs.map +0 -1
  61. package/dist/mcp-ui-solid/src/components/GenerativeUIErrorBoundary.js.map +0 -1
  62. package/dist/mcp-ui-solid/src/components/StreamingUIRenderer.cjs.map +0 -1
  63. package/dist/mcp-ui-solid/src/components/StreamingUIRenderer.js.map +0 -1
  64. package/dist/mcp-ui-solid/src/components/UIResourceRenderer.cjs.map +0 -1
  65. package/dist/mcp-ui-solid/src/components/UIResourceRenderer.js.map +0 -1
  66. package/dist/mcp-ui-solid/src/hooks/useStreamingUI.cjs.map +0 -1
  67. package/dist/mcp-ui-solid/src/hooks/useStreamingUI.js.map +0 -1
  68. package/dist/mcp-ui-solid/src/services/component-registry.cjs.map +0 -1
  69. package/dist/mcp-ui-solid/src/services/component-registry.js.map +0 -1
  70. package/dist/mcp-ui-solid/src/services/validation.cjs.map +0 -1
  71. package/dist/mcp-ui-solid/src/services/validation.js.map +0 -1
  72. package/dist/mcp-ui-solid/src/utils/logger.cjs.map +0 -1
  73. package/dist/mcp-ui-solid/src/utils/logger.js.map +0 -1
  74. /package/dist/{mcp-ui-solid/src/components → components}/GenerativeUIErrorBoundary.cjs +0 -0
  75. /package/dist/{mcp-ui-solid/src/components → components}/GenerativeUIErrorBoundary.js +0 -0
  76. /package/dist/{mcp-ui-solid/src/components → components}/StreamingUIRenderer.cjs +0 -0
  77. /package/dist/{mcp-ui-solid/src/components → components}/StreamingUIRenderer.js +0 -0
  78. /package/dist/{mcp-ui-solid/src/hooks → hooks}/useStreamingUI.cjs +0 -0
  79. /package/dist/{mcp-ui-solid/src/hooks → hooks}/useStreamingUI.js +0 -0
  80. /package/dist/{mcp-ui-solid/src/services → services}/component-registry.cjs +0 -0
  81. /package/dist/{mcp-ui-solid/src/services → services}/component-registry.js +0 -0
  82. /package/dist/{mcp-ui-solid/src/services → services}/validation.cjs +0 -0
  83. /package/dist/{mcp-ui-solid/src/services → services}/validation.js +0 -0
  84. /package/dist/{mcp-ui-solid/src/utils → utils}/logger.cjs +0 -0
  85. /package/dist/{mcp-ui-solid/src/utils → utils}/logger.js +0 -0
@@ -0,0 +1,378 @@
1
+ /**
2
+ * Component Registry Service
3
+ * Phase 0: Static registry with Quickchart and Table definitions
4
+ * Phase 1: Dynamic registry populated from /api/mcp/tools/list
5
+ *
6
+ * Provides component schemas for LLM prompt engineering
7
+ */
8
+
9
+ import type { ComponentRegistryEntry, ComponentType } from '../types'
10
+ import { DEFAULT_RESOURCE_LIMITS } from './validation'
11
+
12
+ /**
13
+ * Quickchart Component Registry Entry
14
+ * Based on Quickchart API documentation
15
+ */
16
+ export const QuickchartRegistry: ComponentRegistryEntry = {
17
+ type: 'chart',
18
+ name: 'Quickchart',
19
+ description:
20
+ 'Render charts using Quickchart.io API. Supports bar, line, pie, doughnut, radar, and scatter charts. Best for visualizing numerical data with 2-10 data series and up to 1000 data points.',
21
+ schema: {
22
+ type: 'object',
23
+ properties: {
24
+ type: {
25
+ type: 'string',
26
+ enum: ['bar', 'line', 'pie', 'doughnut', 'radar', 'scatter'],
27
+ description: 'Chart type',
28
+ },
29
+ title: {
30
+ type: 'string',
31
+ description: 'Chart title (optional)',
32
+ },
33
+ data: {
34
+ type: 'object',
35
+ properties: {
36
+ labels: {
37
+ type: 'array',
38
+ items: { type: 'string' },
39
+ description: 'X-axis labels',
40
+ },
41
+ datasets: {
42
+ type: 'array',
43
+ items: {
44
+ type: 'object',
45
+ properties: {
46
+ label: { type: 'string' },
47
+ data: {
48
+ type: 'array',
49
+ items: { type: 'number' },
50
+ },
51
+ backgroundColor: {
52
+ oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }],
53
+ },
54
+ borderColor: {
55
+ oneOf: [{ type: 'string' }, { type: 'array', items: { type: 'string' } }],
56
+ },
57
+ borderWidth: { type: 'number' },
58
+ },
59
+ required: ['label', 'data'],
60
+ },
61
+ },
62
+ },
63
+ required: ['labels', 'datasets'],
64
+ },
65
+ options: {
66
+ type: 'object',
67
+ description: 'Chart.js options for customization',
68
+ },
69
+ },
70
+ required: ['type', 'data'],
71
+ },
72
+ examples: [
73
+ {
74
+ query: 'Show me document types distribution',
75
+ component: {
76
+ id: 'example-bar-1',
77
+ type: 'chart',
78
+ position: { colStart: 1, colSpan: 6 },
79
+ params: {
80
+ type: 'bar',
81
+ title: 'Document Types',
82
+ data: {
83
+ labels: ['PDF', 'DOCX', 'TXT', 'XLSX'],
84
+ datasets: [
85
+ {
86
+ label: 'Count',
87
+ data: [245, 189, 123, 98],
88
+ backgroundColor: ['rgba(59, 130, 246, 0.8)'],
89
+ },
90
+ ],
91
+ },
92
+ },
93
+ },
94
+ },
95
+ {
96
+ query: 'Display upload trends over the last week',
97
+ component: {
98
+ id: 'example-line-1',
99
+ type: 'chart',
100
+ position: { colStart: 1, colSpan: 6 },
101
+ params: {
102
+ type: 'line',
103
+ title: 'Upload Trends',
104
+ data: {
105
+ labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
106
+ datasets: [
107
+ {
108
+ label: 'Uploads',
109
+ data: [42, 38, 51, 47, 63, 29, 15],
110
+ borderColor: 'rgb(59, 130, 246)',
111
+ },
112
+ ],
113
+ },
114
+ options: {
115
+ tension: 0.4,
116
+ },
117
+ },
118
+ },
119
+ },
120
+ ],
121
+ limits: DEFAULT_RESOURCE_LIMITS,
122
+ }
123
+
124
+ /**
125
+ * Table Component Registry Entry
126
+ */
127
+ export const TableRegistry: ComponentRegistryEntry = {
128
+ type: 'table',
129
+ name: 'DataTable',
130
+ description:
131
+ 'Render tabular data with sortable columns and pagination. Best for displaying structured records with up to 100 rows. Supports column width customization and cell formatting.',
132
+ schema: {
133
+ type: 'object',
134
+ properties: {
135
+ title: {
136
+ type: 'string',
137
+ description: 'Table title (optional)',
138
+ },
139
+ columns: {
140
+ type: 'array',
141
+ items: {
142
+ type: 'object',
143
+ properties: {
144
+ key: { type: 'string', description: 'Data key for this column' },
145
+ label: { type: 'string', description: 'Column header label' },
146
+ sortable: { type: 'boolean', description: 'Whether column is sortable' },
147
+ width: { type: 'string', description: 'CSS width (e.g., "30%")' },
148
+ },
149
+ required: ['key', 'label'],
150
+ },
151
+ minItems: 1,
152
+ },
153
+ rows: {
154
+ type: 'array',
155
+ items: {
156
+ type: 'object',
157
+ description: 'Row data matching column keys',
158
+ },
159
+ maxItems: 100,
160
+ },
161
+ pagination: {
162
+ type: 'object',
163
+ properties: {
164
+ currentPage: { type: 'number' },
165
+ pageSize: { type: 'number' },
166
+ totalRows: { type: 'number' },
167
+ },
168
+ },
169
+ },
170
+ required: ['columns', 'rows'],
171
+ },
172
+ examples: [
173
+ {
174
+ query: 'Show me the most recent documents',
175
+ component: {
176
+ id: 'example-table-1',
177
+ type: 'table',
178
+ position: { colStart: 1, colSpan: 8 },
179
+ params: {
180
+ title: 'Recent Documents',
181
+ columns: [
182
+ { key: 'name', label: 'Name', sortable: true, width: '40%' },
183
+ { key: 'type', label: 'Type', sortable: true, width: '15%' },
184
+ { key: 'size', label: 'Size', width: '15%' },
185
+ { key: 'modified', label: 'Modified', sortable: true, width: '30%' },
186
+ ],
187
+ rows: [
188
+ { name: 'Report.pdf', type: 'PDF', size: '2.4 MB', modified: '2 hours ago' },
189
+ { name: 'Slides.pptx', type: 'PPTX', size: '8.7 MB', modified: '1 day ago' },
190
+ ],
191
+ },
192
+ },
193
+ },
194
+ ],
195
+ limits: DEFAULT_RESOURCE_LIMITS,
196
+ }
197
+
198
+ /**
199
+ * Metric Card Component Registry Entry
200
+ */
201
+ export const MetricRegistry: ComponentRegistryEntry = {
202
+ type: 'metric',
203
+ name: 'MetricCard',
204
+ description:
205
+ 'Display a single metric with optional trend indicator. Best for KPIs, statistics, and summary numbers. Supports trend direction (up/down/neutral) and subtitles.',
206
+ schema: {
207
+ type: 'object',
208
+ properties: {
209
+ title: {
210
+ type: 'string',
211
+ description: 'Metric title',
212
+ },
213
+ value: {
214
+ oneOf: [{ type: 'string' }, { type: 'number' }],
215
+ description: 'Metric value',
216
+ },
217
+ unit: {
218
+ type: 'string',
219
+ description: 'Unit of measurement (optional)',
220
+ },
221
+ trend: {
222
+ type: 'object',
223
+ properties: {
224
+ value: { type: 'number', description: 'Percentage change' },
225
+ direction: { type: 'string', enum: ['up', 'down', 'neutral'] },
226
+ },
227
+ },
228
+ subtitle: {
229
+ type: 'string',
230
+ description: 'Additional context (optional)',
231
+ },
232
+ },
233
+ required: ['title', 'value'],
234
+ },
235
+ examples: [
236
+ {
237
+ query: 'Show total document count',
238
+ component: {
239
+ id: 'example-metric-1',
240
+ type: 'metric',
241
+ position: { colStart: 1, colSpan: 3 },
242
+ params: {
243
+ title: 'Total Documents',
244
+ value: '1,247',
245
+ trend: {
246
+ value: 12.5,
247
+ direction: 'up',
248
+ },
249
+ subtitle: '+142 this month',
250
+ },
251
+ },
252
+ },
253
+ ],
254
+ limits: {
255
+ maxDataPoints: 1,
256
+ maxTableRows: 1,
257
+ maxPayloadSize: 5 * 1024, // 5KB
258
+ renderTimeout: 1000, // 1s
259
+ },
260
+ }
261
+
262
+ /**
263
+ * Text Component Registry Entry
264
+ */
265
+ export const TextRegistry: ComponentRegistryEntry = {
266
+ type: 'text',
267
+ name: 'TextBlock',
268
+ description:
269
+ 'Render text content with optional markdown support. Best for explanations, summaries, and context. Supports basic HTML formatting.',
270
+ schema: {
271
+ type: 'object',
272
+ properties: {
273
+ content: {
274
+ type: 'string',
275
+ description: 'Text content (HTML allowed, will be sanitized)',
276
+ },
277
+ markdown: {
278
+ type: 'boolean',
279
+ description: 'Whether content is markdown (not yet implemented)',
280
+ },
281
+ className: {
282
+ type: 'string',
283
+ description: 'Custom CSS classes',
284
+ },
285
+ },
286
+ required: ['content'],
287
+ },
288
+ examples: [
289
+ {
290
+ query: 'Explain the document distribution',
291
+ component: {
292
+ id: 'example-text-1',
293
+ type: 'text',
294
+ position: { colStart: 1, colSpan: 12 },
295
+ params: {
296
+ content:
297
+ '<p>Your document library contains <strong>1,247 files</strong> across 5 different formats. PDFs represent the largest category at 35% of total storage.</p>',
298
+ },
299
+ },
300
+ },
301
+ ],
302
+ limits: {
303
+ maxDataPoints: 1,
304
+ maxTableRows: 1,
305
+ maxPayloadSize: 10 * 1024, // 10KB
306
+ renderTimeout: 1000, // 1s
307
+ },
308
+ }
309
+
310
+ /**
311
+ * Component Registry - All components indexed by type
312
+ */
313
+ export const ComponentRegistry: Map<ComponentType, ComponentRegistryEntry> = new Map([
314
+ ['chart', QuickchartRegistry],
315
+ ['table', TableRegistry],
316
+ ['metric', MetricRegistry],
317
+ ['text', TextRegistry],
318
+ ])
319
+
320
+ /**
321
+ * Get component registry entry by type
322
+ */
323
+ export function getComponentEntry(type: ComponentType): ComponentRegistryEntry | undefined {
324
+ return ComponentRegistry.get(type)
325
+ }
326
+
327
+ /**
328
+ * Get all component types
329
+ */
330
+ export function getAllComponentTypes(): ComponentType[] {
331
+ return Array.from(ComponentRegistry.keys())
332
+ }
333
+
334
+ /**
335
+ * Get registry as JSON for LLM context
336
+ */
337
+ export function getRegistryForLLM(): string {
338
+ const entries = Array.from(ComponentRegistry.values()).map((entry) => ({
339
+ type: entry.type,
340
+ name: entry.name,
341
+ description: entry.description,
342
+ schema: entry.schema,
343
+ examples: entry.examples.map((ex) => ({
344
+ query: ex.query,
345
+ component: ex.component,
346
+ })),
347
+ limits: entry.limits,
348
+ }))
349
+
350
+ return JSON.stringify(entries, null, 2)
351
+ }
352
+
353
+ /**
354
+ * Validate component against registry schema
355
+ * (Future: Use Zod for runtime validation)
356
+ */
357
+ export function validateAgainstRegistry(
358
+ componentType: ComponentType,
359
+ params: any
360
+ ): { valid: boolean; errors?: string[] } {
361
+ const entry = getComponentEntry(componentType)
362
+ if (!entry) {
363
+ return { valid: false, errors: [`Unknown component type: ${componentType}`] }
364
+ }
365
+
366
+ // Basic validation (Phase 1 will add Zod schema validation)
367
+ const required = entry.schema.required || []
368
+ const missing = required.filter((key: string) => !(key in params))
369
+
370
+ if (missing.length > 0) {
371
+ return {
372
+ valid: false,
373
+ errors: missing.map((key: string) => `Missing required field: ${key}`),
374
+ }
375
+ }
376
+
377
+ return { valid: true }
378
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * MCP UI Solid - Services
3
+ *
4
+ * Business logic for component validation and registry management
5
+ */
6
+
7
+ export { validateComponent, validateLayout, DEFAULT_RESOURCE_LIMITS } from './validation'
8
+
9
+ export { ComponentRegistry } from './component-registry'