@seed-ship/mcp-ui-solid 5.3.1 → 5.5.0

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 (81) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/dist/components/StreamingUIRenderer.cjs +106 -90
  3. package/dist/components/StreamingUIRenderer.cjs.map +1 -1
  4. package/dist/components/StreamingUIRenderer.d.ts +7 -0
  5. package/dist/components/StreamingUIRenderer.d.ts.map +1 -1
  6. package/dist/components/StreamingUIRenderer.js +107 -91
  7. package/dist/components/StreamingUIRenderer.js.map +1 -1
  8. package/dist/components/UIResourceRenderer.cjs +101 -82
  9. package/dist/components/UIResourceRenderer.cjs.map +1 -1
  10. package/dist/components/UIResourceRenderer.d.ts +23 -0
  11. package/dist/components/UIResourceRenderer.d.ts.map +1 -1
  12. package/dist/components/UIResourceRenderer.js +102 -83
  13. package/dist/components/UIResourceRenderer.js.map +1 -1
  14. package/dist/index.cjs +7 -0
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.d.cts +3 -0
  17. package/dist/index.d.ts +3 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +7 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/mcp-ui-spec/dist/schemas.cjs +493 -0
  22. package/dist/mcp-ui-spec/dist/schemas.cjs.map +1 -0
  23. package/dist/mcp-ui-spec/dist/schemas.js +493 -0
  24. package/dist/mcp-ui-spec/dist/schemas.js.map +1 -0
  25. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.cjs +118 -0
  26. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.cjs.map +1 -0
  27. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js +118 -0
  28. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/ZodError.js.map +1 -0
  29. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.cjs +10 -0
  30. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.cjs.map +1 -0
  31. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js +10 -0
  32. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/errors.js.map +1 -0
  33. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.cjs +8 -0
  34. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.cjs.map +1 -0
  35. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js +9 -0
  36. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js.map +1 -0
  37. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.cjs +122 -0
  38. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.cjs.map +1 -0
  39. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js +122 -0
  40. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js.map +1 -0
  41. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs +137 -0
  42. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs.map +1 -0
  43. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js +139 -0
  44. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/helpers/util.js.map +1 -0
  45. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.cjs +105 -0
  46. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.cjs.map +1 -0
  47. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js +106 -0
  48. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/locales/en.js.map +1 -0
  49. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs +3229 -0
  50. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.cjs.map +1 -0
  51. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js +3230 -0
  52. package/dist/node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/types.js.map +1 -0
  53. package/dist/services/validation.cjs +70 -152
  54. package/dist/services/validation.cjs.map +1 -1
  55. package/dist/services/validation.d.ts.map +1 -1
  56. package/dist/services/validation.js +70 -152
  57. package/dist/services/validation.js.map +1 -1
  58. package/dist/utils/logger.cjs +26 -4
  59. package/dist/utils/logger.cjs.map +1 -1
  60. package/dist/utils/logger.d.ts +30 -3
  61. package/dist/utils/logger.d.ts.map +1 -1
  62. package/dist/utils/logger.js +27 -5
  63. package/dist/utils/logger.js.map +1 -1
  64. package/dist/utils/perf.cjs +34 -0
  65. package/dist/utils/perf.cjs.map +1 -0
  66. package/dist/utils/perf.d.ts +19 -0
  67. package/dist/utils/perf.d.ts.map +1 -0
  68. package/dist/utils/perf.js +34 -0
  69. package/dist/utils/perf.js.map +1 -0
  70. package/package.json +3 -2
  71. package/src/components/StreamingUIRenderer.tsx +54 -2
  72. package/src/components/UIResourceRenderer.errorMode.test.tsx +95 -0
  73. package/src/components/UIResourceRenderer.tsx +72 -4
  74. package/src/index.ts +7 -0
  75. package/src/services/validation.spec-migration.test.ts +207 -0
  76. package/src/services/validation.ts +132 -178
  77. package/src/utils/logger.test.ts +130 -0
  78. package/src/utils/logger.ts +60 -7
  79. package/src/utils/perf.test.ts +59 -0
  80. package/src/utils/perf.ts +50 -0
  81. package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,110 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [5.5.0] - 2026-04-27
