@miragon/mcp-toolkit-ui 2.7.0 → 2.8.1
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/README.md +7 -4
- package/dist/app/adapt-data-widget.d.ts +1 -22
- package/dist/app/adapt-data-widget.d.ts.map +1 -1
- package/dist/app/adapt-data-widget.js +1 -35
- package/dist/app/adapt-data-widget.js.map +1 -1
- package/dist/app/builder/BuilderBanners.js +1 -1
- package/dist/app/builder/BuilderBanners.js.map +1 -1
- package/dist/app/builder/CanvasRow.d.ts +4 -2
- package/dist/app/builder/CanvasRow.d.ts.map +1 -1
- package/dist/app/builder/CanvasRow.js +21 -7
- package/dist/app/builder/CanvasRow.js.map +1 -1
- package/dist/app/builder/CatalogueSheet.d.ts.map +1 -1
- package/dist/app/builder/CatalogueSheet.js +11 -4
- package/dist/app/builder/CatalogueSheet.js.map +1 -1
- package/dist/app/builder/CellPropsSheet.d.ts +7 -3
- package/dist/app/builder/CellPropsSheet.d.ts.map +1 -1
- package/dist/app/builder/CellPropsSheet.js +10 -3
- package/dist/app/builder/CellPropsSheet.js.map +1 -1
- package/dist/app/builder/DiscardDialog.d.ts +18 -0
- package/dist/app/builder/DiscardDialog.d.ts.map +1 -0
- package/dist/app/builder/DiscardDialog.js +18 -0
- package/dist/app/builder/DiscardDialog.js.map +1 -0
- package/dist/app/builder/LayoutSurface.d.ts +33 -9
- package/dist/app/builder/LayoutSurface.d.ts.map +1 -1
- package/dist/app/builder/LayoutSurface.js +74 -23
- package/dist/app/builder/LayoutSurface.js.map +1 -1
- package/dist/app/builder/PipelineStrip.d.ts +2 -1
- package/dist/app/builder/PipelineStrip.d.ts.map +1 -1
- package/dist/app/builder/PipelineStrip.js +26 -13
- package/dist/app/builder/PipelineStrip.js.map +1 -1
- package/dist/app/builder/SaveDialog.d.ts +9 -1
- package/dist/app/builder/SaveDialog.d.ts.map +1 -1
- package/dist/app/builder/SaveDialog.js +8 -2
- package/dist/app/builder/SaveDialog.js.map +1 -1
- package/dist/app/builder/Toolbar.d.ts +12 -4
- package/dist/app/builder/Toolbar.d.ts.map +1 -1
- package/dist/app/builder/Toolbar.js +18 -7
- package/dist/app/builder/Toolbar.js.map +1 -1
- package/dist/app/builder/Workspace.d.ts +23 -3
- package/dist/app/builder/Workspace.d.ts.map +1 -1
- package/dist/app/builder/Workspace.js +58 -8
- package/dist/app/builder/Workspace.js.map +1 -1
- package/dist/app/builder/builder-model.d.ts +143 -1
- package/dist/app/builder/builder-model.d.ts.map +1 -1
- package/dist/app/builder/builder-model.js +191 -1
- package/dist/app/builder/builder-model.js.map +1 -1
- package/dist/app/builder/reveal.d.ts +10 -0
- package/dist/app/builder/reveal.d.ts.map +1 -0
- package/dist/app/builder/reveal.js +10 -0
- package/dist/app/builder/reveal.js.map +1 -0
- package/dist/app/builder/use-builder-catalogue.d.ts +4 -1
- package/dist/app/builder/use-builder-catalogue.d.ts.map +1 -1
- package/dist/app/builder/use-builder-catalogue.js +44 -17
- package/dist/app/builder/use-builder-catalogue.js.map +1 -1
- package/dist/app/builder/use-builder-session.d.ts +30 -0
- package/dist/app/builder/use-builder-session.d.ts.map +1 -0
- package/dist/app/builder/use-builder-session.js +58 -0
- package/dist/app/builder/use-builder-session.js.map +1 -0
- package/dist/app/builder/use-display-resolver.d.ts +17 -0
- package/dist/app/builder/use-display-resolver.d.ts.map +1 -0
- package/dist/app/builder/use-display-resolver.js +16 -0
- package/dist/app/builder/use-display-resolver.js.map +1 -0
- package/dist/app/index.d.ts +8 -3
- package/dist/app/index.d.ts.map +1 -1
- package/dist/app/index.js +8 -2
- package/dist/app/index.js.map +1 -1
- package/dist/app/layout-builder.d.ts +13 -25
- package/dist/app/layout-builder.d.ts.map +1 -1
- package/dist/app/layout-builder.js +75 -81
- package/dist/app/layout-builder.js.map +1 -1
- package/dist/app/mcp-app-view-chrome.d.ts +12 -3
- package/dist/app/mcp-app-view-chrome.d.ts.map +1 -1
- package/dist/app/mcp-app-view-chrome.js +21 -5
- package/dist/app/mcp-app-view-chrome.js.map +1 -1
- package/dist/app/mcp-app-view-states.d.ts +11 -3
- package/dist/app/mcp-app-view-states.d.ts.map +1 -1
- package/dist/app/mcp-app-view-states.js +29 -8
- package/dist/app/mcp-app-view-states.js.map +1 -1
- package/dist/app/mcp-app-view.d.ts +33 -1
- package/dist/app/mcp-app-view.d.ts.map +1 -1
- package/dist/app/mcp-app-view.js +181 -127
- package/dist/app/mcp-app-view.js.map +1 -1
- package/dist/app/mcp-toolkit-app.d.ts +6 -1
- package/dist/app/mcp-toolkit-app.d.ts.map +1 -1
- package/dist/app/mcp-toolkit-app.js +8 -1
- package/dist/app/mcp-toolkit-app.js.map +1 -1
- package/dist/app/mcp-use-host-bridge.d.ts +15 -6
- package/dist/app/mcp-use-host-bridge.d.ts.map +1 -1
- package/dist/app/mcp-use-host-bridge.js +51 -22
- package/dist/app/mcp-use-host-bridge.js.map +1 -1
- package/dist/app/model-context.d.ts +71 -0
- package/dist/app/model-context.d.ts.map +1 -0
- package/dist/app/model-context.js +101 -0
- package/dist/app/model-context.js.map +1 -0
- package/dist/app/use-build-mode-focus.d.ts +33 -0
- package/dist/app/use-build-mode-focus.d.ts.map +1 -0
- package/dist/app/use-build-mode-focus.js +59 -0
- package/dist/app/use-build-mode-focus.js.map +1 -0
- package/dist/app/use-view-actions.d.ts +31 -0
- package/dist/app/use-view-actions.d.ts.map +1 -0
- package/dist/app/use-view-actions.js +81 -0
- package/dist/app/use-view-actions.js.map +1 -0
- package/dist/app/use-view-lifecycle.d.ts +4 -0
- package/dist/app/use-view-lifecycle.d.ts.map +1 -1
- package/dist/app/use-view-lifecycle.js +2 -0
- package/dist/app/use-view-lifecycle.js.map +1 -1
- package/dist/app/view-lifecycle.d.ts +80 -4
- package/dist/app/view-lifecycle.d.ts.map +1 -1
- package/dist/app/view-lifecycle.js +90 -3
- package/dist/app/view-lifecycle.js.map +1 -1
- package/dist/app/widget-fixture.d.ts +10 -3
- package/dist/app/widget-fixture.d.ts.map +1 -1
- package/dist/app/widget-fixture.js +21 -8
- package/dist/app/widget-fixture.js.map +1 -1
- package/dist/app/widget-props-sheet.d.ts +3 -1
- package/dist/app/widget-props-sheet.d.ts.map +1 -1
- package/dist/app/widget-props-sheet.js +22 -10
- package/dist/app/widget-props-sheet.js.map +1 -1
- package/dist/app/widget-renderer.js +1 -1
- package/dist/app/widget-renderer.js.map +1 -1
- package/dist/components/DrillButton.d.ts +14 -6
- package/dist/components/DrillButton.d.ts.map +1 -1
- package/dist/components/DrillButton.js +14 -7
- package/dist/components/DrillButton.js.map +1 -1
- package/dist/components/EmptyState.d.ts.map +1 -1
- package/dist/components/EmptyState.js +4 -2
- package/dist/components/EmptyState.js.map +1 -1
- package/dist/components/ErrorState.d.ts +5 -2
- package/dist/components/ErrorState.d.ts.map +1 -1
- package/dist/components/ErrorState.js +25 -8
- package/dist/components/ErrorState.js.map +1 -1
- package/dist/components/FilterBar.d.ts +15 -4
- package/dist/components/FilterBar.d.ts.map +1 -1
- package/dist/components/FilterBar.js +11 -6
- package/dist/components/FilterBar.js.map +1 -1
- package/dist/components/KpiGrid.d.ts +66 -21
- package/dist/components/KpiGrid.d.ts.map +1 -1
- package/dist/components/KpiGrid.js +101 -34
- package/dist/components/KpiGrid.js.map +1 -1
- package/dist/components/ListFooter.d.ts +31 -4
- package/dist/components/ListFooter.d.ts.map +1 -1
- package/dist/components/ListFooter.js +30 -11
- package/dist/components/ListFooter.js.map +1 -1
- package/dist/components/PagedListFooter.d.ts +57 -0
- package/dist/components/PagedListFooter.d.ts.map +1 -0
- package/dist/components/PagedListFooter.js +27 -0
- package/dist/components/PagedListFooter.js.map +1 -0
- package/dist/components/Pills.d.ts +27 -7
- package/dist/components/Pills.d.ts.map +1 -1
- package/dist/components/Pills.js +21 -6
- package/dist/components/Pills.js.map +1 -1
- package/dist/components/SectionHeading.d.ts +3 -1
- package/dist/components/SectionHeading.d.ts.map +1 -1
- package/dist/components/SectionHeading.js +6 -2
- package/dist/components/SectionHeading.js.map +1 -1
- package/dist/components/Toast.d.ts +9 -3
- package/dist/components/Toast.d.ts.map +1 -1
- package/dist/components/Toast.js +31 -16
- package/dist/components/Toast.js.map +1 -1
- package/dist/components/WidgetHeader.d.ts +34 -10
- package/dist/components/WidgetHeader.d.ts.map +1 -1
- package/dist/components/WidgetHeader.js +11 -6
- package/dist/components/WidgetHeader.js.map +1 -1
- package/dist/hooks/index.d.ts +4 -4
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/tool-result-recovery-model.d.ts +155 -0
- package/dist/hooks/tool-result-recovery-model.d.ts.map +1 -0
- package/dist/hooks/tool-result-recovery-model.js +273 -0
- package/dist/hooks/tool-result-recovery-model.js.map +1 -0
- package/dist/hooks/use-tool-query.d.ts +56 -14
- package/dist/hooks/use-tool-query.d.ts.map +1 -1
- package/dist/hooks/use-tool-query.js +102 -25
- package/dist/hooks/use-tool-query.js.map +1 -1
- package/dist/hooks/use-tool-result-recovery.d.ts +47 -52
- package/dist/hooks/use-tool-result-recovery.d.ts.map +1 -1
- package/dist/hooks/use-tool-result-recovery.js +58 -120
- package/dist/hooks/use-tool-result-recovery.js.map +1 -1
- package/dist/hooks/use-view-data.d.ts +52 -10
- package/dist/hooks/use-view-data.d.ts.map +1 -1
- package/dist/hooks/use-view-data.js +81 -16
- package/dist/hooks/use-view-data.js.map +1 -1
- package/dist/hooks/use-view-tool-query.d.ts +12 -7
- package/dist/hooks/use-view-tool-query.d.ts.map +1 -1
- package/dist/hooks/use-view-tool-query.js +15 -14
- package/dist/hooks/use-view-tool-query.js.map +1 -1
- package/dist/index.d.ts +17 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/focus-return.d.ts +61 -0
- package/dist/lib/focus-return.d.ts.map +1 -0
- package/dist/lib/focus-return.js +46 -0
- package/dist/lib/focus-return.js.map +1 -0
- package/dist/lib/parse-tool-result.d.ts +23 -1
- package/dist/lib/parse-tool-result.d.ts.map +1 -1
- package/dist/lib/parse-tool-result.js +38 -2
- package/dist/lib/parse-tool-result.js.map +1 -1
- package/dist/lib/toast-model.d.ts +41 -1
- package/dist/lib/toast-model.d.ts.map +1 -1
- package/dist/lib/toast-model.js +67 -1
- package/dist/lib/toast-model.js.map +1 -1
- package/dist/lib/tone-utils.d.ts +58 -6
- package/dist/lib/tone-utils.d.ts.map +1 -1
- package/dist/lib/tone-utils.js +66 -4
- package/dist/lib/tone-utils.js.map +1 -1
- package/dist/lib/tool-query.d.ts +107 -0
- package/dist/lib/tool-query.d.ts.map +1 -0
- package/dist/lib/tool-query.js +182 -0
- package/dist/lib/tool-query.js.map +1 -0
- package/dist/lib/tool-result-observer.d.ts +108 -0
- package/dist/lib/tool-result-observer.d.ts.map +1 -0
- package/dist/lib/tool-result-observer.js +158 -0
- package/dist/lib/tool-result-observer.js.map +1 -0
- package/dist/lib/typography.d.ts +37 -0
- package/dist/lib/typography.d.ts.map +1 -0
- package/dist/lib/typography.js +41 -0
- package/dist/lib/typography.js.map +1 -0
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +11 -1
- package/dist/lib/utils.js.map +1 -1
- package/dist/locale/index.d.ts +1 -1
- package/dist/locale/index.d.ts.map +1 -1
- package/dist/locale/message-types.d.ts +117 -4
- package/dist/locale/message-types.d.ts.map +1 -1
- package/dist/locale/messages-de.d.ts.map +1 -1
- package/dist/locale/messages-de.js +44 -10
- package/dist/locale/messages-de.js.map +1 -1
- package/dist/locale/messages-en.d.ts.map +1 -1
- package/dist/locale/messages-en.js +44 -10
- package/dist/locale/messages-en.js.map +1 -1
- package/dist/locale/toolkit-messages.d.ts +19 -1
- package/dist/locale/toolkit-messages.d.ts.map +1 -1
- package/dist/locale/toolkit-messages.js +54 -1
- package/dist/locale/toolkit-messages.js.map +1 -1
- package/dist/primitives/alert.d.ts +1 -1
- package/dist/primitives/alert.d.ts.map +1 -1
- package/dist/primitives/alert.js +2 -0
- package/dist/primitives/alert.js.map +1 -1
- package/dist/primitives/badge.d.ts +1 -1
- package/dist/primitives/badge.d.ts.map +1 -1
- package/dist/primitives/badge.js +9 -4
- package/dist/primitives/badge.js.map +1 -1
- package/dist/primitives/button.d.ts +1 -1
- package/dist/primitives/button.js +1 -1
- package/dist/primitives/button.js.map +1 -1
- package/dist/primitives/dialog.d.ts +1 -1
- package/dist/primitives/dialog.d.ts.map +1 -1
- package/dist/primitives/dialog.js +10 -3
- package/dist/primitives/dialog.js.map +1 -1
- package/dist/primitives/select.js +1 -1
- package/dist/primitives/select.js.map +1 -1
- package/dist/primitives/sheet.d.ts +1 -1
- package/dist/primitives/sheet.d.ts.map +1 -1
- package/dist/primitives/sheet.js +6 -2
- package/dist/primitives/sheet.js.map +1 -1
- package/dist/providers/query-provider.d.ts +32 -1
- package/dist/providers/query-provider.d.ts.map +1 -1
- package/dist/providers/query-provider.js +53 -4
- package/dist/providers/query-provider.js.map +1 -1
- package/dist/render-cases-primitives.js +1 -1
- package/dist/render-cases-primitives.js.map +1 -1
- package/dist/render-cases.d.ts.map +1 -1
- package/dist/render-cases.js +30 -6
- package/dist/render-cases.js.map +1 -1
- package/dist/render-effects.d.ts +42 -0
- package/dist/render-effects.d.ts.map +1 -0
- package/dist/render-effects.js +81 -0
- package/dist/render-effects.js.map +1 -0
- package/dist/theme/create-theme.d.ts +19 -1
- package/dist/theme/create-theme.d.ts.map +1 -1
- package/dist/theme/create-theme.js +15 -0
- package/dist/theme/create-theme.js.map +1 -1
- package/package.json +5 -4
- package/src/app/adapt-data-widget.tsx +2 -42
- package/src/app/builder/BuilderBanners.tsx +1 -1
- package/src/app/builder/CanvasRow.tsx +63 -17
- package/src/app/builder/CatalogueSheet.tsx +50 -29
- package/src/app/builder/CellPropsSheet.tsx +17 -2
- package/src/app/builder/DiscardDialog.tsx +59 -0
- package/src/app/builder/LayoutSurface.tsx +206 -66
- package/src/app/builder/PipelineStrip.tsx +253 -153
- package/src/app/builder/SaveDialog.tsx +14 -2
- package/src/app/builder/Toolbar.tsx +144 -59
- package/src/app/builder/Workspace.tsx +226 -58
- package/src/app/builder/builder-model.ts +341 -2
- package/src/app/builder/builder-model.ux.test.ts +456 -0
- package/src/app/builder/builder-ux.test.tsx +844 -0
- package/src/app/builder/reveal.ts +10 -0
- package/src/app/builder/use-builder-catalogue.ts +56 -19
- package/src/app/builder/use-builder-session.ts +68 -0
- package/src/app/builder/use-display-resolver.ts +24 -0
- package/src/app/index.ts +12 -2
- package/src/app/layout-builder.tsx +178 -191
- package/src/app/mcp-app-view-chrome.test.tsx +141 -1
- package/src/app/mcp-app-view-chrome.tsx +56 -6
- package/src/app/mcp-app-view-states.tsx +51 -11
- package/src/app/mcp-app-view.effects.test.tsx +292 -0
- package/src/app/mcp-app-view.test.tsx +222 -2
- package/src/app/mcp-app-view.tsx +267 -117
- package/src/app/mcp-toolkit-app.test.tsx +40 -0
- package/src/app/mcp-toolkit-app.tsx +8 -1
- package/src/app/mcp-use-host-bridge.test.tsx +180 -0
- package/src/app/mcp-use-host-bridge.tsx +67 -24
- package/src/app/model-context.test.tsx +116 -0
- package/src/app/model-context.tsx +125 -0
- package/src/app/use-build-mode-focus.ts +62 -0
- package/src/app/use-view-actions.ts +89 -0
- package/src/app/use-view-lifecycle.ts +6 -0
- package/src/app/view-lifecycle.test.ts +216 -0
- package/src/app/view-lifecycle.ts +165 -5
- package/src/app/widget-fixture.effects.test.tsx +51 -0
- package/src/app/widget-fixture.render.test.tsx +81 -0
- package/src/app/widget-fixture.tsx +34 -11
- package/src/app/widget-props-sheet.tsx +57 -16
- package/src/app/widget-renderer.tsx +1 -1
- package/src/components/DrillButton.test.tsx +48 -0
- package/src/components/DrillButton.tsx +26 -11
- package/src/components/EmptyState.tsx +6 -4
- package/src/components/ErrorState.tsx +31 -9
- package/src/components/FilterBar.test.tsx +82 -0
- package/src/components/FilterBar.tsx +52 -26
- package/src/components/KpiGrid.test.tsx +279 -0
- package/src/components/KpiGrid.tsx +297 -90
- package/src/components/ListFooter.test.tsx +116 -0
- package/src/components/ListFooter.tsx +102 -15
- package/src/components/PagedListFooter.test.tsx +140 -0
- package/src/components/PagedListFooter.tsx +107 -0
- package/src/components/Pills.test.tsx +77 -0
- package/src/components/Pills.tsx +63 -10
- package/src/components/SectionHeading.tsx +9 -3
- package/src/components/Toast.tsx +37 -19
- package/src/components/WidgetHeader.test.tsx +78 -0
- package/src/components/WidgetHeader.tsx +63 -16
- package/src/components/feedback-states.test.tsx +98 -9
- package/src/components/tone-figures.test.tsx +8 -4
- package/src/hooks/index.ts +6 -3
- package/src/hooks/tool-result-recovery-model.test.ts +744 -0
- package/src/hooks/tool-result-recovery-model.ts +418 -0
- package/src/hooks/use-tool-query.effects.test.tsx +205 -0
- package/src/hooks/use-tool-query.ts +156 -33
- package/src/hooks/use-tool-result-recovery.effects.test.tsx +141 -0
- package/src/hooks/use-tool-result-recovery.test.ts +3 -4
- package/src/hooks/use-tool-result-recovery.ts +84 -142
- package/src/hooks/use-view-data.test.tsx +118 -9
- package/src/hooks/use-view-data.ts +128 -18
- package/src/hooks/use-view-tool-query.ts +25 -19
- package/src/i18n-coverage.test.tsx +104 -2
- package/src/index.ts +48 -11
- package/src/lib/focus-return.test.ts +288 -0
- package/src/lib/focus-return.ts +96 -0
- package/src/lib/parse-tool-result.test.ts +46 -1
- package/src/lib/parse-tool-result.ts +40 -2
- package/src/lib/toast-model.test.ts +166 -1
- package/src/lib/toast-model.ts +104 -2
- package/src/lib/tone-utils.test.ts +86 -10
- package/src/lib/tone-utils.ts +89 -8
- package/src/lib/tool-query.test.ts +569 -0
- package/src/lib/tool-query.ts +253 -0
- package/src/lib/tool-result-observer.test.ts +296 -0
- package/src/lib/tool-result-observer.ts +211 -0
- package/src/lib/typography.test.ts +45 -0
- package/src/lib/typography.ts +47 -0
- package/src/lib/utils.ts +12 -1
- package/src/locale/index.ts +1 -0
- package/src/locale/message-types.ts +118 -2
- package/src/locale/messages-de.ts +49 -10
- package/src/locale/messages-en.ts +49 -10
- package/src/locale/toolkit-messages.test.ts +133 -0
- package/src/locale/toolkit-messages.ts +63 -2
- package/src/primitives/alert.tsx +3 -0
- package/src/primitives/badge.tsx +9 -4
- package/src/primitives/button.tsx +1 -1
- package/src/primitives/dialog.tsx +10 -1
- package/src/primitives/select.tsx +1 -1
- package/src/primitives/sheet.tsx +7 -0
- package/src/providers/query-provider.test.tsx +154 -0
- package/src/providers/query-provider.tsx +66 -5
- package/src/render-cases-primitives.tsx +1 -1
- package/src/render-cases.tsx +38 -6
- package/src/render-effects.tsx +96 -0
- package/src/theme/cd-tokens.test.ts +3 -1
- package/src/theme/create-theme.test.ts +10 -0
- package/src/theme/create-theme.ts +28 -0
- package/src/theme/theme-css.test.ts +51 -0
- package/src/theme.css +31 -1
- package/ui-catalog.json +448 -41
|
@@ -1,31 +1,32 @@
|
|
|
1
|
+
import { QueryClient } from "@tanstack/react-query"
|
|
1
2
|
import { renderToStaticMarkup } from "react-dom/server"
|
|
2
3
|
import { describe, expect, it, vi } from "vitest"
|
|
4
|
+
import { toolQueryKey } from "../lib/tool-query.js"
|
|
3
5
|
import { AppQueryProvider } from "../providers/query-provider.js"
|
|
4
|
-
import { useViewData, type ViewDataResult } from "./use-view-data.js"
|
|
6
|
+
import { useViewData, type UseViewDataOptions, type ViewDataResult } from "./use-view-data.js"
|
|
5
7
|
|
|
6
8
|
type Demo = { n: number }
|
|
7
9
|
type CallTool = (name: string, args: object) => Promise<unknown>
|
|
8
10
|
|
|
11
|
+
const KEY = ["use-view-data.test"] as const
|
|
12
|
+
const ARGS = { id: 1 }
|
|
13
|
+
|
|
9
14
|
/** Renders a probe once (SSR, the house path) and hands back the hook's result. */
|
|
10
15
|
function probe(
|
|
11
16
|
initialData: Demo | null,
|
|
12
17
|
ready: boolean,
|
|
13
18
|
callTool: CallTool,
|
|
14
19
|
key: string,
|
|
20
|
+
options?: UseViewDataOptions<Demo> & { client?: QueryClient; toolNameInQueryKey?: boolean },
|
|
15
21
|
): ViewDataResult<Demo> {
|
|
16
22
|
let result: ViewDataResult<Demo> | undefined
|
|
23
|
+
const { client, toolNameInQueryKey, ...hookOptions } = options ?? {}
|
|
17
24
|
function Probe() {
|
|
18
|
-
result = useViewData<Demo>(
|
|
19
|
-
initialData,
|
|
20
|
-
["use-view-data.test", key],
|
|
21
|
-
"demo_data",
|
|
22
|
-
{ id: 1 },
|
|
23
|
-
ready,
|
|
24
|
-
)
|
|
25
|
+
result = useViewData<Demo>(initialData, [...KEY, key], "demo_data", ARGS, ready, hookOptions)
|
|
25
26
|
return null
|
|
26
27
|
}
|
|
27
28
|
renderToStaticMarkup(
|
|
28
|
-
<AppQueryProvider callTool={callTool}>
|
|
29
|
+
<AppQueryProvider callTool={callTool} client={client} toolNameInQueryKey={toolNameInQueryKey}>
|
|
29
30
|
<Probe />
|
|
30
31
|
</AppQueryProvider>,
|
|
31
32
|
)
|
|
@@ -48,6 +49,16 @@ describe("useViewData", () => {
|
|
|
48
49
|
expect(result).toMatchObject({ data: null, loading: false, error: null })
|
|
49
50
|
})
|
|
50
51
|
|
|
52
|
+
it("exposes the query's progress: failureCount, failureReason, isFetching, isPlaceholderData", () => {
|
|
53
|
+
const result = probe(null, false, vi.fn<CallTool>(), "progress")
|
|
54
|
+
expect(result).toMatchObject({
|
|
55
|
+
failureCount: 0,
|
|
56
|
+
failureReason: null,
|
|
57
|
+
isFetching: false,
|
|
58
|
+
isPlaceholderData: false,
|
|
59
|
+
})
|
|
60
|
+
})
|
|
61
|
+
|
|
51
62
|
it("refetch calls the tool again: the retry an error state offers", async () => {
|
|
52
63
|
const callTool = vi.fn<CallTool>(() => Promise.resolve({ structuredContent: { n: 2 } }))
|
|
53
64
|
const result = probe(null, false, callTool, "refetch")
|
|
@@ -57,4 +68,102 @@ describe("useViewData", () => {
|
|
|
57
68
|
expect(callTool).toHaveBeenCalledWith("demo_data", { id: 1 })
|
|
58
69
|
})
|
|
59
70
|
})
|
|
71
|
+
|
|
72
|
+
it("enabled: false gates the feed next to ready; a ready feed without data is loading", () => {
|
|
73
|
+
const client = new QueryClient()
|
|
74
|
+
expect(probe(null, true, vi.fn<CallTool>(), "gated", { client, enabled: false }).loading).toBe(
|
|
75
|
+
false,
|
|
76
|
+
)
|
|
77
|
+
expect(probe(null, true, vi.fn<CallTool>(), "open", { client }).loading).toBe(true)
|
|
78
|
+
})
|
|
79
|
+
|
|
80
|
+
it("a function gate that says no idles like enabled: false, never an endless skeleton", () => {
|
|
81
|
+
const client = new QueryClient()
|
|
82
|
+
const closed = probe(null, true, vi.fn<CallTool>(), "fn-closed", {
|
|
83
|
+
client,
|
|
84
|
+
enabled: () => false,
|
|
85
|
+
})
|
|
86
|
+
expect(closed).toMatchObject({ data: null, loading: false, error: null })
|
|
87
|
+
const open = probe(null, true, vi.fn<CallTool>(), "fn-open", { client, enabled: () => true })
|
|
88
|
+
expect(open.loading).toBe(true)
|
|
89
|
+
// Not ready keeps it off whatever the gate says.
|
|
90
|
+
expect(
|
|
91
|
+
probe(null, false, vi.fn<CallTool>(), "fn-not-ready", { client, enabled: () => true })
|
|
92
|
+
.loading,
|
|
93
|
+
).toBe(false)
|
|
94
|
+
})
|
|
95
|
+
|
|
96
|
+
it("passes TanStack's options through: initialData-free placeholderData shows meanwhile", () => {
|
|
97
|
+
const client = new QueryClient()
|
|
98
|
+
const result = probe(null, true, vi.fn<CallTool>(), "placeholder", {
|
|
99
|
+
client,
|
|
100
|
+
placeholderData: { n: 0 },
|
|
101
|
+
})
|
|
102
|
+
expect(result).toMatchObject({ data: { n: 0 }, isPlaceholderData: true, loading: false })
|
|
103
|
+
})
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
describe('useViewData initialDataMode: "seed" (the live standalone view)', () => {
|
|
107
|
+
const cacheKey = (key: string) => toolQueryKey([...KEY, key], "demo_data", ARGS)
|
|
108
|
+
|
|
109
|
+
it("seeds the feed's cache entry with the host's payload and returns it", () => {
|
|
110
|
+
const client = new QueryClient()
|
|
111
|
+
const result = probe({ n: 1 }, true, vi.fn<CallTool>(), "seeded", {
|
|
112
|
+
client,
|
|
113
|
+
initialDataMode: "seed",
|
|
114
|
+
initialDataUpdatedAt: 1234,
|
|
115
|
+
})
|
|
116
|
+
expect(result).toMatchObject({ data: { n: 1 }, loading: false })
|
|
117
|
+
expect(client.getQueryData(cacheKey("seeded"))).toEqual({ n: 1 })
|
|
118
|
+
expect(client.getQueryState(cacheKey("seeded"))?.dataUpdatedAt).toBe(1234)
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
it("with toolNameInQueryKey the seed lands under the key carrying the tool name", () => {
|
|
122
|
+
const client = new QueryClient()
|
|
123
|
+
const result = probe({ n: 1 }, true, vi.fn<CallTool>(), "tool-key", {
|
|
124
|
+
client,
|
|
125
|
+
initialDataMode: "seed",
|
|
126
|
+
toolNameInQueryKey: true,
|
|
127
|
+
})
|
|
128
|
+
expect(result.data).toEqual({ n: 1 })
|
|
129
|
+
expect(client.getQueryData([...KEY, "tool-key", "demo_data", ARGS])).toEqual({ n: 1 })
|
|
130
|
+
expect(client.getQueryData(cacheKey("tool-key")), "never the 2.x key").toBeUndefined()
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
it("static mode never writes the cache", () => {
|
|
134
|
+
const client = new QueryClient()
|
|
135
|
+
probe({ n: 1 }, true, vi.fn<CallTool>(), "static", { client })
|
|
136
|
+
expect(client.getQueryData(cacheKey("static"))).toBeUndefined()
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
it("the cached answer wins over the seed it came from once the feed answered anew", () => {
|
|
140
|
+
const client = new QueryClient()
|
|
141
|
+
probe({ n: 1 }, true, vi.fn<CallTool>(), "refetched", { client, initialDataMode: "seed" })
|
|
142
|
+
client.setQueryData(cacheKey("refetched"), { n: 2 })
|
|
143
|
+
const remounted = probe({ n: 1 }, true, vi.fn<CallTool>(), "refetched", {
|
|
144
|
+
client,
|
|
145
|
+
initialDataMode: "seed",
|
|
146
|
+
initialDataUpdatedAt: () => 99,
|
|
147
|
+
})
|
|
148
|
+
expect(remounted.data, "an old payload never rolls the answer back").toEqual({ n: 2 })
|
|
149
|
+
const delivered = probe({ n: 3 }, true, vi.fn<CallTool>(), "refetched", {
|
|
150
|
+
client,
|
|
151
|
+
initialDataMode: "seed",
|
|
152
|
+
})
|
|
153
|
+
expect(delivered.data, "a new delivery wins").toEqual({ n: 3 })
|
|
154
|
+
})
|
|
155
|
+
|
|
156
|
+
it("refetch over a seeded entry reads the feed again", async () => {
|
|
157
|
+
const client = new QueryClient()
|
|
158
|
+
const callTool = vi.fn<CallTool>(() => Promise.resolve({ structuredContent: { n: 2 } }))
|
|
159
|
+
const result = probe({ n: 1 }, true, callTool, "seed-refetch", {
|
|
160
|
+
client,
|
|
161
|
+
initialDataMode: "seed",
|
|
162
|
+
})
|
|
163
|
+
result.refetch()
|
|
164
|
+
await vi.waitFor(() => {
|
|
165
|
+
expect(client.getQueryData(cacheKey("seed-refetch"))).toEqual({ n: 2 })
|
|
166
|
+
})
|
|
167
|
+
expect(callTool).toHaveBeenCalledWith("demo_data", ARGS)
|
|
168
|
+
})
|
|
60
169
|
})
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import { useCallback } from "react"
|
|
2
|
-
import {
|
|
1
|
+
import { useCallback, useState } from "react"
|
|
2
|
+
import { hashKey, useQueryClient } from "@tanstack/react-query"
|
|
3
|
+
import { seedToolQuery, type UseToolQueryOptions } from "../lib/tool-query.js"
|
|
4
|
+
import { useToolQuery, useToolQueryKey } from "./use-tool-query.js"
|
|
3
5
|
|
|
4
6
|
export interface ViewDataResult<T> {
|
|
5
7
|
data: T | null
|
|
@@ -7,23 +9,66 @@ export interface ViewDataResult<T> {
|
|
|
7
9
|
loading: boolean
|
|
8
10
|
error: Error | null
|
|
9
11
|
/**
|
|
10
|
-
* Fetch `tool` again: the retry of an error state
|
|
11
|
-
* (`<ErrorState onRetry={refetch} … />`)
|
|
12
|
-
*
|
|
12
|
+
* Fetch `tool` again now: the retry of an error state
|
|
13
|
+
* (`<ErrorState onRetry={refetch} … />`) or a manual refresh — a new read
|
|
14
|
+
* even while a failed fetch still waits on its retry backoff. In `"static"`
|
|
15
|
+
* mode host-pushed data, when present, stays what `data` returns.
|
|
13
16
|
*/
|
|
14
17
|
refetch: () => void
|
|
18
|
+
/** Failed attempts of the current fetch (0 once it succeeds). */
|
|
19
|
+
failureCount: number
|
|
20
|
+
/**
|
|
21
|
+
* The current fetch's last failed attempt — set from the first failure on,
|
|
22
|
+
* while the query still retries (`error` waits for the last retry).
|
|
23
|
+
*/
|
|
24
|
+
failureReason: Error | null
|
|
25
|
+
/** A fetch is in flight (the first one or a refetch). */
|
|
26
|
+
isFetching: boolean
|
|
27
|
+
/**
|
|
28
|
+
* `data` is a placeholder (`placeholderData`, e.g. `keepPreviousData`):
|
|
29
|
+
* the previous args' answer while the current args' fetch runs or failed.
|
|
30
|
+
*/
|
|
31
|
+
isPlaceholderData: boolean
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* How {@link useViewData} treats host-pushed `initialData`.
|
|
36
|
+
*
|
|
37
|
+
* - `"static"` (default): returned verbatim; the feed query stays off while
|
|
38
|
+
* it is present.
|
|
39
|
+
* - `"seed"`: it becomes the feed query's cached answer, and the query stays
|
|
40
|
+
* live (once `ready`): an invalidation after a write, a `refetch` or a
|
|
41
|
+
* retry re-reads the feed. A fresh seed is not refetched on mount (it is
|
|
42
|
+
* younger than `staleTime`); a payload delivered anew (content not seeded
|
|
43
|
+
* for the key before) replaces the cached answer, while a re-rendered or
|
|
44
|
+
* remounted old one never rolls a refetched answer back.
|
|
45
|
+
*/
|
|
46
|
+
export type ViewDataMode = "static" | "seed"
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Options of {@link useViewData}: TanStack's query options for the feed
|
|
50
|
+
* (`retry`, `retryDelay`, `staleTime`, `placeholderData` /
|
|
51
|
+
* `keepPreviousData`, `enabled` as an extra gate next to `ready`, …),
|
|
52
|
+
* plus how host data seeds it.
|
|
53
|
+
*/
|
|
54
|
+
export type UseViewDataOptions<T> = Omit<UseToolQueryOptions<T>, "initialData" | "select"> & {
|
|
55
|
+
initialDataMode?: ViewDataMode
|
|
15
56
|
}
|
|
16
57
|
|
|
17
58
|
/**
|
|
18
59
|
* The seam that lets one widget component serve both modes without a duplicate UI.
|
|
19
60
|
*
|
|
20
61
|
* Standalone (a `*_show_*` widget) the agent's tool result is handed in via
|
|
21
|
-
* `initialData` (from the view's stepData, e.g. through `adaptDataWidget`)
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
62
|
+
* `initialData` (from the view's stepData, e.g. through `adaptDataWidget`).
|
|
63
|
+
* Embedded in a self-fetching cockpit only scope params are passed, so the
|
|
64
|
+
* component fetches `tool` with `args` under `key`, gated on `ready` (i.e.
|
|
65
|
+
* the required id/key is present). Sibling widgets sharing `key` and `args`
|
|
66
|
+
* dedupe to a single call, so a composed view of N widgets over one data
|
|
67
|
+
* feed fetches once.
|
|
68
|
+
*
|
|
69
|
+
* By default host data is returned verbatim and switches the query off;
|
|
70
|
+
* `initialDataMode: "seed"` keeps the query live over it instead (see
|
|
71
|
+
* {@link ViewDataMode}). `options` passes TanStack's query options through.
|
|
27
72
|
*/
|
|
28
73
|
export function useViewData<T>(
|
|
29
74
|
initialData: T | null | undefined,
|
|
@@ -31,12 +76,77 @@ export function useViewData<T>(
|
|
|
31
76
|
tool: string,
|
|
32
77
|
args: Record<string, unknown>,
|
|
33
78
|
ready: boolean,
|
|
79
|
+
options?: UseViewDataOptions<T>,
|
|
34
80
|
): ViewDataResult<T> {
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
81
|
+
const { initialDataMode = "static", enabled, ...queryOptions } = options ?? {}
|
|
82
|
+
const seeding = initialDataMode === "seed"
|
|
83
|
+
const cacheKey = useStableKey(useToolQueryKey(key, tool, args))
|
|
84
|
+
useSeed(seeding ? initialData : null, cacheKey, queryOptions.initialDataUpdatedAt)
|
|
85
|
+
|
|
86
|
+
const active = ready && enabled !== false
|
|
87
|
+
const fetches = active && (seeding || !initialData)
|
|
88
|
+
const query = useToolQuery<T>([...key], tool, args, {
|
|
89
|
+
...queryOptions,
|
|
90
|
+
enabled: typeof enabled === "function" ? (q) => fetches && enabled(q) : fetches,
|
|
91
|
+
})
|
|
92
|
+
const data = seeding ? (query.data ?? initialData) : (initialData ?? query.data)
|
|
93
|
+
const refetch = useFreshRefetch(cacheKey, query.refetch)
|
|
94
|
+
return {
|
|
95
|
+
data: data ?? null,
|
|
96
|
+
// The query's own verdict: a function `enabled` that returns false idles
|
|
97
|
+
// like `enabled: false`, never an endless skeleton.
|
|
98
|
+
loading: !data && query.isEnabled && !query.isError,
|
|
99
|
+
error: query.error,
|
|
100
|
+
refetch,
|
|
101
|
+
failureCount: query.failureCount,
|
|
102
|
+
failureReason: query.failureReason,
|
|
103
|
+
isFetching: query.isFetching,
|
|
104
|
+
isPlaceholderData: query.isPlaceholderData,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/** `key`, kept by content: callers build `key`/`args` anew every render. */
|
|
109
|
+
function useStableKey(key: unknown[]): unknown[] {
|
|
110
|
+
const id = hashKey(key)
|
|
111
|
+
const [stable, setStable] = useState({ id, key })
|
|
112
|
+
if (stable.id !== id) setStable({ id, key })
|
|
113
|
+
return stable.id === id ? stable.key : key
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* `"seed"` mode: write the host's payload into the feed's cache entry in the
|
|
118
|
+
* render phase, before the query's observer reads the cache — what TanStack's
|
|
119
|
+
* own `initialData` does (see {@link seedToolQuery} for when it wins over a
|
|
120
|
+
* cached answer). The last processed seed skips the content check while the
|
|
121
|
+
* same object comes in render after render.
|
|
122
|
+
*/
|
|
123
|
+
function useSeed(
|
|
124
|
+
seed: unknown,
|
|
125
|
+
cacheKey: unknown[],
|
|
126
|
+
updatedAt: number | (() => number | undefined) | undefined,
|
|
127
|
+
): void {
|
|
128
|
+
const client = useQueryClient()
|
|
129
|
+
const keyId = hashKey(cacheKey)
|
|
130
|
+
const [seen, setSeen] = useState<{ seed: unknown; keyId: string } | null>(null)
|
|
131
|
+
if (seed == null || (seen?.seed === seed && seen.keyId === keyId)) return
|
|
132
|
+
const at = typeof updatedAt === "function" ? updatedAt() : updatedAt
|
|
133
|
+
const written = seedToolQuery(client, cacheKey, seed, at)
|
|
134
|
+
// Only a real change re-renders: an equal new object per render must not loop.
|
|
135
|
+
if (written || seen?.keyId !== keyId) setSeen({ seed, keyId })
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* A refetch that reads anew at once. TanStack restarts an in-flight fetch only
|
|
140
|
+
* over data (`cancelRefetch`); a key without data joins the running retry
|
|
141
|
+
* chain and waits out its backoff. So cancel that chain first, then read.
|
|
142
|
+
*/
|
|
143
|
+
function useFreshRefetch(cacheKey: unknown[], refetchQuery: () => Promise<unknown>): () => void {
|
|
144
|
+
const client = useQueryClient()
|
|
145
|
+
return useCallback(() => {
|
|
146
|
+
if (client.getQueryData(cacheKey) !== undefined) {
|
|
147
|
+
void refetchQuery()
|
|
148
|
+
return
|
|
149
|
+
}
|
|
150
|
+
void client.cancelQueries({ queryKey: cacheKey, exact: true }).then(() => refetchQuery())
|
|
151
|
+
}, [client, cacheKey, refetchQuery])
|
|
42
152
|
}
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { useQuery, type UseQueryResult } from "@tanstack/react-query"
|
|
2
|
-
import { useCallTool } from "../providers/query-provider.js"
|
|
2
|
+
import { useCallTool, useToolNameInQueryKey } from "../providers/query-provider.js"
|
|
3
3
|
import { parseViewToolResult } from "../lib/parse-tool-result.js"
|
|
4
|
+
import { toolQueryOptions, type UseToolQueryOptions } from "../lib/tool-query.js"
|
|
5
|
+
import { useRefetchOnTransport, useToolKeyGuard } from "./use-tool-query.js"
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Options of {@link useViewToolQuery}: TanStack's query options, passed
|
|
9
|
+
* through like `useToolQuery`'s (`enabled`, `retry`, `staleTime`,
|
|
10
|
+
* `placeholderData`, `initialData`, …).
|
|
11
|
+
*/
|
|
12
|
+
export type UseViewToolQueryOptions<T = unknown> = UseToolQueryOptions<T>
|
|
8
13
|
|
|
9
14
|
/**
|
|
10
15
|
* Self-fetch hook for `*_show_*` widget tools — the envelope-unwrapping sibling
|
|
@@ -14,25 +19,26 @@ export interface UseViewToolQueryOptions {
|
|
|
14
19
|
* envelope; this hook decodes via {@link parseViewToolResult} (single-step →
|
|
15
20
|
* flat data, multi-step → keyed by step id) instead.
|
|
16
21
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
22
|
+
* Same key and options contract as {@link useToolQuery}: the effective key is
|
|
23
|
+
* `[...queryKey, args]` (`[...queryKey, toolName, args]` under an
|
|
24
|
+
* `AppQueryProvider` with `toolNameInQueryKey`), so sibling widgets sharing a
|
|
25
|
+
* query key and args collapse to a single deduped tool call.
|
|
20
26
|
*/
|
|
21
27
|
export function useViewToolQuery<T = unknown>(
|
|
22
|
-
queryKey: unknown[],
|
|
28
|
+
queryKey: readonly unknown[],
|
|
23
29
|
toolName: string,
|
|
24
30
|
args: object,
|
|
25
|
-
opts?: UseViewToolQueryOptions
|
|
31
|
+
opts?: UseViewToolQueryOptions<T>,
|
|
26
32
|
): UseQueryResult<T, Error> {
|
|
27
33
|
const callTool = useCallTool()
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
const toolNameInKey = useToolNameInQueryKey()
|
|
35
|
+
useToolKeyGuard(queryKey, toolName, args)
|
|
36
|
+
const query = useQuery<T, Error>(
|
|
37
|
+
toolQueryOptions<T>(queryKey, toolName, args, callTool, opts, {
|
|
38
|
+
decode: parseViewToolResult,
|
|
39
|
+
toolNameInKey,
|
|
40
|
+
}),
|
|
41
|
+
)
|
|
42
|
+
useRefetchOnTransport(callTool, query)
|
|
43
|
+
return query
|
|
38
44
|
}
|
|
@@ -17,6 +17,7 @@ import { BuilderBanners } from "./app/builder/BuilderBanners.js"
|
|
|
17
17
|
import { PipelineStrip } from "./app/builder/PipelineStrip.js"
|
|
18
18
|
import { StatusChip } from "./app/builder/status-chip.js"
|
|
19
19
|
import { Toolbar } from "./app/builder/Toolbar.js"
|
|
20
|
+
import { Workspace } from "./app/builder/Workspace.js"
|
|
20
21
|
import { WidgetCrashFallback, WidgetRenderer } from "./app/widget-renderer.js"
|
|
21
22
|
|
|
22
23
|
/**
|
|
@@ -135,6 +136,26 @@ const CHROME_CASES: { name: string; render: () => ReactElement }[] = [
|
|
|
135
136
|
/>
|
|
136
137
|
),
|
|
137
138
|
},
|
|
139
|
+
{
|
|
140
|
+
name: "ViewPlaceholder blocked (a writing tool, no retry)",
|
|
141
|
+
render: () => (
|
|
142
|
+
<ViewPlaceholder
|
|
143
|
+
lifecycle={{ phase: "error", reason: undefined, canRetry: false, kind: "blocked" }}
|
|
144
|
+
labels={PSEUDO.view}
|
|
145
|
+
onRetry={noop}
|
|
146
|
+
/>
|
|
147
|
+
),
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: "ViewPlaceholder blocked (load the view)",
|
|
151
|
+
render: () => (
|
|
152
|
+
<ViewPlaceholder
|
|
153
|
+
lifecycle={{ phase: "error", reason: undefined, canRetry: true, kind: "blocked" }}
|
|
154
|
+
labels={PSEUDO.view}
|
|
155
|
+
onRetry={noop}
|
|
156
|
+
/>
|
|
157
|
+
),
|
|
158
|
+
},
|
|
138
159
|
{
|
|
139
160
|
name: "StepErrors without a refresh",
|
|
140
161
|
render: () => (
|
|
@@ -167,6 +188,7 @@ const CHROME_CASES: { name: string; render: () => ReactElement }[] = [
|
|
|
167
188
|
onRefresh={asyncNoop}
|
|
168
189
|
onEnterBuildMode={noop}
|
|
169
190
|
onToggleFullscreen={asyncNoop}
|
|
191
|
+
dataAsOf="14:32"
|
|
170
192
|
/>
|
|
171
193
|
),
|
|
172
194
|
},
|
|
@@ -236,7 +258,7 @@ const CHROME_CASES: { name: string; render: () => ReactElement }[] = [
|
|
|
236
258
|
),
|
|
237
259
|
},
|
|
238
260
|
{
|
|
239
|
-
name: "Builder toolbar",
|
|
261
|
+
name: "Builder toolbar (advanced, unsaved)",
|
|
240
262
|
render: () => (
|
|
241
263
|
<Toolbar
|
|
242
264
|
L={PSEUDO.builder}
|
|
@@ -246,13 +268,93 @@ const CHROME_CASES: { name: string; render: () => ReactElement }[] = [
|
|
|
246
268
|
liveKeys={2}
|
|
247
269
|
reachableCount={5}
|
|
248
270
|
unreachableCount={1}
|
|
271
|
+
advanced
|
|
272
|
+
onToggleAdvanced={noop}
|
|
273
|
+
unsaved
|
|
249
274
|
onOpenCatalogue={noop}
|
|
250
275
|
onOpenSave={noop}
|
|
251
|
-
|
|
276
|
+
onDiscard={noop}
|
|
277
|
+
onApply={noop}
|
|
252
278
|
hasAnyCell
|
|
253
279
|
/>
|
|
254
280
|
),
|
|
255
281
|
},
|
|
282
|
+
{
|
|
283
|
+
name: "Builder workspace (titled and untitled palette entries, canvas cells)",
|
|
284
|
+
render: () => (
|
|
285
|
+
<Workspace
|
|
286
|
+
L={PSEUDO.builder}
|
|
287
|
+
paletteByApp={[
|
|
288
|
+
[
|
|
289
|
+
"demo",
|
|
290
|
+
[
|
|
291
|
+
{
|
|
292
|
+
id: "demo:orders",
|
|
293
|
+
app: "demo",
|
|
294
|
+
requires: ["demo:key"],
|
|
295
|
+
size: "full",
|
|
296
|
+
title: { en: "Orders", de: "Bestellungen" },
|
|
297
|
+
summary: { de: "Alle offenen Bestellungen." },
|
|
298
|
+
},
|
|
299
|
+
{ id: "demo:raw", app: "demo", requires: [], size: "half" },
|
|
300
|
+
],
|
|
301
|
+
],
|
|
302
|
+
]}
|
|
303
|
+
appDisplayByName={new Map()}
|
|
304
|
+
paletteCount={2}
|
|
305
|
+
paletteLoading={false}
|
|
306
|
+
onOpenDataSources={noop}
|
|
307
|
+
activeRows={[{ row: [{ widget: "demo:orders" }] }, { row: [] }]}
|
|
308
|
+
focusedRowIndex={0}
|
|
309
|
+
setFocusedRowIndex={noop}
|
|
310
|
+
dragOverRow={null}
|
|
311
|
+
setDragOverRow={noop}
|
|
312
|
+
onAddRow={noop}
|
|
313
|
+
onRemoveRow={noop}
|
|
314
|
+
onMoveRow={noop}
|
|
315
|
+
onSetCellSpan={noop}
|
|
316
|
+
onRemoveCell={noop}
|
|
317
|
+
onAddWidget={noop}
|
|
318
|
+
onConfigureCell={noop}
|
|
319
|
+
propsSchemaByWidgetId={new Map([["demo:orders", { type: "object" }]])}
|
|
320
|
+
displayByWidgetId={new Map([["demo:orders", { title: { de: "Bestellungen" } }]])}
|
|
321
|
+
advanced
|
|
322
|
+
widgets={{}}
|
|
323
|
+
widgetProps={{ keys: {}, context: { keys: {}, steps: {}, errors: [] } }}
|
|
324
|
+
onAddTab={noop}
|
|
325
|
+
/>
|
|
326
|
+
),
|
|
327
|
+
},
|
|
328
|
+
...[true, false].map((paletteLoading) => ({
|
|
329
|
+
name: `Builder workspace (palette ${paletteLoading ? "loading" : "empty"})`,
|
|
330
|
+
render: () => (
|
|
331
|
+
<Workspace
|
|
332
|
+
L={PSEUDO.builder}
|
|
333
|
+
paletteByApp={[]}
|
|
334
|
+
appDisplayByName={new Map()}
|
|
335
|
+
paletteCount={0}
|
|
336
|
+
paletteLoading={paletteLoading}
|
|
337
|
+
onOpenDataSources={noop}
|
|
338
|
+
activeRows={[{ row: [] }]}
|
|
339
|
+
focusedRowIndex={0}
|
|
340
|
+
setFocusedRowIndex={noop}
|
|
341
|
+
dragOverRow={null}
|
|
342
|
+
setDragOverRow={noop}
|
|
343
|
+
onAddRow={noop}
|
|
344
|
+
onRemoveRow={noop}
|
|
345
|
+
onMoveRow={noop}
|
|
346
|
+
onSetCellSpan={noop}
|
|
347
|
+
onRemoveCell={noop}
|
|
348
|
+
onAddWidget={noop}
|
|
349
|
+
onConfigureCell={noop}
|
|
350
|
+
propsSchemaByWidgetId={new Map()}
|
|
351
|
+
displayByWidgetId={new Map()}
|
|
352
|
+
advanced={false}
|
|
353
|
+
widgets={{}}
|
|
354
|
+
widgetProps={{ keys: {}, context: { keys: {}, steps: {}, errors: [] } }}
|
|
355
|
+
/>
|
|
356
|
+
),
|
|
357
|
+
})),
|
|
256
358
|
{
|
|
257
359
|
name: "Builder data sources",
|
|
258
360
|
render: () => (
|
package/src/index.ts
CHANGED
|
@@ -66,16 +66,40 @@ export {
|
|
|
66
66
|
// NOTE: the view-tool hooks (`useViewToolQuery`, `useViewData`) are exported
|
|
67
67
|
// from the `./hooks` subpath only — see `packages/ui/src/hooks/index.ts`.
|
|
68
68
|
export { useIsMobile } from "./hooks/use-mobile.js"
|
|
69
|
-
export { useToolQuery, useToolMutation } from "./hooks/use-tool-query.js"
|
|
70
|
-
export type { UseToolQueryOptions } from "./hooks/use-tool-query.js"
|
|
69
|
+
export { useToolQuery, useToolQueryKey, useToolMutation } from "./hooks/use-tool-query.js"
|
|
70
|
+
export type { UseToolQueryOptions, UseToolMutationOptions } from "./hooks/use-tool-query.js"
|
|
71
|
+
// The query layer's contract: the effective cache key, the opt-in retry
|
|
72
|
+
// policy (no retry of a tool's own isError answer), and TanStack's
|
|
73
|
+
// keepPreviousData for `placeholderData`, so a consumer needs no direct
|
|
74
|
+
// @tanstack/react-query import for the common options.
|
|
75
|
+
export { toolQueryKey, shouldRetryToolCall } from "./lib/tool-query.js"
|
|
76
|
+
export { ToolResultError, isToolError } from "./lib/parse-tool-result.js"
|
|
77
|
+
export { keepPreviousData } from "@tanstack/react-query"
|
|
71
78
|
export { useDebouncedValue } from "./hooks/use-debounced-value.js"
|
|
72
79
|
|
|
73
80
|
// Tone token system — the semantic status tones (ToneVariant + TONE_* maps)
|
|
74
|
-
// behind the tone-aware components below. Pure data + class strings.
|
|
81
|
+
// behind the tone-aware components below. Pure data + class strings. ONE
|
|
82
|
+
// vocabulary (TONE_VARIANTS; retired names map through resolveTone). Three
|
|
75
83
|
// roles per tone: colour (TONE_DOT/TONE_BORDER/TONE_ICON), tint (TONE_SOFT,
|
|
76
|
-
// foreground text on it), text on a plain surface (
|
|
77
|
-
|
|
78
|
-
export
|
|
84
|
+
// foreground text on it; TONE_TINT alone), text on a plain surface (TONE_INK,
|
|
85
|
+
// the -ink role; TONE_TEXT is its deprecated name).
|
|
86
|
+
export {
|
|
87
|
+
TONE_VARIANTS,
|
|
88
|
+
TONE_ALIASES,
|
|
89
|
+
resolveTone,
|
|
90
|
+
isToneVariant,
|
|
91
|
+
TONE_SOFT,
|
|
92
|
+
TONE_TINT,
|
|
93
|
+
TONE_DOT,
|
|
94
|
+
TONE_INK,
|
|
95
|
+
TONE_TEXT,
|
|
96
|
+
TONE_BORDER,
|
|
97
|
+
TONE_ICON,
|
|
98
|
+
} from "./lib/tone-utils.js"
|
|
99
|
+
export type { ToneVariant, ToneAlias, ToneName } from "./lib/tone-utils.js"
|
|
100
|
+
// The type scale (CI §4): text-title/section/body/dense/small utilities, 13 px floor.
|
|
101
|
+
export { TYPE_SCALE, TYPE_STEPS, TYPE_FLOOR_PX, MICRO_LABEL } from "./lib/typography.js"
|
|
102
|
+
export type { TypeStep } from "./lib/typography.js"
|
|
79
103
|
// The kit's opaque focus ring as class strings, for custom controls.
|
|
80
104
|
export { FOCUS_RING, FOCUS_RING_INSET } from "./lib/focus-ring.js"
|
|
81
105
|
|
|
@@ -83,14 +107,24 @@ export { FOCUS_RING, FOCUS_RING_INSET } from "./lib/focus-ring.js"
|
|
|
83
107
|
// primitives. Pure (React + primitives + cn), so they live in the root barrel.
|
|
84
108
|
export { GridLayout, GridItem } from "./components/GridLayout.js"
|
|
85
109
|
export type { GridLayoutProps, GridItemProps } from "./components/GridLayout.js"
|
|
86
|
-
export { KpiGrid } from "./components/KpiGrid.js"
|
|
87
|
-
export type {
|
|
88
|
-
|
|
89
|
-
|
|
110
|
+
export { KpiGrid, KpiGridSkeleton } from "./components/KpiGrid.js"
|
|
111
|
+
export type {
|
|
112
|
+
KpiGridProps,
|
|
113
|
+
KpiGridHeader,
|
|
114
|
+
KpiCell,
|
|
115
|
+
KpiGridSkeletonProps,
|
|
116
|
+
} from "./components/KpiGrid.js"
|
|
117
|
+
export { LivePill, CountPill, StatusBadge } from "./components/Pills.js"
|
|
118
|
+
export type {
|
|
119
|
+
LivePillProps,
|
|
120
|
+
CountPillProps,
|
|
121
|
+
StatusBadgeProps,
|
|
122
|
+
StatusBadgeText,
|
|
123
|
+
} from "./components/Pills.js"
|
|
90
124
|
export { SectionHeading } from "./components/SectionHeading.js"
|
|
91
125
|
export type { SectionHeadingProps } from "./components/SectionHeading.js"
|
|
92
126
|
export { WidgetHeader } from "./components/WidgetHeader.js"
|
|
93
|
-
export type { WidgetHeaderProps } from "./components/WidgetHeader.js"
|
|
127
|
+
export type { WidgetHeaderProps, WidgetHeadingLevel } from "./components/WidgetHeader.js"
|
|
94
128
|
export { GroupCard } from "./components/GroupCard.js"
|
|
95
129
|
export type { GroupCardProps } from "./components/GroupCard.js"
|
|
96
130
|
export { FilterBar } from "./components/FilterBar.js"
|
|
@@ -99,6 +133,8 @@ export { DrillButton } from "./components/DrillButton.js"
|
|
|
99
133
|
export type { DrillButtonProps } from "./components/DrillButton.js"
|
|
100
134
|
export { ListFooter } from "./components/ListFooter.js"
|
|
101
135
|
export type { ListFooterProps } from "./components/ListFooter.js"
|
|
136
|
+
export { PagedListFooter } from "./components/PagedListFooter.js"
|
|
137
|
+
export type { PagedListFooterProps, PagedListState } from "./components/PagedListFooter.js"
|
|
102
138
|
|
|
103
139
|
// Feedback and states — one pattern each for toasts, empty and error states.
|
|
104
140
|
export { ToastProvider, useToast } from "./components/Toast.js"
|
|
@@ -166,6 +202,7 @@ export type {
|
|
|
166
202
|
BoundTranslate,
|
|
167
203
|
BuilderMessages,
|
|
168
204
|
CommonMessages,
|
|
205
|
+
FilterBarMessages,
|
|
169
206
|
ListFooterMessages,
|
|
170
207
|
PropsSheetMessages,
|
|
171
208
|
RendererMessages,
|