@mastra/playground-ui 22.2.0-alpha.9 → 23.0.0-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +37 -0
- package/dist/index.cjs.js +177 -27
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.css +152 -7
- package/dist/index.es.js +178 -29
- package/dist/index.es.js.map +1 -1
- package/dist/src/ds/components/BrandLoader/brand-loader.stories.d.ts +6 -0
- package/dist/src/ds/components/ErrorBoundary/ErrorBoundary.d.ts +44 -0
- package/dist/src/ds/components/ErrorBoundary/error-boundary.stories.d.ts +12 -0
- package/dist/src/ds/components/ErrorBoundary/index.d.ts +2 -0
- package/dist/src/index.d.ts +1 -0
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# @mastra/playground-ui
|
|
2
2
|
|
|
3
|
+
## 23.0.0-alpha.10
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Added `ErrorBoundary` component to catch and display runtime errors in the studio. Wraps routes in the local playground so a crash on one page (e.g. an agent editor referencing an unresolved workspace skill) surfaces a friendly recovery UI with **Try again** (in-place React reset), **Reload page** (full browser refresh), and **Report issue** (opens the Mastra GitHub issues page in a new tab) actions, plus a collapsible stack trace — instead of a blank screen. ([#15561](https://github.com/mastra-ai/mastra/pull/15561))
|
|
8
|
+
|
|
9
|
+
The fallback is spatially aware: it fills its parent and the icon, heading, and body text scale up on wider containers via Tailwind container queries. Scope the boundary to a single widget to keep the rest of the UI interactive while one panel fails.
|
|
10
|
+
|
|
11
|
+
**Usage**
|
|
12
|
+
|
|
13
|
+
```tsx
|
|
14
|
+
import { ErrorBoundary } from '@mastra/playground-ui';
|
|
15
|
+
import { useLocation } from 'react-router';
|
|
16
|
+
|
|
17
|
+
// Route-level: wrap the router outlet, reset when the path changes
|
|
18
|
+
function Layout({ children }) {
|
|
19
|
+
const { pathname } = useLocation();
|
|
20
|
+
return <ErrorBoundary resetKeys={[pathname]}>{children}</ErrorBoundary>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Scoped: contain the crash to one panel, leave the rest of the tree alone
|
|
24
|
+
<ErrorBoundary variant="inline" title="The editor failed to render">
|
|
25
|
+
<AgentEditor />
|
|
26
|
+
</ErrorBoundary>;
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Props: `fallback` (node or render prop with `{ error, errorInfo, reset }`), `onError` for reporting, `resetKeys` for automatic reset, `variant` (`'section'` — fills available space, default; `'inline'` — stays compact), and `title` / `description` overrides.
|
|
30
|
+
|
|
31
|
+
### Patch Changes
|
|
32
|
+
|
|
33
|
+
- Align BrandLoader geometry with the Mastra logo: match disk positions to the logo path, introduce per-size stroke widths and bubble radii (sm/md/lg), and rebalance the gooey filter for rounder ridge↔disk fillets. Shift the size scale so sm stays, md is now w-8, lg is now w-10, and the old w-16 size is removed. ([#15531](https://github.com/mastra-ai/mastra/pull/15531))
|
|
34
|
+
|
|
35
|
+
- Updated dependencies [[`aba393e`](https://github.com/mastra-ai/mastra/commit/aba393e2da7390c69b80e516a4f153cda6f09376), [`0a5fa1d`](https://github.com/mastra-ai/mastra/commit/0a5fa1d3cb0583889d06687155f26fd7d2edc76c), [`ea43e64`](https://github.com/mastra-ai/mastra/commit/ea43e646dd95d507694b6112b0bf1df22ad552b2), [`00d1b16`](https://github.com/mastra-ai/mastra/commit/00d1b16b401199cb294fa23f43336547db4dca9b), [`af8a57e`](https://github.com/mastra-ai/mastra/commit/af8a57ed9ba9685ad8601d5b71ae3706da6222f9), [`be49755`](https://github.com/mastra-ai/mastra/commit/be4975575e63b38f63af588ea8ce6f4cf5b8ff2c)]:
|
|
36
|
+
- @mastra/core@1.26.0-alpha.10
|
|
37
|
+
- @mastra/client-js@1.14.0-alpha.10
|
|
38
|
+
- @mastra/react@0.2.27-alpha.10
|
|
39
|
+
|
|
3
40
|
## 22.2.0-alpha.9
|
|
4
41
|
|
|
5
42
|
### Minor Changes
|
package/dist/index.cjs.js
CHANGED
|
@@ -7716,43 +7716,46 @@ Slider.displayName = SliderPrimitive__namespace.Root.displayName;
|
|
|
7716
7716
|
|
|
7717
7717
|
const sizeClasses$1 = {
|
|
7718
7718
|
sm: "w-6",
|
|
7719
|
-
md: "w-
|
|
7720
|
-
lg: "w-
|
|
7719
|
+
md: "w-8",
|
|
7720
|
+
lg: "w-10"
|
|
7721
|
+
};
|
|
7722
|
+
const strokeBySize = {
|
|
7723
|
+
sm: 2.2,
|
|
7724
|
+
md: 2.5,
|
|
7725
|
+
lg: 2.9
|
|
7726
|
+
};
|
|
7727
|
+
const bubbleBySize = {
|
|
7728
|
+
sm: 4.3,
|
|
7729
|
+
md: 4.4,
|
|
7730
|
+
lg: 4.498
|
|
7721
7731
|
};
|
|
7722
7732
|
function BrandLoader({ className, size = "md", "aria-label": ariaLabel = "Loading" }) {
|
|
7723
7733
|
const reactId = React.useId();
|
|
7724
7734
|
const filterId = `brand-loader-${reactId.replace(/[^a-zA-Z0-9_-]/g, "")}`;
|
|
7735
|
+
const r = bubbleBySize[size];
|
|
7725
7736
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
7726
7737
|
"div",
|
|
7727
7738
|
{
|
|
7728
7739
|
role: "status",
|
|
7729
7740
|
"aria-label": ariaLabel,
|
|
7730
7741
|
className: cn("brand-loader inline-block text-neutral6", sizeClasses$1[size], className),
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
{
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b2", cx: "10.4", cy: "4.5", r: "4.5" }),
|
|
7749
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b3", cx: "16.8", cy: "16.2", r: "4.5" }),
|
|
7750
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b4", cx: "23.2", cy: "4.5", r: "4.5" }),
|
|
7751
|
-
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b5", cx: "29.5", cy: "16.2", r: "4.5" })
|
|
7752
|
-
] })
|
|
7753
|
-
]
|
|
7754
|
-
}
|
|
7755
|
-
)
|
|
7742
|
+
style: { ["--brand-loader-stroke"]: strokeBySize[size] },
|
|
7743
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 34 21", "aria-hidden": "true", children: [
|
|
7744
|
+
/* @__PURE__ */ jsxRuntime.jsx("defs", { children: /* @__PURE__ */ jsxRuntime.jsxs("filter", { id: filterId, x: "-5%", y: "-5%", width: "110%", height: "110%", children: [
|
|
7745
|
+
/* @__PURE__ */ jsxRuntime.jsx("feGaussianBlur", { in: "SourceGraphic", stdDeviation: "0.9" }),
|
|
7746
|
+
/* @__PURE__ */ jsxRuntime.jsx("feColorMatrix", { values: "1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 11 -4.3" })
|
|
7747
|
+
] }) }),
|
|
7748
|
+
/* @__PURE__ */ jsxRuntime.jsxs("g", { filter: `url(#${filterId})`, children: [
|
|
7749
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { className: "brand-loader-ln23", x1: "10.387", y1: "4.498", x2: "16.899", y2: "16.192" }),
|
|
7750
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { className: "brand-loader-ln34", x1: "16.899", y1: "16.192", x2: "22.815", y2: "4.56" }),
|
|
7751
|
+
/* @__PURE__ */ jsxRuntime.jsx("line", { className: "brand-loader-ln45", x1: "22.815", y1: "4.56", x2: "28.57", y2: "16.192" }),
|
|
7752
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b1", cx: "4.498", cy: "16.192", r }),
|
|
7753
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b2", cx: "10.387", cy: "4.498", r }),
|
|
7754
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b3", cx: "16.899", cy: "16.192", r }),
|
|
7755
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b4", cx: "22.815", cy: "4.56", r }),
|
|
7756
|
+
/* @__PURE__ */ jsxRuntime.jsx("circle", { className: "brand-loader-b5", cx: "28.57", cy: "16.192", r })
|
|
7757
|
+
] })
|
|
7758
|
+
] })
|
|
7756
7759
|
}
|
|
7757
7760
|
);
|
|
7758
7761
|
}
|
|
@@ -12003,6 +12006,152 @@ const ListSearch = ({
|
|
|
12003
12006
|
);
|
|
12004
12007
|
};
|
|
12005
12008
|
|
|
12009
|
+
const INITIAL_STATE = { error: null, errorInfo: null };
|
|
12010
|
+
function keysChanged(prev, next) {
|
|
12011
|
+
if (prev === next) return false;
|
|
12012
|
+
if (!prev || !next) return true;
|
|
12013
|
+
if (prev.length !== next.length) return true;
|
|
12014
|
+
for (let i = 0; i < prev.length; i++) {
|
|
12015
|
+
if (!Object.is(prev[i], next[i])) return true;
|
|
12016
|
+
}
|
|
12017
|
+
return false;
|
|
12018
|
+
}
|
|
12019
|
+
class ErrorBoundary extends React__namespace.Component {
|
|
12020
|
+
state = INITIAL_STATE;
|
|
12021
|
+
static getDerivedStateFromError(error) {
|
|
12022
|
+
return { error };
|
|
12023
|
+
}
|
|
12024
|
+
componentDidCatch(error, errorInfo) {
|
|
12025
|
+
this.setState({ errorInfo });
|
|
12026
|
+
if (this.props.onError) {
|
|
12027
|
+
try {
|
|
12028
|
+
this.props.onError(error, errorInfo);
|
|
12029
|
+
} catch (handlerError) {
|
|
12030
|
+
if (typeof console !== "undefined") {
|
|
12031
|
+
console.error("[ErrorBoundary] onError handler threw:", handlerError);
|
|
12032
|
+
}
|
|
12033
|
+
}
|
|
12034
|
+
}
|
|
12035
|
+
if (typeof console !== "undefined") {
|
|
12036
|
+
console.error("[ErrorBoundary] Uncaught error:", error, errorInfo);
|
|
12037
|
+
}
|
|
12038
|
+
}
|
|
12039
|
+
componentDidUpdate(prevProps) {
|
|
12040
|
+
if (this.state.error && keysChanged(prevProps.resetKeys, this.props.resetKeys)) {
|
|
12041
|
+
this.reset();
|
|
12042
|
+
}
|
|
12043
|
+
}
|
|
12044
|
+
reset = () => {
|
|
12045
|
+
this.setState(INITIAL_STATE);
|
|
12046
|
+
};
|
|
12047
|
+
render() {
|
|
12048
|
+
const { error, errorInfo } = this.state;
|
|
12049
|
+
const { children, fallback, title, description, variant, className } = this.props;
|
|
12050
|
+
if (!error) return children;
|
|
12051
|
+
if (typeof fallback === "function") {
|
|
12052
|
+
return fallback({ error, errorInfo, reset: this.reset });
|
|
12053
|
+
}
|
|
12054
|
+
if (fallback !== void 0) return fallback;
|
|
12055
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12056
|
+
DefaultErrorFallback,
|
|
12057
|
+
{
|
|
12058
|
+
error,
|
|
12059
|
+
errorInfo,
|
|
12060
|
+
reset: this.reset,
|
|
12061
|
+
title,
|
|
12062
|
+
description,
|
|
12063
|
+
variant: variant ?? "section",
|
|
12064
|
+
className
|
|
12065
|
+
}
|
|
12066
|
+
);
|
|
12067
|
+
}
|
|
12068
|
+
}
|
|
12069
|
+
function DefaultErrorFallback({
|
|
12070
|
+
error,
|
|
12071
|
+
errorInfo,
|
|
12072
|
+
reset,
|
|
12073
|
+
title,
|
|
12074
|
+
description,
|
|
12075
|
+
variant,
|
|
12076
|
+
className
|
|
12077
|
+
}) {
|
|
12078
|
+
const stack = errorInfo?.componentStack ?? error.stack ?? "";
|
|
12079
|
+
const isInline = variant === "inline";
|
|
12080
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
12081
|
+
"div",
|
|
12082
|
+
{
|
|
12083
|
+
role: "alert",
|
|
12084
|
+
className: cn(
|
|
12085
|
+
"@container flex w-full items-center justify-center",
|
|
12086
|
+
isInline ? "py-6 px-4" : "h-full min-h-[240px] flex-1 py-10 px-6",
|
|
12087
|
+
className
|
|
12088
|
+
),
|
|
12089
|
+
children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
12090
|
+
"div",
|
|
12091
|
+
{
|
|
12092
|
+
className: cn(
|
|
12093
|
+
"flex flex-col items-center text-center",
|
|
12094
|
+
isInline ? "gap-3 max-w-md" : "gap-4 max-w-2xl @md:gap-5 @lg:gap-6"
|
|
12095
|
+
),
|
|
12096
|
+
children: [
|
|
12097
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12098
|
+
"div",
|
|
12099
|
+
{
|
|
12100
|
+
className: cn(
|
|
12101
|
+
"rounded-full bg-accent2/10 text-accent2 flex items-center justify-center",
|
|
12102
|
+
isInline ? "h-10 w-10 [&>svg]:h-5 [&>svg]:w-5" : "h-14 w-14 [&>svg]:h-7 [&>svg]:w-7 @md:h-16 @md:w-16 @md:[&>svg]:h-8 @md:[&>svg]:w-8 @lg:h-20 @lg:w-20 @lg:[&>svg]:h-10 @lg:[&>svg]:w-10"
|
|
12103
|
+
),
|
|
12104
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertTriangle, {})
|
|
12105
|
+
}
|
|
12106
|
+
),
|
|
12107
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12108
|
+
"h3",
|
|
12109
|
+
{
|
|
12110
|
+
className: cn(
|
|
12111
|
+
"font-medium text-neutral6",
|
|
12112
|
+
isInline ? "text-ui-md" : "text-ui-lg @md:text-header-md @lg:text-header-lg"
|
|
12113
|
+
),
|
|
12114
|
+
children: title ?? "Something went wrong"
|
|
12115
|
+
}
|
|
12116
|
+
),
|
|
12117
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: cn("text-neutral3", isInline ? "text-ui-sm" : "text-ui-md @lg:text-ui-lg"), children: description ?? "An unexpected error occurred while rendering this part of the page." }),
|
|
12118
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12119
|
+
"p",
|
|
12120
|
+
{
|
|
12121
|
+
className: cn(
|
|
12122
|
+
"font-mono text-neutral4 break-words rounded-md bg-surface3 px-3 py-2",
|
|
12123
|
+
isInline ? "text-ui-xs" : "text-ui-sm"
|
|
12124
|
+
),
|
|
12125
|
+
children: error.message
|
|
12126
|
+
}
|
|
12127
|
+
),
|
|
12128
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn("flex flex-wrap items-center justify-center gap-2", isInline ? "mt-1" : "mt-2"), children: [
|
|
12129
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "primary", size: isInline ? "sm" : "default", onClick: reset, children: "Try again" }),
|
|
12130
|
+
/* @__PURE__ */ jsxRuntime.jsx(Button, { variant: "default", size: isInline ? "sm" : "default", onClick: () => window.location.reload(), children: "Reload page" }),
|
|
12131
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
12132
|
+
Button,
|
|
12133
|
+
{
|
|
12134
|
+
as: "a",
|
|
12135
|
+
variant: "default",
|
|
12136
|
+
size: isInline ? "sm" : "default",
|
|
12137
|
+
href: "https://github.com/mastra-ai/mastra/issues",
|
|
12138
|
+
target: "_blank",
|
|
12139
|
+
rel: "noopener noreferrer",
|
|
12140
|
+
children: "Report issue"
|
|
12141
|
+
}
|
|
12142
|
+
)
|
|
12143
|
+
] }),
|
|
12144
|
+
stack ? /* @__PURE__ */ jsxRuntime.jsxs("details", { className: cn("w-full text-left", isInline ? "mt-1" : "mt-2"), children: [
|
|
12145
|
+
/* @__PURE__ */ jsxRuntime.jsx("summary", { className: "cursor-pointer text-ui-sm text-neutral3 hover:text-neutral4", children: "Show error details" }),
|
|
12146
|
+
/* @__PURE__ */ jsxRuntime.jsx("pre", { className: "mt-2 max-h-64 overflow-auto rounded-md bg-surface3 p-3 text-ui-xs text-neutral4 whitespace-pre-wrap break-words", children: stack })
|
|
12147
|
+
] }) : null
|
|
12148
|
+
]
|
|
12149
|
+
}
|
|
12150
|
+
)
|
|
12151
|
+
}
|
|
12152
|
+
);
|
|
12153
|
+
}
|
|
12154
|
+
|
|
12006
12155
|
function ErrorState({ title, message }) {
|
|
12007
12156
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-center h-[30vh]", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col items-center justify-center text-center py-10 px-6", children: [
|
|
12008
12157
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntime.jsx(lucideReact.CircleXIcon, { className: "h-8 w-8 text-red-900" }) }),
|
|
@@ -14356,6 +14505,7 @@ exports.EntryCell = EntryCell;
|
|
|
14356
14505
|
exports.EntryList = EntryList;
|
|
14357
14506
|
exports.EntryListSkeleton = EntryListSkeleton;
|
|
14358
14507
|
exports.EnvIcon = EnvIcon;
|
|
14508
|
+
exports.ErrorBoundary = ErrorBoundary;
|
|
14359
14509
|
exports.ErrorState = ErrorState;
|
|
14360
14510
|
exports.Field = Field;
|
|
14361
14511
|
exports.FieldBlock = FieldBlock;
|