9
+
10
+ B.1 PR2 — `services/validation.ts` migration vers Zod schemas spec-driven (cf. audit deposium `MCP-UI-AUDIT-2026-04-26.md` §I + greenlight §J). **Non-breaking, aucune migration consumer requise.**
11
+
12
+ ### Changed — validation refactor (B.1 PR2)
13
+
14
+ - Nouvelle dépendance : **`@seed-ship/mcp-ui-spec` ^5.0.1** (workspace).
15
+ - `validateComponent()` consomme désormais les Zod schemas exportés depuis `mcp-ui-spec` pour **12 ComponentTypes sur 17** : `metric`, `text`, `iframe`, `image`, `link`, `action`, `video`, `carousel`, `image-gallery`, `action-group`, `code`, `artifact`.
16
+ - Mapper interne **`mapZodIssuesToErrors(issues, legacyCode)`** : convertit `ZodIssue[]` → `ValidationError[]` en préservant le `code` legacy par type (`INVALID_METRIC`, `EMPTY_CAROUSEL`, etc.). **L'API publique `validateComponent()` retourne exactement la même shape `{valid, errors: [{path, message, code}]}` qu'avant** — voir audit §J.1 (deposium a confirmé que `errors[].code` n'est lu nulle part en logique métier).
17
+ - Path Zod normalisé : `params.<joined>` (ex. `params.title`, `params.data.datasets`) — cohérent avec les chemins legacy.
18
+ - 5 ComponentTypes restent **délibérément sur le path impératif** :
19
+ - `chart` + `table` — leurs validateurs (`validateChartComponent`, `validateTableComponent`) font cross-field consistency + resource limits + codes riches (`MISSING_DATA`, `DATA_LENGTH_MISMATCH`, `DUPLICATE_COLUMN_KEY`...) que Zod ne peut pas exprimer aussi proprement.
20
+ - `form` — `FormComponentParamsSchema` du spec a une regex stricte sur les noms de fields qui pourrait rejeter des payloads LLM valides. Conservatisme.
21
+ - `map` — spec exige `center: tuple([number, number])` mais la prod accepte `{lat, lng}` objects. Backward-compat.
22
+ - `modal` — tous params optionnels, rien à valider.
23
+
24
+ ### Fixed — Artifact validation drift (side-effect)
25
+
26
+ - **Pré-v5.5.0 bug** : `validation.ts` exigeait `params.content` (code `INVALID_ARTIFACT`) mais `<ArtifactRenderer>` consomme `url + filename + mimeType`. Tout artifact rendu valide échouait la validation, et tout artifact "validé" ne pouvait pas être rendu.
27
+ - **Fix** : la migration vers `ArtifactComponentParamsSchema` aligne automatiquement la validation sur ce que le renderer attend (`url + filename + mimeType` requis, `size` ≥ 0, `description` optionnel).
28
+ - Code legacy `INVALID_ARTIFACT` préservé pour les consumers qui filtrent dessus.
29
+
30
+ ### Preserved — Resource limits + iframe whitelist (sécurité)
31
+
32
+ Explicitement **gardés impératifs**, hors scope de la migration Zod :
33
+ - `validatePayloadSize` (max 50KB par défaut)
34
+ - `validateChartComponent` data points limits (max 1000 par défaut)
35
+ - `validateTableComponent` row limits (max 100 par défaut)
36
+ - `validateIframeDomain` + `DEFAULT_IFRAME_DOMAINS` whitelist (~45 domaines)
37
+ - `getIframeSandbox` tiered sandbox flags
38
+
39
+ Ces couches sont chaînées **après** le spec parse (cf. `iframe` + `video` → spec parse réussi → domain whitelist).
40
+
41
+ ### Build pipeline (mcp-ui-spec @ 5.0.1+)
42
+
43
+ Bonus : remplacement du `scripts/generate-dts.js` hand-rolled (qui ne déclarait que 9 schemas sur ~30) par `tsc -p tsconfig.build.json --emitDeclarationOnly`. Les 30+ schemas sont maintenant tous correctement déclarés dans `dist/schemas.d.ts` automatiquement. Élimine une dette de maintenance.
44
+
45
+ ### Tests
46
+
47
+ - `services/validation.test.ts` (49 tests) — **inchangé**, passe tel quel → preuve que l'API externe est préservée.
48
+ - `services/validation.spec-migration.test.ts` — **+18 nouveaux tests** ciblant explicitement v5.5.0 :
49
+ - Mapper preserve legacy `code` per type (12 types vérifiés)
50
+ - ZodIssue path → `params.<joined>` translation
51
+ - Artifact bug fix (url+filename+mimeType requis, plus content)
52
+ - Iframe + video chain : spec parse réussi → domain check, parse failed → SKIP domain check (no cascade)
53
+ - Imperative passthrough types préservent leurs codes riches (`MISSING_DATA`, `EMPTY_COLUMNS`, `EMPTY_FORM`, etc.)
54
+ - Invariants : `UNKNOWN_COMPONENT_TYPE`, `MISSING_PARAMS`, `INVALID_GRID_COL_START` toujours émis
55
+
56
+ Suite totale solid : **523/523 tests pass** (vs 505 sur v5.4.0).
57
+
58
+ ### Cross-stack — bénéfice deposium
59
+
60
+ Avec spec@5.0.1 + solid@5.5.0, deposium peut maintenant factoriser sa validation cross-stack :
61
+ ```ts
62
+ import { ChartComponentParamsSchema } from '@seed-ship/mcp-ui-spec'
63
+ // Côté MCPs (backend) : valider extracted_charts à la source
64
+ // Côté Solid (frontend) : héritage automatique via mcp-ui-solid
65
+ ```
66
+
67
+ ### Non-breaking guarantee
68
+
69
+ - API `validateComponent()` shape **identique** : `{ valid: boolean, errors?: Array<{path, message, code}> }`.
70
+ - Tous les codes legacy préservés via le mapper (51 codes existants).
71
+ - Resource limits + iframe whitelist + sandbox flags **inchangés**.
72
+ - Seul changement de comportement observable : `artifact` accepte maintenant les payloads que le renderer rend réellement (bug fix).
73
+
74
+ ## [5.4.0] - 2026-04-26
75
+
76
+ Combo non-breaking d'observabilité + UX, motivé par l'audit deposium_MCPs `MCP-UI-AUDIT-2026-04-26.md` (items B.2 + B.3 + B.4).
77
+
78
+ ### Added — B.2 Runtime debug mode
79
+
80
+ - **`setDebugMode(enabled: boolean | null)`** + **`isDebugEnabled()`** exportés depuis l'index. Permet d'activer le verbose logging sans recompilation, utile pour debugger une session prod (Docker dev avec `NODE_ENV=production` notamment).
81
+ - 4 sources d'activation (OR logique) : `NODE_ENV !== 'production'` (existant), `process.env.MCP_UI_DEBUG === 'true'`, `globalThis.__MCP_UI_DEBUG__ === true`, ou `setDebugMode(true)`.
82
+ - `setDebugMode(null)` réinitialise à la détection env-based.
83
+ - `error()` log toujours, indépendamment du mode (inchangé).
84
+
85
+ ### Added — B.4 Performance markers
86
+
87
+ - Nouveaux helpers **`markRenderStart(id)`** + **`markRenderEnd(id)`** + constante **`PERF_PREFIX`** (`'mcp-ui:component:'`) exportés depuis l'index.
88
+ - Câblés automatiquement dans `<UIResourceRenderer>` + `<StreamingUIRenderer>` autour de chaque `ComponentRenderer`. Émettent :
89
+ - `mcp-ui:component:<id>:render-start`
90
+ - `mcp-ui:component:<id>:render-end`
91
+ - `mcp-ui:component:<id>:render` (un `performance.measure` entre les deux)
92
+ - Visibles automatiquement dans Chrome DevTools "Performance" panel sous user timings, sans config consumer.
93
+ - SSR-safe (`performance` est gardé) ; coût négligeable (<μs par mark).
94
+
95
+ ### Added — B.3 `errorMode` prop sur les renderers
96
+
97
+ - Nouveau type **`ValidationErrorMode = 'block' | 'inline-warn' | 'silent'`** + nouvelle prop **`errorMode?: ValidationErrorMode`** sur `<UIResourceRenderer>` et `<StreamingUIRenderer>`.
98
+ - `'block'` (default, **backward-compatible**) : carte rouge "Validation Error" pleine slot — comportement pré-v5.4.0.
99
+ - `'inline-warn'` : chip jaune compact dans le slot, message d'erreur dans le tooltip + `aria-label`. Évite de polluer une conversation chat avec un gros bloc rouge.
100
+ - `'silent'` : aucun rendu visible (le slot reste vide). `onError` est appelé dans les 3 modes.
101
+ - Ne s'applique qu'au path **validation** (`validateComponent` failure). Les runtime errors capturées par `<GenerativeUIErrorBoundary>` continuent d'utiliser le fallback existant.
102
+
103
+ ### Tests
104
+
105
+ - 3 nouveaux fichiers de tests : `src/utils/logger.test.ts` (10 tests), `src/utils/perf.test.ts` (5 tests), `src/components/UIResourceRenderer.errorMode.test.tsx` (6 tests).
106
+ - Suite totale : **505/505 tests pass** (vs. 484 sur v5.3.1).
107
+
108
+ ### Non-breaking
109
+
110
+ - Aucun changement d'API existante. Les apps qui ne passent pas `errorMode` voient exactement le comportement v5.3.1.
111
+
8
112
  ## [5.3.1] - 2026-04-25
9
113
 
10
114
  ### Security
@@ -5,9 +5,12 @@ const solidJs = require("solid-js");
5
5
  const useStreamingUI = require("../hooks/useStreamingUI.cjs");
6
6
  const validation = require("../services/validation.cjs");
7
7
  const GenerativeUIErrorBoundary = require("./GenerativeUIErrorBoundary.cjs");
8
- var _tmpl$ = /* @__PURE__ */ web.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">`), _tmpl$2 = /* @__PURE__ */ web.template(`<h3 class="text-sm font-semibold text-text-primary">`), _tmpl$3 = /* @__PURE__ */ web.template(`<span class="text-sm text-text-secondary">`), _tmpl$4 = /* @__PURE__ */ web.template(`<div class=mt-2><p class="text-2xl font-semibold text-text-primary"></p><!$><!/>`), _tmpl$5 = /* @__PURE__ */ web.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: <!$><!/>...`), _tmpl$6 = /* @__PURE__ */ web.template(`<span class="text-sm text-text-secondary"><!$><!/> / <!$><!/>`), _tmpl$7 = /* @__PURE__ */ web.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">`), _tmpl$8 = /* @__PURE__ */ web.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"></div></div><!$><!/>`), _tmpl$9 = /* @__PURE__ */ web.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`), _tmpl$0 = /* @__PURE__ */ web.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"></p><!$><!/>`), _tmpl$1 = /* @__PURE__ */ web.template(`<div><div class="font-medium text-text-primary">Cost</div><div>$<!$><!/>`), _tmpl$10 = /* @__PURE__ */ web.template(`<div><div class="font-medium text-text-primary">Cached</div><div class=text-success-primary>Yes`), _tmpl$11 = /* @__PURE__ */ web.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</div></div><!$><!/>`), _tmpl$12 = /* @__PURE__ */ web.template(`<div><!$><!/><!$><!/><div class="grid grid-cols-12 gap-4"><!$><!/><!$><!/></div><!$><!/>`), _tmpl$13 = /* @__PURE__ */ web.template(`<div>`), _tmpl$14 = /* @__PURE__ */ web.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">`);
8
+ const perf = require("../utils/perf.cjs");
9
+ var _tmpl$ = /* @__PURE__ */ web.template(`<div class="inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 text-xs text-yellow-800 dark:text-yellow-200"role=alert aria-label="Component validation warning"><svg xmlns=http://www.w3.org/2000/svg class="w-3.5 h-3.5"viewBox="0 0 24 24"fill=none stroke=currentColor stroke-width=2 stroke-linecap=round stroke-linejoin=round aria-hidden=true><path d="M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z"></path><line x1=12 y1=9 x2=12 y2=13></line><line x1=12 y1=17 x2=12.01 y2=17></line></svg><span>Invalid <!$><!/>`), _tmpl$2 = /* @__PURE__ */ web.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">`), _tmpl$3 = /* @__PURE__ */ web.template(`<h3 class="text-sm font-semibold text-text-primary">`), _tmpl$4 = /* @__PURE__ */ web.template(`<span class="text-sm text-text-secondary">`), _tmpl$5 = /* @__PURE__ */ web.template(`<div class=mt-2><p class="text-2xl font-semibold text-text-primary"></p><!$><!/>`), _tmpl$6 = /* @__PURE__ */ web.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: <!$><!/>...`), _tmpl$7 = /* @__PURE__ */ web.template(`<span class="text-sm text-text-secondary"><!$><!/> / <!$><!/>`), _tmpl$8 = /* @__PURE__ */ web.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">`), _tmpl$9 = /* @__PURE__ */ web.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"></div></div><!$><!/>`), _tmpl$0 = /* @__PURE__ */ web.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`), _tmpl$1 = /* @__PURE__ */ web.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"></p><!$><!/>`), _tmpl$10 = /* @__PURE__ */ web.template(`<div><div class="font-medium text-text-primary">Cost</div><div>$<!$><!/>`), _tmpl$11 = /* @__PURE__ */ web.template(`<div><div class="font-medium text-text-primary">Cached</div><div class=text-success-primary>Yes`), _tmpl$12 = /* @__PURE__ */ web.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</div></div><!$><!/>`), _tmpl$13 = /* @__PURE__ */ web.template(`<div><!$><!/><!$><!/><div class="grid grid-cols-12 gap-4"><!$><!/><!$><!/></div><!$><!/>`), _tmpl$14 = /* @__PURE__ */ web.template(`<div>`), _tmpl$15 = /* @__PURE__ */ web.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">`);
9
10
  function StreamingComponentRenderer(props) {
10
- var _a;
11
+ var _a, _b, _c;
12
+ perf.markRenderStart(props.component.id);
13
+ solidJs.onMount(() => perf.markRenderEnd(props.component.id));
11
14
  const validation$1 = validation.validateComponent(props.component);
12
15
  if (!validation$1.valid) {
13
16
  (_a = props.onError) == null ? void 0 : _a.call(props, {
@@ -16,13 +19,23 @@ function StreamingComponentRenderer(props) {
16
19
  componentId: props.component.id,
17
20
  details: validation$1.errors
18
21
  });
22
+ const mode = props.errorMode ?? "block";
23
+ const firstError = ((_c = (_b = validation$1.errors) == null ? void 0 : _b[0]) == null ? void 0 : _c.message) || "Unknown validation error";
24
+ if (mode === "silent") {
25
+ return null;
26
+ }
27
+ if (mode === "inline-warn") {
28
+ return (() => {
29
+ var _el$ = web.getNextElement(_tmpl$), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling, _el$4 = _el$3.firstChild, _el$5 = _el$4.nextSibling, [_el$6, _co$] = web.getNextMarker(_el$5.nextSibling);
30
+ web.setAttribute(_el$, "title", firstError);
31
+ web.insert(_el$3, () => props.component.type, _el$6, _co$);
32
+ return _el$;
33
+ })();
34
+ }
19
35
  return (() => {
20
- var _el$ = web.getNextElement(_tmpl$), _el$2 = _el$.firstChild, _el$3 = _el$2.nextSibling;
21
- web.insert(_el$3, () => {
22
- var _a2, _b;
23
- return ((_b = (_a2 = validation$1.errors) == null ? void 0 : _a2[0]) == null ? void 0 : _b.message) || "Unknown validation error";
24
- });
25
- return _el$;
36
+ var _el$7 = web.getNextElement(_tmpl$2), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling;
37
+ web.insert(_el$9, firstError);
38
+ return _el$7;
26
39
  })();
27
40
  }
28
41
  const params = props.component.params;
@@ -38,41 +51,41 @@ function StreamingComponentRenderer(props) {
38
51
  },
39
52
  allowRetry: false,
40
53
  get children() {
41
- var _el$4 = web.getNextElement(_tmpl$5), _el$5 = _el$4.firstChild, _el$6 = _el$5.firstChild, _el$16 = _el$5.nextSibling, [_el$17, _co$3] = web.getNextMarker(_el$16.nextSibling), _el$18 = _el$17.nextSibling, [_el$19, _co$4] = web.getNextMarker(_el$18.nextSibling), _el$11 = _el$19.nextSibling, _el$12 = _el$11.firstChild, _el$14 = _el$12.nextSibling, [_el$15, _co$2] = web.getNextMarker(_el$14.nextSibling);
42
- _el$15.nextSibling;
43
- web.insert(_el$6, () => props.component.type);
44
- web.insert(_el$4, web.createComponent(solidJs.Show, {
54
+ var _el$0 = web.getNextElement(_tmpl$6), _el$1 = _el$0.firstChild, _el$10 = _el$1.firstChild, _el$22 = _el$1.nextSibling, [_el$23, _co$4] = web.getNextMarker(_el$22.nextSibling), _el$24 = _el$23.nextSibling, [_el$25, _co$5] = web.getNextMarker(_el$24.nextSibling), _el$17 = _el$25.nextSibling, _el$18 = _el$17.firstChild, _el$20 = _el$18.nextSibling, [_el$21, _co$3] = web.getNextMarker(_el$20.nextSibling);
55
+ _el$21.nextSibling;
56
+ web.insert(_el$10, () => props.component.type);
57
+ web.insert(_el$0, web.createComponent(solidJs.Show, {
45
58
  get when() {
46
59
  return params == null ? void 0 : params.title;
47
60
  },
48
61
  get children() {
49
- var _el$7 = web.getNextElement(_tmpl$2);
50
- web.insert(_el$7, () => params.title);
51
- return _el$7;
62
+ var _el$11 = web.getNextElement(_tmpl$3);
63
+ web.insert(_el$11, () => params.title);
64
+ return _el$11;
52
65
  }
53
- }), _el$17, _co$3);
54
- web.insert(_el$4, web.createComponent(solidJs.Show, {
66
+ }), _el$23, _co$4);
67
+ web.insert(_el$0, web.createComponent(solidJs.Show, {
55
68
  get when() {
56
69
  return web.memo(() => props.component.type === "metric")() && (params == null ? void 0 : params.value);
57
70
  },
58
71
  get children() {
59
- var _el$8 = web.getNextElement(_tmpl$4), _el$9 = _el$8.firstChild, _el$1 = _el$9.nextSibling, [_el$10, _co$] = web.getNextMarker(_el$1.nextSibling);
60
- web.insert(_el$9, () => params.value);
61
- web.insert(_el$8, web.createComponent(solidJs.Show, {
72
+ var _el$12 = web.getNextElement(_tmpl$5), _el$13 = _el$12.firstChild, _el$15 = _el$13.nextSibling, [_el$16, _co$2] = web.getNextMarker(_el$15.nextSibling);
73
+ web.insert(_el$13, () => params.value);
74
+ web.insert(_el$12, web.createComponent(solidJs.Show, {
62
75
  get when() {
63
76
  return params.unit;
64
77
  },
65
78
  get children() {
66
- var _el$0 = web.getNextElement(_tmpl$3);
67
- web.insert(_el$0, () => params.unit);
68
- return _el$0;
79
+ var _el$14 = web.getNextElement(_tmpl$4);
80
+ web.insert(_el$14, () => params.unit);
81
+ return _el$14;
69
82
  }
70
- }), _el$10, _co$);
71
- return _el$8;
83
+ }), _el$16, _co$2);
84
+ return _el$12;
72
85
  }
73
- }), _el$19, _co$4);
74
- web.insert(_el$11, () => props.component.id.slice(0, 8), _el$15, _co$2);
75
- return _el$4;
86
+ }), _el$25, _co$5);
87
+ web.insert(_el$17, () => props.component.id.slice(0, 8), _el$21, _co$3);
88
+ return _el$0;
76
89
  }
77
90
  });
