@databricks/appkit-ui 0.38.1 → 0.40.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.
- package/dist/cli/commands/generate-types.js +114 -5
- package/dist/cli/commands/generate-types.js.map +1 -1
- package/dist/cli/commands/spawn-lock.js +116 -0
- package/dist/cli/commands/spawn-lock.js.map +1 -0
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/react/charts/index.d.ts +1 -0
- package/dist/react/charts/index.js +1 -0
- package/dist/react/charts/loading.d.ts +24 -0
- package/dist/react/charts/loading.d.ts.map +1 -0
- package/dist/react/charts/loading.js +20 -2
- package/dist/react/charts/loading.js.map +1 -1
- package/dist/react/charts/wrapper.d.ts.map +1 -1
- package/dist/react/charts/wrapper.js +9 -2
- package/dist/react/charts/wrapper.js.map +1 -1
- package/dist/react/hooks/index.d.ts +3 -1
- package/dist/react/hooks/index.js +2 -0
- package/dist/react/hooks/types.d.ts +28 -1
- package/dist/react/hooks/types.d.ts.map +1 -1
- package/dist/react/hooks/use-analytics-query.d.ts.map +1 -1
- package/dist/react/hooks/use-analytics-query.js +77 -45
- package/dist/react/hooks/use-analytics-query.js.map +1 -1
- package/dist/react/hooks/use-analytics-warehouse-status.js +48 -0
- package/dist/react/hooks/use-analytics-warehouse-status.js.map +1 -0
- package/dist/react/hooks/use-chart-data.d.ts +8 -0
- package/dist/react/hooks/use-chart-data.d.ts.map +1 -1
- package/dist/react/hooks/use-chart-data.js +3 -2
- package/dist/react/hooks/use-chart-data.js.map +1 -1
- package/dist/react/hooks/use-resource-status.d.ts +92 -0
- package/dist/react/hooks/use-resource-status.d.ts.map +1 -0
- package/dist/react/hooks/use-resource-status.js +199 -0
- package/dist/react/hooks/use-resource-status.js.map +1 -0
- package/dist/react/index.d.ts +5 -2
- package/dist/react/index.js +5 -2
- package/dist/react/resource-status-indicator.d.ts +78 -0
- package/dist/react/resource-status-indicator.d.ts.map +1 -0
- package/dist/react/resource-status-indicator.js +155 -0
- package/dist/react/resource-status-indicator.js.map +1 -0
- package/dist/react/ui/index.js +1 -1
- package/dist/react/ui/sonner.js +1 -1
- package/docs/development/type-generation.md +13 -0
- package/docs/plugins/analytics.md +156 -0
- package/package.json +1 -1
- package/sbom.cdx.json +1 -1
|
@@ -73,6 +73,19 @@ npx @databricks/appkit generate-types [rootDir] [outFile] [warehouseId]
|
|
|
73
73
|
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
### Warehouse readiness and the `--wait` flag[](#warehouse-readiness-and-the---wait-flag "Direct link to warehouse-readiness-and-the---wait-flag")
|
|
77
|
+
|
|
78
|
+
By default, `generate-types` is **non-blocking**: it never waits on — or fails because of — your SQL warehouse. It writes the best types it can immediately (reusing cached types where the query is unchanged, otherwise `result: unknown`) and then spawns a detached background worker that refreshes the real types once the warehouse is ready. This keeps `npm install` (postinstall) and `npm run dev` (predev) fast and resilient to a cold or briefly-unreachable warehouse. The dev Vite plugin behaves the same way: types appear instantly and refresh in place once the warehouse is live.
|
|
79
|
+
|
|
80
|
+
Pass `--wait` for CI and production builds, where accurate types must be present before the build proceeds:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
npx @databricks/appkit generate-types --wait
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
In blocking mode the generator starts a stopped warehouse, waits (bounded) for it to reach `RUNNING`, and then describes your queries. It fails only when the configured warehouse no longer exists (deleted/deleting), so a transient outage or a cold warehouse degrades gracefully rather than breaking the build. The app template wires this up for you: `postinstall` and `predev` run the non-blocking default, while `prebuild` runs `--wait`.
|
|
88
|
+
|
|
76
89
|
## How it works[](#how-it-works "Direct link to How it works")
|
|
77
90
|
|
|
78
91
|
The type generator:
|
|
@@ -97,6 +97,7 @@ const { data, loading, error } = useAnalyticsQuery(queryKey, parameters, options
|
|
|
97
97
|
data: T | null; // query result (typed array for JSON, TypedArrowTable for ARROW)
|
|
98
98
|
loading: boolean; // true while the query is executing
|
|
99
99
|
error: string | null; // error message, or null on success
|
|
100
|
+
warehouseStatus: WarehouseStatus | null; // see "Warehouse readiness" below
|
|
100
101
|
}
|
|
101
102
|
|
|
102
103
|
```
|
|
@@ -109,6 +110,161 @@ const { data, loading, error } = useAnalyticsQuery(queryKey, parameters, options
|
|
|
109
110
|
| `maxParametersSize` | `number` | `102400` | Max serialized parameters size in bytes |
|
|
110
111
|
| `autoStart` | `boolean` | `true` | Start query on mount |
|
|
111
112
|
|
|
113
|
+
### Warehouse readiness[](#warehouse-readiness "Direct link to Warehouse readiness")
|
|
114
|
+
|
|
115
|
+
If the configured SQL warehouse is `STOPPED` or `STARTING` when a query is requested, the analytics plugin will:
|
|
116
|
+
|
|
117
|
+
1. Auto-start the warehouse (when `STOPPED`).
|
|
118
|
+
2. Poll the warehouse state and stream `warehouse_status` events over SSE until it reaches `RUNNING`.
|
|
119
|
+
3. Execute the SQL statement.
|
|
120
|
+
|
|
121
|
+
This means a cold start no longer freezes the UI on a stalled spinner. Render the new `warehouseStatus` field to give users feedback:
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
import { useAnalyticsQuery } from "@databricks/appkit-ui/react";
|
|
125
|
+
|
|
126
|
+
function SpendTable() {
|
|
127
|
+
const { data, loading, error, warehouseStatus } =
|
|
128
|
+
useAnalyticsQuery("spend_summary", params);
|
|
129
|
+
|
|
130
|
+
if (warehouseStatus && warehouseStatus.state !== "RUNNING") {
|
|
131
|
+
return <div>Warehouse is {warehouseStatus.state.toLowerCase()}…</div>;
|
|
132
|
+
}
|
|
133
|
+
if (loading) return <div>Loading…</div>;
|
|
134
|
+
if (error) return <div>{error}</div>;
|
|
135
|
+
return <table>{/* render data */}</table>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
`warehouseStatus` is `null` until the first status event arrives. After the server has observed the warehouse `RUNNING` once, subsequent requests within \~30s skip the readiness check entirely and `warehouseStatus` stays `null`, so the steady-state hot path isn't taxed any extra round-trips.
|
|
141
|
+
|
|
142
|
+
If the warehouse is `DELETED`/`DELETING` or fails to reach `RUNNING` within the configured timeout, the route emits an `error` event (surfaced via the `error` field).
|
|
143
|
+
|
|
144
|
+
#### Global readiness indicator[](#global-readiness-indicator "Direct link to Global readiness indicator")
|
|
145
|
+
|
|
146
|
+
For dashboards with many charts a per-component spinner isn't enough — wiring the same "warehouse warming up" UI into every skeleton is repetitive. AppKit ships a small generic context (`ResourceStatusProvider`) + drop-in indicator (`ResourceStatusIndicator`) that any plugin can publish into; analytics warehouses are wired up automatically.
|
|
147
|
+
|
|
148
|
+
The indicator surfaces the worst pending status as a [sonner](https://sonner.emilkowal.ski/) toast, so it inherits sonner's animations, theming, and stacking. The component mounts its own `<Toaster />` (top-right by default) and forwards its props (`position`, `theme`, `richColors`, …):
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
import {
|
|
152
|
+
ResourceStatusIndicator,
|
|
153
|
+
ResourceStatusProvider,
|
|
154
|
+
} from "@databricks/appkit-ui/react";
|
|
155
|
+
|
|
156
|
+
export function AppShell({ children }) {
|
|
157
|
+
return (
|
|
158
|
+
<ResourceStatusProvider>
|
|
159
|
+
<ResourceStatusIndicator />
|
|
160
|
+
{children}
|
|
161
|
+
</ResourceStatusProvider>
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
`useAnalyticsQuery` registers itself with the nearest provider, so no per-chart wiring is needed. The indicator renders only the `<Toaster />` mount point while every resource is healthy; it pops a single sticky toast — `toast.loading` for cold starts, `toast.error` for unrecoverable states — keyed by the worst kind, and dismisses it when they all settle. Because the same provider is shared across resource kinds (warehouse, lakebase, model serving, …), a single indicator covers every plugin.
|
|
168
|
+
|
|
169
|
+
If you already render your own `<Toaster />` for unrelated app toasts, drop the indicator and call `useResourceStatusToaster()` instead so resource-status toasts share that single Toaster:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import {
|
|
173
|
+
useResourceStatusToaster,
|
|
174
|
+
Toaster,
|
|
175
|
+
} from "@databricks/appkit-ui/react";
|
|
176
|
+
|
|
177
|
+
function App() {
|
|
178
|
+
useResourceStatusToaster();
|
|
179
|
+
return (
|
|
180
|
+
<>
|
|
181
|
+
<Toaster position="top-right" />
|
|
182
|
+
<Routes />
|
|
183
|
+
</>
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
For a fully custom toast body, pass `render` (rendered through `toast.custom`):
|
|
190
|
+
|
|
191
|
+
```tsx
|
|
192
|
+
<ResourceStatusIndicator
|
|
193
|
+
render={(agg) => (
|
|
194
|
+
<div className="rounded-lg border bg-background p-3 shadow">
|
|
195
|
+
{agg.worst?.kind} {agg.worst?.state.toLowerCase()} ({agg.activeCount} waiting)
|
|
196
|
+
</div>
|
|
197
|
+
)}
|
|
198
|
+
/>
|
|
199
|
+
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
To override copy for a specific kind without rewriting the whole UI, pass `renderers`:
|
|
203
|
+
|
|
204
|
+
```tsx
|
|
205
|
+
<ResourceStatusIndicator
|
|
206
|
+
renderers={{
|
|
207
|
+
warehouse: {
|
|
208
|
+
title: () => "Spinning up your data",
|
|
209
|
+
description: (_s, agg) =>
|
|
210
|
+
`${agg.affectedLabels.length} chart(s) waiting`,
|
|
211
|
+
},
|
|
212
|
+
}}
|
|
213
|
+
/>
|
|
214
|
+
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Or build your own UI from the aggregate with `useResourceStatus()`:
|
|
218
|
+
|
|
219
|
+
```ts
|
|
220
|
+
import { useResourceStatus } from "@databricks/appkit-ui/react";
|
|
221
|
+
|
|
222
|
+
// Worst across all kinds
|
|
223
|
+
const aggregate = useResourceStatus();
|
|
224
|
+
// Just warehouses
|
|
225
|
+
const warehouseOnly = useResourceStatus({ kind: "warehouse" });
|
|
226
|
+
// { worst, byKind, affectedLabels, activeCount, elapsedMs }
|
|
227
|
+
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The provider is optional. Apps that don't mount it still get the per-hook `warehouseStatus` field and the hook works exactly as before.
|
|
231
|
+
|
|
232
|
+
##### Publishing your own resource status[](#publishing-your-own-resource-status "Direct link to Publishing your own resource status")
|
|
233
|
+
|
|
234
|
+
Plugins (or your own code) can hook into the same provider for non-analytics resources — e.g. a Lakebase Postgres connection warming up, a model-serving endpoint cold-starting:
|
|
235
|
+
|
|
236
|
+
```ts
|
|
237
|
+
import { useResourceStatusPublisher } from "@databricks/appkit-ui/react";
|
|
238
|
+
import { useEffect, useId } from "react";
|
|
239
|
+
|
|
240
|
+
function useLakebaseReadiness() {
|
|
241
|
+
const id = useId();
|
|
242
|
+
const { publish, unpublish } = useResourceStatusPublisher(
|
|
243
|
+
id,
|
|
244
|
+
"lakebase",
|
|
245
|
+
{ kindHint: "lakebase" },
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
useEffect(() => {
|
|
249
|
+
publish({
|
|
250
|
+
kind: "lakebase",
|
|
251
|
+
state: "STARTING",
|
|
252
|
+
severity: "pending",
|
|
253
|
+
startedAt: Date.now(),
|
|
254
|
+
});
|
|
255
|
+
return () => unpublish();
|
|
256
|
+
}, [publish, unpublish]);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Server config (in `analytics({...})`):**
|
|
262
|
+
|
|
263
|
+
| Option | Type | Default | Description |
|
|
264
|
+
| --------------------------- | --------- | ---------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
265
|
+
| `warehouseStartupTimeoutMs` | `number` | `300000` (5 min) | Maximum time to wait for the warehouse to reach `RUNNING` before failing the request |
|
|
266
|
+
| `autoStartWarehouse` | `boolean` | `true` | When `true`, a `STOPPED` warehouse is auto-started on the first request. Set to `false` for cost-controlled deployments where billable warehouse starts must not be triggered by user requests; in that case `STOPPED` surfaces as a `ConfigurationError` |
|
|
267
|
+
|
|
112
268
|
**Example with loading/error/empty handling:**
|
|
113
269
|
|
|
114
270
|
```tsx
|