78
91
  }
@@ -106,78 +119,81 @@ function StreamingUIRenderer(props) {
106
119
  }, 500);
107
120
  };
108
121
  return (() => {
109
- var _el$20 = web.getNextElement(_tmpl$12), _el$81 = _el$20.firstChild, [_el$82, _co$15] = web.getNextMarker(_el$81.nextSibling), _el$83 = _el$82.nextSibling, [_el$84, _co$16] = web.getNextMarker(_el$83.nextSibling), _el$45 = _el$84.nextSibling, _el$46 = _el$45.firstChild, [_el$47, _co$0] = web.getNextMarker(_el$46.nextSibling), _el$48 = _el$47.nextSibling, [_el$49, _co$1] = web.getNextMarker(_el$48.nextSibling), _el$85 = _el$45.nextSibling, [_el$86, _co$17] = web.getNextMarker(_el$85.nextSibling);
110
- web.insert(_el$20, web.createComponent(solidJs.Show, {
122
+ var _el$26 = web.getNextElement(_tmpl$13), _el$87 = _el$26.firstChild, [_el$88, _co$16] = web.getNextMarker(_el$87.nextSibling), _el$89 = _el$88.nextSibling, [_el$90, _co$17] = web.getNextMarker(_el$89.nextSibling), _el$51 = _el$90.nextSibling, _el$52 = _el$51.firstChild, [_el$53, _co$1] = web.getNextMarker(_el$52.nextSibling), _el$54 = _el$53.nextSibling, [_el$55, _co$10] = web.getNextMarker(_el$54.nextSibling), _el$91 = _el$51.nextSibling, [_el$92, _co$18] = web.getNextMarker(_el$91.nextSibling);
123
+ web.insert(_el$26, web.createComponent(solidJs.Show, {
111
124
  get when() {
112
125
  return web.memo(() => props.showProgress !== false)() && (isLoading() || isStreaming());
113
126
  },
114
127
  get children() {
115
- var _el$21 = web.getNextElement(_tmpl$8), _el$22 = _el$21.firstChild, _el$23 = _el$22.firstChild, _el$30 = _el$23.nextSibling, [_el$31, _co$7] = web.getNextMarker(_el$30.nextSibling), _el$32 = _el$22.nextSibling, _el$33 = _el$32.firstChild, _el$35 = _el$32.nextSibling, [_el$36, _co$8] = web.getNextMarker(_el$35.nextSibling);
116
- web.insert(_el$23, () => progress().message);
117
- web.insert(_el$22, web.createComponent(solidJs.Show, {
128
+ var _el$27 = web.getNextElement(_tmpl$9), _el$28 = _el$27.firstChild, _el$29 = _el$28.firstChild, _el$36 = _el$29.nextSibling, [_el$37, _co$8] = web.getNextMarker(_el$36.nextSibling), _el$38 = _el$28.nextSibling, _el$39 = _el$38.firstChild, _el$41 = _el$38.nextSibling, [_el$42, _co$9] = web.getNextMarker(_el$41.nextSibling);
129
+ web.insert(_el$29, () => progress().message);
130
+ web.insert(_el$28, web.createComponent(solidJs.Show, {
118
131
  get when() {
119
132
  return progress().totalCount !== null;
120
133
  },
121
134
  get children() {
122
- var _el$24 = web.getNextElement(_tmpl$6), _el$26 = _el$24.firstChild, [_el$27, _co$5] = web.getNextMarker(_el$26.nextSibling), _el$25 = _el$27.nextSibling, _el$28 = _el$25.nextSibling, [_el$29, _co$6] = web.getNextMarker(_el$28.nextSibling);
123
- web.insert(_el$24, () => progress().receivedCount, _el$27, _co$5);
124
- web.insert(_el$24, () => progress().totalCount, _el$29, _co$6);
125
- return _el$24;
135
+ var _el$30 = web.getNextElement(_tmpl$7), _el$32 = _el$30.firstChild, [_el$33, _co$6] = web.getNextMarker(_el$32.nextSibling), _el$31 = _el$33.nextSibling, _el$34 = _el$31.nextSibling, [_el$35, _co$7] = web.getNextMarker(_el$34.nextSibling);
136
+ web.insert(_el$30, () => progress().receivedCount, _el$33, _co$6);
137
+ web.insert(_el$30, () => progress().totalCount, _el$35, _co$7);
138
+ return _el$30;
126
139
  }
127
- }), _el$31, _co$7);
128
- web.insert(_el$21, web.createComponent(solidJs.Show, {
140
+ }), _el$37, _co$8);
141
+ web.insert(_el$27, web.createComponent(solidJs.Show, {
129
142
  get when() {
130
143
  return web.memo(() => progress().totalCount === null)() && isStreaming();
131
144
  },
132
145
  get children() {
133
- return web.getNextElement(_tmpl$7);
146
+ return web.getNextElement(_tmpl$8);
134
147
  }
135
- }), _el$36, _co$8);
136
- web.effect((_$p) => web.style(_el$33, progress().totalCount !== null ? `width: ${progress().receivedCount / progress().totalCount * 100}%` : "width: 0%", _$p));
137
- return _el$21;
148
+ }), _el$42, _co$9);
149
+ web.effect((_$p) => web.style(_el$39, progress().totalCount !== null ? `width: ${progress().receivedCount / progress().totalCount * 100}%` : "width: 0%", _$p));
150
+ return _el$27;
138
151
  }
139
- }), _el$82, _co$15);
140
- web.insert(_el$20, web.createComponent(solidJs.Show, {
152
+ }), _el$88, _co$16);
153
+ web.insert(_el$26, web.createComponent(solidJs.Show, {
141
154
  get when() {
142
155
  return error();
143
156
  },
144
157
  get children() {
145
- var _el$37 = web.getNextElement(_tmpl$0), _el$38 = _el$37.firstChild, _el$39 = _el$38.firstChild, _el$40 = _el$39.nextSibling, _el$41 = _el$38.nextSibling, _el$43 = _el$41.nextSibling, [_el$44, _co$9] = web.getNextMarker(_el$43.nextSibling);
146
- web.insert(_el$40, () => {
158
+ var _el$43 = web.getNextElement(_tmpl$1), _el$44 = _el$43.firstChild, _el$45 = _el$44.firstChild, _el$46 = _el$45.nextSibling, _el$47 = _el$44.nextSibling, _el$49 = _el$47.nextSibling, [_el$50, _co$0] = web.getNextMarker(_el$49.nextSibling);
159
+ web.insert(_el$46, () => {
147
160
  var _a;
148
161
  return (_a = error()) == null ? void 0 : _a.error;
149
162
  });
150
- web.insert(_el$41, () => {
163
+ web.insert(_el$47, () => {
151
164
  var _a;
152
165
  return (_a = error()) == null ? void 0 : _a.message;
153
166
  });
154
- web.insert(_el$37, web.createComponent(solidJs.Show, {
167
+ web.insert(_el$43, web.createComponent(solidJs.Show, {
155
168
  get when() {
156
169
  var _a;
157
170
  return (_a = error()) == null ? void 0 : _a.recoverable;
158
171
  },
159
172
  get children() {
160
- var _el$42 = web.getNextElement(_tmpl$9);
161
- _el$42.$$click = () => startStreaming();
173
+ var _el$48 = web.getNextElement(_tmpl$0);
174
+ _el$48.$$click = () => startStreaming();
162
175
  web.runHydrationEvents();
163
- return _el$42;
176
+ return _el$48;
164
177
  }
165
- }), _el$44, _co$9);
166
- return _el$37;
178
+ }), _el$50, _co$0);
179
+ return _el$43;
167
180
  }
168
- }), _el$84, _co$16);
169
- web.insert(_el$45, web.createComponent(solidJs.For, {
181
+ }), _el$90, _co$17);
182
+ web.insert(_el$51, web.createComponent(solidJs.For, {
170
183
  get each() {
171
184
  return components();
172
185
  },
173
186
  children: (component) => {
174
187
  solidJs.onMount(() => handleComponentRender(component.id));
175
188
  return (() => {
176
- var _el$87 = web.getNextElement(_tmpl$13);
177
- web.insert(_el$87, web.createComponent(StreamingComponentRenderer, {
189
+ var _el$93 = web.getNextElement(_tmpl$14);
190
+ web.insert(_el$93, web.createComponent(StreamingComponentRenderer, {
178
191
  component,
179
192
  get onError() {
180
193
  return props.onRenderError;
194
+ },
195
+ get errorMode() {
196
+ return props.errorMode;
181
197
  }
182
198
  }));
183
199
  web.effect((_p$) => {
@@ -185,18 +201,18 @@ function StreamingUIRenderer(props) {
185
201
  col-span-${component.position.colSpan}
186
202
  ${animatingComponents().has(component.id) ? "animate-fade-in-up" : ""}
187
203
  `, _v$2 = `grid-column-start: ${component.position.colStart}; grid-column-end: ${component.position.colStart + component.position.colSpan}`;
188
- _v$ !== _p$.e && web.className(_el$87, _p$.e = _v$);
189
- _p$.t = web.style(_el$87, _v$2, _p$.t);
204
+ _v$ !== _p$.e && web.className(_el$93, _p$.e = _v$);
205
+ _p$.t = web.style(_el$93, _v$2, _p$.t);
190
206
  return _p$;
191
207
  }, {
192
208
  e: void 0,
193
209
  t: void 0
194
210
  });
195
- return _el$87;
211
+ return _el$93;
196
212
  })();
197
213
  }
198
- }), _el$47, _co$0);
199
- web.insert(_el$45, web.createComponent(solidJs.Show, {
214
+ }), _el$53, _co$1);
215
+ web.insert(_el$51, web.createComponent(solidJs.Show, {
200
216
  get when() {
201
217
  return web.memo(() => !!isStreaming())() && progress().totalCount !== null;
202
218
  },
@@ -210,65 +226,65 @@ function StreamingUIRenderer(props) {
210
226
  children: () => web.createComponent(SkeletonComponent, {})
211
227
  });
212
228
  }
213
- }), _el$49, _co$1);
214
- web.insert(_el$20, web.createComponent(solidJs.Show, {
229
+ }), _el$55, _co$10);
230
+ web.insert(_el$26, web.createComponent(solidJs.Show, {
215
231
  get when() {
216
232
  return web.memo(() => props.showMetadata !== false)() && metadata();
217
233
  },
218
234
  get children() {
219
- var _el$50 = web.getNextElement(_tmpl$11), _el$51 = _el$50.firstChild, _el$52 = _el$51.firstChild, _el$53 = _el$52.firstChild, _el$54 = _el$53.nextSibling, _el$55 = _el$52.nextSibling, _el$56 = _el$55.firstChild, _el$57 = _el$56.nextSibling, _el$58 = _el$55.nextSibling, _el$59 = _el$58.firstChild, _el$60 = _el$59.nextSibling, _el$62 = _el$60.firstChild, [_el$63, _co$10] = web.getNextMarker(_el$62.nextSibling);
220
- _el$63.nextSibling;
221
- var _el$77 = _el$58.nextSibling, [_el$78, _co$13] = web.getNextMarker(_el$77.nextSibling), _el$70 = _el$78.nextSibling, _el$71 = _el$70.firstChild, _el$72 = _el$71.nextSibling, _el$74 = _el$72.firstChild, [_el$75, _co$12] = web.getNextMarker(_el$74.nextSibling);
222
- _el$75.nextSibling;
223
- var _el$79 = _el$70.nextSibling, [_el$80, _co$14] = web.getNextMarker(_el$79.nextSibling);
224
- web.insert(_el$54, () => {
235
+ var _el$56 = web.getNextElement(_tmpl$12), _el$57 = _el$56.firstChild, _el$58 = _el$57.firstChild, _el$59 = _el$58.firstChild, _el$60 = _el$59.nextSibling, _el$61 = _el$58.nextSibling, _el$62 = _el$61.firstChild, _el$63 = _el$62.nextSibling, _el$64 = _el$61.nextSibling, _el$65 = _el$64.firstChild, _el$66 = _el$65.nextSibling, _el$68 = _el$66.firstChild, [_el$69, _co$11] = web.getNextMarker(_el$68.nextSibling);
236
+ _el$69.nextSibling;
237
+ var _el$83 = _el$64.nextSibling, [_el$84, _co$14] = web.getNextMarker(_el$83.nextSibling), _el$76 = _el$84.nextSibling, _el$77 = _el$76.firstChild, _el$78 = _el$77.nextSibling, _el$80 = _el$78.firstChild, [_el$81, _co$13] = web.getNextMarker(_el$80.nextSibling);
238
+ _el$81.nextSibling;
239
+ var _el$85 = _el$76.nextSibling, [_el$86, _co$15] = web.getNextMarker(_el$85.nextSibling);
240
+ web.insert(_el$60, () => {
225
241
  var _a;
226
242
  return (_a = metadata()) == null ? void 0 : _a.provider;
227
243
  });
228
- web.insert(_el$57, () => {
244
+ web.insert(_el$63, () => {
229
245
  var _a;
230
246
  return (_a = metadata()) == null ? void 0 : _a.model;
231
247
  });
232
- web.insert(_el$60, () => {
248
+ web.insert(_el$66, () => {
233
249
  var _a;
234
250
  return (_a = metadata()) == null ? void 0 : _a.executionTimeMs;
235
- }, _el$63, _co$10);
236
- web.insert(_el$51, web.createComponent(solidJs.Show, {
251
+ }, _el$69, _co$11);
252
+ web.insert(_el$57, web.createComponent(solidJs.Show, {
237
253
  get when() {
238
254
  var _a;
239
255
  return ((_a = metadata()) == null ? void 0 : _a.costUSD) !== void 0;
240
256
  },
241
257
  get children() {
242
- var _el$64 = web.getNextElement(_tmpl$1), _el$65 = _el$64.firstChild, _el$66 = _el$65.nextSibling, _el$67 = _el$66.firstChild, _el$68 = _el$67.nextSibling, [_el$69, _co$11] = web.getNextMarker(_el$68.nextSibling);
243
- web.insert(_el$66, () => {
258
+ var _el$70 = web.getNextElement(_tmpl$10), _el$71 = _el$70.firstChild, _el$72 = _el$71.nextSibling, _el$73 = _el$72.firstChild, _el$74 = _el$73.nextSibling, [_el$75, _co$12] = web.getNextMarker(_el$74.nextSibling);
259
+ web.insert(_el$72, () => {
244
260
  var _a, _b;
245
261
  return (_b = (_a = metadata()) == null ? void 0 : _a.costUSD) == null ? void 0 : _b.toFixed(4);
246
- }, _el$69, _co$11);
247
- return _el$64;
262
+ }, _el$75, _co$12);
263
+ return _el$70;
248
264
  }
249
- }), _el$78, _co$13);
250
- web.insert(_el$72, () => {
265
+ }), _el$84, _co$14);
266
+ web.insert(_el$78, () => {
251
267
  var _a;
252
268
  return (_a = metadata()) == null ? void 0 : _a.firstTokenMs;
253
- }, _el$75, _co$12);
254
- web.insert(_el$51, web.createComponent(solidJs.Show, {
269
+ }, _el$81, _co$13);
270
+ web.insert(_el$57, web.createComponent(solidJs.Show, {
255
271
  get when() {
256
272
  var _a;
257
273
  return (_a = metadata()) == null ? void 0 : _a.cached;
258
274
  },
259
275
  get children() {
260
- return web.getNextElement(_tmpl$10);
276
+ return web.getNextElement(_tmpl$11);
261
277
  }
262
- }), _el$80, _co$14);
263
- return _el$50;
278
+ }), _el$86, _co$15);
279
+ return _el$56;
264
280
  }
265
- }), _el$86, _co$17);
266
- web.effect(() => web.className(_el$20, `streaming-ui-renderer ${props.class || ""}`));
267
- return _el$20;
281
+ }), _el$92, _co$18);
282
+ web.effect(() => web.className(_el$26, `streaming-ui-renderer ${props.class || ""}`));
283
+ return _el$26;
268
284
  })();
269
285
  }
270
286
  function SkeletonComponent() {
271
- return web.getNextElement(_tmpl$14);
287
+ return web.getNextElement(_tmpl$15);
272
288
  }
273
289
  web.delegateEvents(["click"]);
274
290
  exports.StreamingUIRenderer = StreamingUIRenderer;
@@ -1 +1 @@
1
- {"version":3,"file":"StreamingUIRenderer.cjs","sources":["../../src/components/StreamingUIRenderer.tsx"],"sourcesContent":["/**\n * StreamingUIRenderer Component - Phase 2\n *\n * Renders streaming dashboard components with skeleton states and progress indicators.\n * Uses the useStreamingUI hook for SSE connection and state management.\n *\n * Features:\n * - Skeleton loading states while components stream\n * - Progress bar and status messages\n * - Smooth component animations on arrival\n * - Error handling with retry capability\n * - Responsive 12-column grid layout\n *\n * Usage:\n * ```tsx\n * <StreamingUIRenderer\n * query=\"Show me revenue trends\"\n * spaceIds={['uuid1', 'uuid2']}\n * onComplete={(metadata) => console.log('Done!', metadata)}\n * />\n * ```\n */\n\nimport { Show, For, createSignal, onMount } from 'solid-js'\nimport { useStreamingUI, type UseStreamingUIOptions } from '../hooks/useStreamingUI'\nimport type { UIComponent, RendererError } from '../types'\nimport { validateComponent } from '../services/validation'\nimport { GenerativeUIErrorBoundary } from './GenerativeUIErrorBoundary'\n\nexport interface StreamingUIRendererProps extends UseStreamingUIOptions {\n class?: string\n showProgress?: boolean\n showMetadata?: boolean\n onRenderError?: (error: RendererError) => void\n}\n\n/**\n * Component Renderer - Inline lightweight version\n * (Full implementation in UIResourceRenderer)\n */\nfunction StreamingComponentRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n}) {\n // Validate component before rendering\n const validation = validateComponent(props.component)\n if (!validation.valid) {\n props.onError?.({\n type: 'validation',\n message: 'Component validation failed',\n componentId: props.component.id,\n details: validation.errors,\n })\n\n return (\n <div class=\"w-full bg-error-subtle border border-border-error rounded-lg p-4\">\n <p class=\"text-sm font-medium text-error-primary\">Validation Error</p>\n <p class=\"text-xs text-text-secondary mt-1\">\n {validation.errors?.[0]?.message || 'Unknown validation error'}\n </p>\n </div>\n )\n }\n\n // Simplified renderer - just show component type and title\n // Full rendering logic in UIResourceRenderer\n const params = props.component.params as any\n\n return (\n <GenerativeUIErrorBoundary\n componentId={props.component.id}\n componentType={props.component.type}\n onError={props.onError}\n allowRetry={false}\n >\n <div class=\"w-full bg-surface-secondary border border-border-subtle rounded-lg p-4\">\n <div class=\"flex items-center gap-2 mb-2\">\n <span class=\"text-xs font-medium text-text-tertiary uppercase\">\n {props.component.type}\n </span>\n </div>\n <Show when={params?.title}>\n <h3 class=\"text-sm font-semibold text-text-primary\">{params.title}</h3>\n </Show>\n <Show when={props.component.type === 'metric' && params?.value}>\n <div class=\"mt-2\">\n <p class=\"text-2xl font-semibold text-text-primary\">{params.value}</p>\n <Show when={params.unit}>\n <span class=\"text-sm text-text-secondary\">{params.unit}</span>\n </Show>\n </div>\n </Show>\n <div class=\"mt-3 text-xs text-text-tertiary\">\n Component ID: {props.component.id.slice(0, 8)}...\n </div>\n </div>\n </GenerativeUIErrorBoundary>\n )\n}\n\nexport function StreamingUIRenderer(props: StreamingUIRendererProps) {\n const { components, isLoading, isStreaming, error, progress, metadata, startStreaming } =\n useStreamingUI({\n query: props.query,\n spaceIds: props.spaceIds,\n sessionId: props.sessionId,\n options: props.options,\n onComplete: props.onComplete,\n onError: props.onError,\n onComponentReceived: props.onComponentReceived,\n })\n\n const [animatingComponents, setAnimatingComponents] = createSignal<Set<string>>(new Set())\n\n // Track new components for animation\n const handleComponentRender = (componentId: string) => {\n setAnimatingComponents((prev) => new Set([...prev, componentId]))\n\n // Remove from animating set after animation completes\n setTimeout(() => {\n setAnimatingComponents((prev) => {\n const next = new Set(prev)\n next.delete(componentId)\n return next\n })\n }, 500)\n }\n\n return (\n <div class={`streaming-ui-renderer ${props.class || ''}`}>\n {/* Progress Bar */}\n <Show when={props.showProgress !== false && (isLoading() || isStreaming())}>\n <div class=\"mb-4 rounded-lg border border-border-subtle bg-surface-secondary p-4\">\n {/* Status Message */}\n <div class=\"mb-2 flex items-center justify-between\">\n <span class=\"text-sm font-medium text-text-primary\">{progress().message}</span>\n <Show when={progress().totalCount !== null}>\n <span class=\"text-sm text-text-secondary\">\n {progress().receivedCount} / {progress().totalCount}\n </span>\n </Show>\n </div>\n\n {/* Progress Bar */}\n <div class=\"h-2 w-full overflow-hidden rounded-full bg-surface-tertiary\">\n <div\n class=\"h-full bg-brand-primary transition-all duration-300 ease-out\"\n style={\n progress().totalCount !== null\n ? `width: ${(progress().receivedCount / progress().totalCount!) * 100}%`\n : 'width: 0%'\n }\n />\n </div>\n\n {/* Indeterminate Progress (when totalCount unknown) */}\n <Show when={progress().totalCount === null && isStreaming()}>\n <div class=\"mt-2\">\n <div class=\"h-1 w-full overflow-hidden rounded-full bg-surface-tertiary\">\n <div class=\"animate-progress-indeterminate h-full w-1/3 bg-brand-primary\" />\n </div>\n </div>\n </Show>\n </div>\n </Show>\n\n {/* Error State */}\n <Show when={error()}>\n <div class=\"mb-4 rounded-lg border border-border-error bg-error-subtle p-4\">\n <div class=\"mb-2 flex items-center gap-2\">\n <svg\n class=\"h-5 w-5 text-error-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span class=\"font-medium text-error-primary\">{error()?.error}</span>\n </div>\n <p class=\"text-sm text-text-secondary\">{error()?.message}</p>\n\n {/* Retry Button (if recoverable) */}\n <Show when={error()?.recoverable}>\n <button\n type=\"button\"\n class=\"mt-3 rounded-md bg-error-primary px-3 py-1.5 text-sm font-medium text-white hover:bg-error-hover\"\n onClick={() => startStreaming()}\n >\n Retry\n </button>\n </Show>\n </div>\n </Show>\n\n {/* Components Grid */}\n <div class=\"grid grid-cols-12 gap-4\">\n {/* Render received components */}\n <For each={components()}>\n {(component) => {\n // Trigger animation on mount (SSR-safe, no 'use' directive needed)\n onMount(() => handleComponentRender(component.id))\n\n return (\n <div\n class={`\n col-span-${component.position.colSpan}\n ${animatingComponents().has(component.id) ? 'animate-fade-in-up' : ''}\n `}\n style={`grid-column-start: ${component.position.colStart}; grid-column-end: ${component.position.colStart + component.position.colSpan}`}\n >\n <StreamingComponentRenderer component={component} onError={props.onRenderError} />\n </div>\n )\n }}\n </For>\n\n {/* Skeleton placeholders (if streaming and expecting more) */}\n <Show when={isStreaming() && progress().totalCount !== null}>\n <For\n each={Array.from({\n length: progress().totalCount! - progress().receivedCount,\n })}\n >\n {() => <SkeletonComponent />}\n </For>\n </Show>\n </div>\n\n {/* Metadata Display */}\n <Show when={props.showMetadata !== false && metadata()}>\n <div class=\"mt-6 rounded-lg border border-border-subtle bg-surface-secondary p-4 text-sm text-text-secondary\">\n <div class=\"grid grid-cols-2 gap-4 md:grid-cols-4\">\n <div>\n <div class=\"font-medium text-text-primary\">Provider</div>\n <div>{metadata()?.provider}</div>\n </div>\n <div>\n <div class=\"font-medium text-text-primary\">Model</div>\n <div>{metadata()?.model}</div>\n </div>\n <div>\n <div class=\"font-medium text-text-primary\">Execution Time</div>\n <div>{metadata()?.executionTimeMs}ms</div>\n </div>\n <Show when={metadata()?.costUSD !== undefined}>\n <div>\n <div class=\"font-medium text-text-primary\">Cost</div>\n <div>${metadata()?.costUSD?.toFixed(4)}</div>\n </div>\n </Show>\n <div>\n <div class=\"font-medium text-text-primary\">TTFB</div>\n <div>{metadata()?.firstTokenMs}ms</div>\n </div>\n <Show when={metadata()?.cached}>\n <div>\n <div class=\"font-medium text-text-primary\">Cached</div>\n <div class=\"text-success-primary\">Yes</div>\n </div>\n </Show>\n </div>\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * Skeleton Component - Placeholder while components load\n */\nfunction SkeletonComponent() {\n return (\n <div class=\"col-span-12 md:col-span-6 lg:col-span-4\">\n <div class=\"animate-pulse rounded-lg border border-border-subtle bg-surface-secondary p-4\">\n {/* Header skeleton */}\n <div class=\"mb-4 h-6 w-1/2 rounded bg-surface-tertiary\" />\n\n {/* Content skeleton */}\n <div class=\"space-y-3\">\n <div class=\"h-4 rounded bg-surface-tertiary\" />\n <div class=\"h-4 w-5/6 rounded bg-surface-tertiary\" />\n <div class=\"h-4 w-4/6 rounded bg-surface-tertiary\" />\n </div>\n\n {/* Chart/visual skeleton */}\n <div class=\"mt-4 h-32 rounded bg-surface-tertiary\" />\n </div>\n </div>\n )\n}\n\n// CSS Animations (add to global styles or Tailwind config)\n/*\n@keyframes fade-in-up {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes progress-indeterminate {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n\n.animate-fade-in-up {\n animation: fade-in-up 0.5s ease-out;\n}\n\n.animate-progress-indeterminate {\n animation: progress-indeterminate 1.5s infinite ease-in-out;\n}\n*/\n"],"names":["StreamingComponentRenderer","props","validation","validateComponent","component","valid","onError","type","message","componentId","id","details","errors","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","nextSibling","_$insert","params","_$createComponent","GenerativeUIErrorBoundary","componentType","allowRetry","children","_el$4","_tmpl$5","_el$5","_el$6","_el$16","_el$17","_co$3","_$getNextMarker","_el$18","_el$19","_co$4","_el$11","_el$12","_el$14","_el$15","_co$2","Show","when","title","_el$7","_tmpl$2","_$memo","value","_el$8","_tmpl$4","_el$9","_el$1","_el$10","_co$","unit","_el$0","_tmpl$3","slice","StreamingUIRenderer","components","isLoading","isStreaming","error","progress","metadata","startStreaming","useStreamingUI","query","spaceIds","sessionId","options","onComplete","onComponentReceived","animatingComponents","setAnimatingComponents","createSignal","Set","handleComponentRender","prev","setTimeout","next","delete","_el$20","_tmpl$12","_el$81","_el$82","_co$15","_el$83","_el$84","_co$16","_el$45","_el$46","_el$47","_co$0","_el$48","_el$49","_co$1","_el$85","_el$86","_co$17","showProgress","_el$21","_tmpl$8","_el$22","_el$23","_el$30","_el$31","_co$7","_el$32","_el$33","_el$35","_el$36","_co$8","totalCount","_el$24","_tmpl$6","_el$26","_el$27","_co$5","_el$25","_el$28","_el$29","_co$6","receivedCount","_tmpl$7","_$effect","_$p","_$style","_el$37","_tmpl$0","_el$38","_el$39","_el$40","_el$41","_el$43","_el$44","_co$9","recoverable","_el$42","_tmpl$9","$$click","_$runHydrationEvents","For","each","onMount","_el$87","_tmpl$13","onRenderError","_p$","_v$","position","colSpan","has","_v$2","colStart","e","_$className","t","undefined","Array","from","length","SkeletonComponent","showMetadata","_el$50","_tmpl$11","_el$51","_el$52","_el$53","_el$54","_el$55","_el$56","_el$57","_el$58","_el$59","_el$60","_el$62","_el$63","_co$10","_el$77","_el$78","_co$13","_el$70","_el$71","_el$72","_el$74","_el$75","_co$12","_el$79","_el$80","_co$14","provider","model","executionTimeMs","costUSD","_el$64","_tmpl$1","_el$65","_el$66","_el$67","_el$68","_el$69","_co$11","toFixed","firstTokenMs","cached","_tmpl$10","class","_tmpl$14","_$delegateEvents"],"mappings":"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"}
1
+ {"version":3,"file":"StreamingUIRenderer.cjs","sources":["../../src/components/StreamingUIRenderer.tsx"],"sourcesContent":["/**\n * StreamingUIRenderer Component - Phase 2\n *\n * Renders streaming dashboard components with skeleton states and progress indicators.\n * Uses the useStreamingUI hook for SSE connection and state management.\n *\n * Features:\n * - Skeleton loading states while components stream\n * - Progress bar and status messages\n * - Smooth component animations on arrival\n * - Error handling with retry capability\n * - Responsive 12-column grid layout\n *\n * Usage:\n * ```tsx\n * <StreamingUIRenderer\n * query=\"Show me revenue trends\"\n * spaceIds={['uuid1', 'uuid2']}\n * onComplete={(metadata) => console.log('Done!', metadata)}\n * />\n * ```\n */\n\nimport { Show, For, createSignal, onMount } from 'solid-js'\nimport { useStreamingUI, type UseStreamingUIOptions } from '../hooks/useStreamingUI'\nimport type { UIComponent, RendererError } from '../types'\nimport { validateComponent } from '../services/validation'\nimport { GenerativeUIErrorBoundary } from './GenerativeUIErrorBoundary'\nimport { markRenderStart, markRenderEnd } from '../utils/perf'\nimport type { ValidationErrorMode } from './UIResourceRenderer'\n\nexport interface StreamingUIRendererProps extends UseStreamingUIOptions {\n class?: string\n showProgress?: boolean\n showMetadata?: boolean\n onRenderError?: (error: RendererError) => void\n /**\n * How to react when a streamed component fails `validateComponent()`\n * (v5.4.0). Defaults to `'block'` (full red error card — pre-v5.4.0\n * behavior). See `ValidationErrorMode` in `UIResourceRenderer`.\n */\n errorMode?: ValidationErrorMode\n}\n\n/**\n * Component Renderer - Inline lightweight version\n * (Full implementation in UIResourceRenderer)\n */\nfunction StreamingComponentRenderer(props: {\n component: UIComponent\n onError?: (error: RendererError) => void\n errorMode?: ValidationErrorMode\n}) {\n // Performance marks (v5.4.0) — see utils/perf.ts\n markRenderStart(props.component.id)\n onMount(() => markRenderEnd(props.component.id))\n\n // Validate component before rendering\n const validation = validateComponent(props.component)\n if (!validation.valid) {\n props.onError?.({\n type: 'validation',\n message: 'Component validation failed',\n componentId: props.component.id,\n details: validation.errors,\n })\n\n const mode: ValidationErrorMode = props.errorMode ?? 'block'\n const firstError = validation.errors?.[0]?.message || 'Unknown validation error'\n\n if (mode === 'silent') {\n return null\n }\n\n if (mode === 'inline-warn') {\n return (\n <div\n class=\"inline-flex items-center gap-1.5 px-2 py-1 rounded-md bg-yellow-50 dark:bg-yellow-900/20 border border-yellow-200 dark:border-yellow-800 text-xs text-yellow-800 dark:text-yellow-200\"\n role=\"alert\"\n aria-label=\"Component validation warning\"\n title={firstError}\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"w-3.5 h-3.5\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n stroke-width=\"2\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M10.29 3.86 1.82 18a2 2 0 0 0 1.71 3h16.94a2 2 0 0 0 1.71-3L13.71 3.86a2 2 0 0 0-3.42 0z\" />\n <line x1=\"12\" y1=\"9\" x2=\"12\" y2=\"13\" />\n <line x1=\"12\" y1=\"17\" x2=\"12.01\" y2=\"17\" />\n </svg>\n <span>Invalid {props.component.type}</span>\n </div>\n )\n }\n\n return (\n <div class=\"w-full bg-error-subtle border border-border-error rounded-lg p-4\">\n <p class=\"text-sm font-medium text-error-primary\">Validation Error</p>\n <p class=\"text-xs text-text-secondary mt-1\">\n {firstError}\n </p>\n </div>\n )\n }\n\n // Simplified renderer - just show component type and title\n // Full rendering logic in UIResourceRenderer\n const params = props.component.params as any\n\n return (\n <GenerativeUIErrorBoundary\n componentId={props.component.id}\n componentType={props.component.type}\n onError={props.onError}\n allowRetry={false}\n >\n <div class=\"w-full bg-surface-secondary border border-border-subtle rounded-lg p-4\">\n <div class=\"flex items-center gap-2 mb-2\">\n <span class=\"text-xs font-medium text-text-tertiary uppercase\">\n {props.component.type}\n </span>\n </div>\n <Show when={params?.title}>\n <h3 class=\"text-sm font-semibold text-text-primary\">{params.title}</h3>\n </Show>\n <Show when={props.component.type === 'metric' && params?.value}>\n <div class=\"mt-2\">\n <p class=\"text-2xl font-semibold text-text-primary\">{params.value}</p>\n <Show when={params.unit}>\n <span class=\"text-sm text-text-secondary\">{params.unit}</span>\n </Show>\n </div>\n </Show>\n <div class=\"mt-3 text-xs text-text-tertiary\">\n Component ID: {props.component.id.slice(0, 8)}...\n </div>\n </div>\n </GenerativeUIErrorBoundary>\n )\n}\n\nexport function StreamingUIRenderer(props: StreamingUIRendererProps) {\n const { components, isLoading, isStreaming, error, progress, metadata, startStreaming } =\n useStreamingUI({\n query: props.query,\n spaceIds: props.spaceIds,\n sessionId: props.sessionId,\n options: props.options,\n onComplete: props.onComplete,\n onError: props.onError,\n onComponentReceived: props.onComponentReceived,\n })\n\n const [animatingComponents, setAnimatingComponents] = createSignal<Set<string>>(new Set())\n\n // Track new components for animation\n const handleComponentRender = (componentId: string) => {\n setAnimatingComponents((prev) => new Set([...prev, componentId]))\n\n // Remove from animating set after animation completes\n setTimeout(() => {\n setAnimatingComponents((prev) => {\n const next = new Set(prev)\n next.delete(componentId)\n return next\n })\n }, 500)\n }\n\n return (\n <div class={`streaming-ui-renderer ${props.class || ''}`}>\n {/* Progress Bar */}\n <Show when={props.showProgress !== false && (isLoading() || isStreaming())}>\n <div class=\"mb-4 rounded-lg border border-border-subtle bg-surface-secondary p-4\">\n {/* Status Message */}\n <div class=\"mb-2 flex items-center justify-between\">\n <span class=\"text-sm font-medium text-text-primary\">{progress().message}</span>\n <Show when={progress().totalCount !== null}>\n <span class=\"text-sm text-text-secondary\">\n {progress().receivedCount} / {progress().totalCount}\n </span>\n </Show>\n </div>\n\n {/* Progress Bar */}\n <div class=\"h-2 w-full overflow-hidden rounded-full bg-surface-tertiary\">\n <div\n class=\"h-full bg-brand-primary transition-all duration-300 ease-out\"\n style={\n progress().totalCount !== null\n ? `width: ${(progress().receivedCount / progress().totalCount!) * 100}%`\n : 'width: 0%'\n }\n />\n </div>\n\n {/* Indeterminate Progress (when totalCount unknown) */}\n <Show when={progress().totalCount === null && isStreaming()}>\n <div class=\"mt-2\">\n <div class=\"h-1 w-full overflow-hidden rounded-full bg-surface-tertiary\">\n <div class=\"animate-progress-indeterminate h-full w-1/3 bg-brand-primary\" />\n </div>\n </div>\n </Show>\n </div>\n </Show>\n\n {/* Error State */}\n <Show when={error()}>\n <div class=\"mb-4 rounded-lg border border-border-error bg-error-subtle p-4\">\n <div class=\"mb-2 flex items-center gap-2\">\n <svg\n class=\"h-5 w-5 text-error-primary\"\n fill=\"none\"\n viewBox=\"0 0 24 24\"\n stroke=\"currentColor\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z\"\n />\n </svg>\n <span class=\"font-medium text-error-primary\">{error()?.error}</span>\n </div>\n <p class=\"text-sm text-text-secondary\">{error()?.message}</p>\n\n {/* Retry Button (if recoverable) */}\n <Show when={error()?.recoverable}>\n <button\n type=\"button\"\n class=\"mt-3 rounded-md bg-error-primary px-3 py-1.5 text-sm font-medium text-white hover:bg-error-hover\"\n onClick={() => startStreaming()}\n >\n Retry\n </button>\n </Show>\n </div>\n </Show>\n\n {/* Components Grid */}\n <div class=\"grid grid-cols-12 gap-4\">\n {/* Render received components */}\n <For each={components()}>\n {(component) => {\n // Trigger animation on mount (SSR-safe, no 'use' directive needed)\n onMount(() => handleComponentRender(component.id))\n\n return (\n <div\n class={`\n col-span-${component.position.colSpan}\n ${animatingComponents().has(component.id) ? 'animate-fade-in-up' : ''}\n `}\n style={`grid-column-start: ${component.position.colStart}; grid-column-end: ${component.position.colStart + component.position.colSpan}`}\n >\n <StreamingComponentRenderer\n component={component}\n onError={props.onRenderError}\n errorMode={props.errorMode}\n />\n </div>\n )\n }}\n </For>\n\n {/* Skeleton placeholders (if streaming and expecting more) */}\n <Show when={isStreaming() && progress().totalCount !== null}>\n <For\n each={Array.from({\n length: progress().totalCount! - progress().receivedCount,\n })}\n >\n {() => <SkeletonComponent />}\n </For>\n </Show>\n </div>\n\n {/* Metadata Display */}\n <Show when={props.showMetadata !== false && metadata()}>\n <div class=\"mt-6 rounded-lg border border-border-subtle bg-surface-secondary p-4 text-sm text-text-secondary\">\n <div class=\"grid grid-cols-2 gap-4 md:grid-cols-4\">\n <div>\n <div class=\"font-medium text-text-primary\">Provider</div>\n <div>{metadata()?.provider}</div>\n </div>\n <div>\n <div class=\"font-medium text-text-primary\">Model</div>\n <div>{metadata()?.model}</div>\n </div>\n <div>\n <div class=\"font-medium text-text-primary\">Execution Time</div>\n <div>{metadata()?.executionTimeMs}ms</div>\n </div>\n <Show when={metadata()?.costUSD !== undefined}>\n <div>\n <div class=\"font-medium text-text-primary\">Cost</div>\n <div>${metadata()?.costUSD?.toFixed(4)}</div>\n </div>\n </Show>\n <div>\n <div class=\"font-medium text-text-primary\">TTFB</div>\n <div>{metadata()?.firstTokenMs}ms</div>\n </div>\n <Show when={metadata()?.cached}>\n <div>\n <div class=\"font-medium text-text-primary\">Cached</div>\n <div class=\"text-success-primary\">Yes</div>\n </div>\n </Show>\n </div>\n </div>\n </Show>\n </div>\n )\n}\n\n/**\n * Skeleton Component - Placeholder while components load\n */\nfunction SkeletonComponent() {\n return (\n <div class=\"col-span-12 md:col-span-6 lg:col-span-4\">\n <div class=\"animate-pulse rounded-lg border border-border-subtle bg-surface-secondary p-4\">\n {/* Header skeleton */}\n <div class=\"mb-4 h-6 w-1/2 rounded bg-surface-tertiary\" />\n\n {/* Content skeleton */}\n <div class=\"space-y-3\">\n <div class=\"h-4 rounded bg-surface-tertiary\" />\n <div class=\"h-4 w-5/6 rounded bg-surface-tertiary\" />\n <div class=\"h-4 w-4/6 rounded bg-surface-tertiary\" />\n </div>\n\n {/* Chart/visual skeleton */}\n <div class=\"mt-4 h-32 rounded bg-surface-tertiary\" />\n </div>\n </div>\n )\n}\n\n// CSS Animations (add to global styles or Tailwind config)\n/*\n@keyframes fade-in-up {\n from {\n opacity: 0;\n transform: translateY(10px);\n }\n to {\n opacity: 1;\n transform: translateY(0);\n }\n}\n\n@keyframes progress-indeterminate {\n 0% {\n transform: translateX(-100%);\n }\n 100% {\n transform: translateX(400%);\n }\n}\n\n.animate-fade-in-up {\n animation: fade-in-up 0.5s ease-out;\n}\n\n.animate-progress-indeterminate {\n animation: progress-indeterminate 1.5s infinite ease-in-out;\n}\n*/\n"],"names":["StreamingComponentRenderer","props","markRenderStart","component","id","onMount","markRenderEnd","validation","validateComponent","valid","onError","type","message","componentId","details","errors","mode","errorMode","firstError","_el$","_$getNextElement","_tmpl$","_el$2","firstChild","_el$3","nextSibling","_el$4","_el$5","_el$6","_co$","_$getNextMarker","_$setAttribute","_$insert","_el$7","_tmpl$2","_el$8","_el$9","params","_$createComponent","GenerativeUIErrorBoundary","componentType","allowRetry","children","_el$0","_tmpl$6","_el$1","_el$10","_el$22","_el$23","_co$4","_el$24","_el$25","_co$5","_el$17","_el$18","_el$20","_el$21","_co$3","Show","when","title","_el$11","_tmpl$3","_$memo","value","_el$12","_tmpl$5","_el$13","_el$15","_el$16","_co$2","unit","_el$14","_tmpl$4","slice","StreamingUIRenderer","components","isLoading","isStreaming","error","progress","metadata","startStreaming","useStreamingUI","query","spaceIds","sessionId","options","onComplete","onComponentReceived","animatingComponents","setAnimatingComponents","createSignal","Set","handleComponentRender","prev","setTimeout","next","delete","_el$26","_tmpl$13","_el$87","_el$88","_co$16","_el$89","_el$90","_co$17","_el$51","_el$52","_el$53","_co$1","_el$54","_el$55","_co$10","_el$91","_el$92","_co$18","showProgress","_el$27","_tmpl$9","_el$28","_el$29","_el$36","_el$37","_co$8","_el$38","_el$39","_el$41","_el$42","_co$9","totalCount","_el$30","_tmpl$7","_el$32","_el$33","_co$6","_el$31","_el$34","_el$35","_co$7","receivedCount","_tmpl$8","_$effect","_$p","_$style","_el$43","_tmpl$1","_el$44","_el$45","_el$46","_el$47","_el$49","_el$50","_co$0","recoverable","_el$48","_tmpl$0","$$click","_$runHydrationEvents","For","each","_el$93","_tmpl$14","onRenderError","_p$","_v$","position","colSpan","has","_v$2","colStart","e","_$className","t","undefined","Array","from","length","SkeletonComponent","showMetadata","_el$56","_tmpl$12","_el$57","_el$58","_el$59","_el$60","_el$61","_el$62","_el$63","_el$64","_el$65","_el$66","_el$68","_el$69","_co$11","_el$83","_el$84","_co$14","_el$76","_el$77","_el$78","_el$80","_el$81","_co$13","_el$85","_el$86","_co$15","provider","model","executionTimeMs","costUSD","_el$70","_tmpl$10","_el$71","_el$72","_el$73","_el$74","_el$75","_co$12","toFixed","firstTokenMs","cached","_tmpl$11","class","_tmpl$15","_$delegateEvents"],"mappings":"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"}