@unblind/react 0.1.0-alpha.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.
@@ -0,0 +1,520 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import React$1, { ReactNode, PropsWithChildren } from 'react';
3
+ import { QueryClient, QueryClientConfig } from '@tanstack/react-query';
4
+ import { StringValue } from 'ms';
5
+ import uPlot from 'uplot';
6
+
7
+ type UnblindClientConfig = {
8
+ /**
9
+ * Base URL that client-side hooks will use.
10
+ * Should point to the host app endpoint that is proxied by middleware.
11
+ * Defaults to `/api/unblind`.
12
+ */
13
+ apiBaseUrl: string;
14
+ /**
15
+ * Optional custom fetch implementation (for tests or advanced setups).
16
+ * When not provided, the global `fetch` will be used.
17
+ */
18
+ fetchImpl?: typeof fetch;
19
+ };
20
+ type UnblindClientProviderProps = {
21
+ children: ReactNode;
22
+ /**
23
+ * Optional QueryClient instance. If not provided, a new one will be created.
24
+ * Useful if you already have a QueryClientProvider in your app and want to reuse it.
25
+ */
26
+ queryClient?: QueryClient;
27
+ /**
28
+ * Optional QueryClientConfig. If not provided, a default one will be used.
29
+ * Useful if you already have a QueryClientProvider in your app and want to reuse it.
30
+ */
31
+ queryClientConfig?: QueryClientConfig | undefined;
32
+ /**
33
+ * Optional API base URL override. Defaults to `/api/unblind`.
34
+ */
35
+ apiBaseUrl?: string;
36
+ /**
37
+ * Optional custom fetch implementation (for tests or advanced setups).
38
+ */
39
+ fetchImpl?: typeof fetch;
40
+ };
41
+ /**
42
+ * UnblindClientProvider sets up the QueryClientProvider (for React Query)
43
+ * and the Unblind client configuration context.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * import { UnblindClientProvider } from '@unblind/react';
48
+ *
49
+ * function App() {
50
+ * return (
51
+ * <UnblindClientProvider apiBaseUrl="/api/unblind">
52
+ * <YourComponents />
53
+ * </UnblindClientProvider>
54
+ * );
55
+ * }
56
+ * ```
57
+ */
58
+ declare function UnblindClientProvider({ children, queryClient: providedQueryClient, queryClientConfig: providedQueryClientConfig, apiBaseUrl, fetchImpl, }: UnblindClientProviderProps): react_jsx_runtime.JSX.Element;
59
+ /**
60
+ * Access the Unblind client configuration.
61
+ *
62
+ * @throws Error if called outside of an UnblindClientProvider.
63
+ * This ensures that QueryClientProvider is always available for hooks.
64
+ */
65
+ declare function useUnblindClientConfig(): UnblindClientConfig;
66
+ /**
67
+ * Hook to refresh all timeseries data.
68
+ * Invalidates all queries with the 'unblind' and 'timeseries' keys,
69
+ * causing them to refetch automatically.
70
+ *
71
+ * @example
72
+ * ```tsx
73
+ * function Dashboard() {
74
+ * const refresh = useRefresh();
75
+ * return (
76
+ * <>
77
+ * <button onClick={() => refresh()}>Refresh</button>
78
+ * <TimeseriesChart metrics={["cpu"]} />
79
+ * </>
80
+ * );
81
+ * }
82
+ * ```
83
+ */
84
+ declare function useRefresh(): () => Promise<void>;
85
+
86
+ interface TooltipItem {
87
+ metric: string | HTMLElement | undefined;
88
+ color: string;
89
+ value?: number;
90
+ formattedValue?: string;
91
+ attributes?: Record<string, any>;
92
+ }
93
+ interface TooltipProps {
94
+ timestamp: number;
95
+ items: TooltipItem[];
96
+ timeZone?: string;
97
+ }
98
+
99
+ /**
100
+ * Shared types for Unblind React library.
101
+ */
102
+
103
+ type MetricType = "gauge" | "sum" | "histogram" | "summary" | "exphistogram";
104
+ /**
105
+ * Aggregation operators available for metric queries.
106
+ */
107
+ type AggregationOperator = "avg" | "sum" | "max" | "min" | "p90" | "p99" | "p50";
108
+ /**
109
+ * Attribute filter with a specific value.
110
+ */
111
+ interface AttributeWithValue {
112
+ name: string;
113
+ value: string;
114
+ }
115
+ /**
116
+ * Metric metadata returned by the API.
117
+ */
118
+ interface MetricMetadata {
119
+ name: string;
120
+ description: string;
121
+ displayName?: string;
122
+ unit: {
123
+ code?: string;
124
+ name?: string;
125
+ synonym?: string;
126
+ category?: string;
127
+ };
128
+ type: MetricType;
129
+ operator?: AggregationOperator;
130
+ }
131
+ /**
132
+ * List of metric metadata.
133
+ */
134
+ type MetricMetadataList = Array<MetricMetadata>;
135
+ /**
136
+ * A single time series data point.
137
+ */
138
+ interface Serie {
139
+ metric: string;
140
+ attributes: Array<AttributeWithValue>;
141
+ values: Array<number>;
142
+ queryName?: string;
143
+ queryIndex: number;
144
+ isEmpty?: boolean;
145
+ }
146
+ /**
147
+ * Query definition for timeseries requests.
148
+ */
149
+ interface TimeseriesQuery {
150
+ queryName?: string;
151
+ metrics: Array<string>;
152
+ groupBy?: Array<string>;
153
+ operator?: AggregationOperator;
154
+ attributes?: Partial<Record<string, Array<string>>>;
155
+ }
156
+ /**
157
+ * Chart types available
158
+ */
159
+ type ChartType = "bar" | "line" | "area" | "step";
160
+ /**
161
+ * Time Range definition:
162
+ *
163
+ * e.g. 5secs, 4h, 3 days, and so on.
164
+ */
165
+ type TimeRange = StringValue;
166
+ interface Log {
167
+ timestamp: number;
168
+ trace_id?: string;
169
+ span_id?: string;
170
+ severity_text: Severity;
171
+ attributes?: Record<string, string>;
172
+ service_name?: string;
173
+ body?: string;
174
+ }
175
+ /**
176
+ * Default paginated response structure
177
+ */
178
+ type PaginatedResponse<T> = {
179
+ data: Array<T>;
180
+ next_page?: string;
181
+ };
182
+ /**
183
+ * Different severity values based on OTEL
184
+ * https://opentelemetry.io/docs/specs/otel/logs/data-model/#field-severitytext
185
+ */
186
+ type Severity = "TRACE" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "FATAL";
187
+ type Colors = Array<string> | ((serie: Serie, index: number) => string);
188
+ /**
189
+ * Interval expressed in milliseconds.
190
+ */
191
+ type Interval = number;
192
+ type TimeConfig = {
193
+ /**
194
+ * Optional time range. If not provided, will use timeRange from the provider.
195
+ * Ignored if startTime and endTime are provided.
196
+ */
197
+ timeRange?: TimeRange;
198
+ /**
199
+ * Optional start time (Unix timestamp in milliseconds).
200
+ * If provided along with endTime, takes priority over timeRange.
201
+ */
202
+ startTime?: number;
203
+ /**
204
+ * Optional end time (Unix timestamp in milliseconds).
205
+ * If provided along with startTime, takes priority over timeRange.
206
+ */
207
+ endTime?: number;
208
+ };
209
+ /**
210
+ * Base query configuration for timeseries data.
211
+ * Used across components and providers.
212
+ */
213
+ type TimeseriesQueryConfig = TimeConfig & {
214
+ /**
215
+ * Optional interval in milliseconds. If not provided, will use interval from the provider.
216
+ */
217
+ interval?: Interval;
218
+ /**
219
+ * Optional attributes filter. If not provided, will use attributes from the provider.
220
+ */
221
+ attributes?: Record<string, Array<string>>;
222
+ /**
223
+ * Optional groupBy. If not provided, will use groupBy from the provider.
224
+ */
225
+ groupBy?: Array<string>;
226
+ /**
227
+ * Optional aggregation operator. If not provided, will use the operator from the provider.
228
+ */
229
+ operator?: AggregationOperator;
230
+ };
231
+ /**
232
+ * Visual/presentation configuration for charts.
233
+ */
234
+ interface ChartVisualConfig {
235
+ /**
236
+ * Optional color configuration
237
+ */
238
+ colors?: Colors;
239
+ /**
240
+ * Optional order for rendering results.
241
+ * Defaults to false
242
+ */
243
+ orderByValues?: boolean;
244
+ }
245
+ /**
246
+ * Appearance configuration for Unblind components.
247
+ *
248
+ * Allows consumers to override internal UI components used for
249
+ * loading, empty, and error states.
250
+ *
251
+ * Overrides can be provided globally via UnblindScope or
252
+ * locally per component.
253
+ *
254
+ * This API customizes presentation only; component state and data
255
+ * fetching logic remain internal.
256
+ */
257
+ type Appearance = {
258
+ components?: {
259
+ Loading?: React.ComponentType;
260
+ Error?: React.ComponentType;
261
+ Empty?: React.ComponentType;
262
+ Tooltip?: React.ComponentType<TooltipProps>;
263
+ };
264
+ } & ChartVisualConfig;
265
+ type TimeseriesProps = TimeseriesQueryConfig & {
266
+ /**
267
+ * Array of metric names to display in the chart.
268
+ */
269
+ metrics: Array<string>;
270
+ };
271
+
272
+ type UnblindScopeConfig = TimeseriesQueryConfig & {
273
+ /**
274
+ * Optional appearance configuration for all components
275
+ * within this scope.
276
+ *
277
+ * Use this to globally override UI components such as loading,
278
+ * or error states.
279
+ *
280
+ * Local overrides passed directly to a component take
281
+ * precedence over this configuration.
282
+ *
283
+ * @example
284
+ * ```tsx
285
+ * <UnblindScope
286
+ * appearance={{
287
+ * components: {
288
+ * Loading: CustomLoading,
289
+ * Error: CustomError,
290
+ * },
291
+ * }}
292
+ * >
293
+ * <App />
294
+ * </UnblindScope>
295
+ * ```
296
+ */
297
+ appearance?: Appearance;
298
+ };
299
+ type UnblindScopeProps = UnblindScopeConfig & PropsWithChildren;
300
+ /**
301
+ * UnblindScope provides scoped configuration for all Unblind components (charts, logs, etc).
302
+ * This includes default time ranges, intervals, attributes, groupBy, operator, appearance, and colors.
303
+ *
304
+ * When nested, child scopes inherit defaults from parent scopes and can override specific values.
305
+ * This allows you to set global defaults (like appearance) at the top level and override
306
+ * settings (like timeRange) in nested scopes.
307
+ *
308
+ * @example
309
+ * ```tsx
310
+ * import { UnblindScope } from '@unblind/react';
311
+ *
312
+ * function App() {
313
+ * return (
314
+ * <UnblindScope
315
+ * appearance={{ components: { Loading: CustomLoading } }}
316
+ * timeRange="24h"
317
+ * >
318
+ * // Components here use 24h and CustomLoading
319
+ *
320
+ * <UnblindScope timeRange="1h">
321
+ * // Components here use 1h but still inherit CustomLoading
322
+ * </UnblindScope>
323
+ * </UnblindScope>
324
+ * );
325
+ * }
326
+ * ```
327
+ */
328
+ declare function UnblindScope({ children, timeRange, startTime, endTime, interval, attributes, groupBy, operator, appearance, }: UnblindScopeProps): react_jsx_runtime.JSX.Element;
329
+ type UseScopeReturn = TimeseriesQueryConfig & {
330
+ timeRange: TimeRange;
331
+ appearance: {
332
+ components: {
333
+ Loading: React$1.ComponentType;
334
+ Error: React$1.ComponentType;
335
+ Empty: React$1.ComponentType;
336
+ Tooltip?: React$1.ComponentType<TooltipProps>;
337
+ };
338
+ colors: Colors;
339
+ orderByValues?: boolean;
340
+ };
341
+ };
342
+ /**
343
+ * Hook to access the scoped configuration from UnblindScope.
344
+ * Returns all configuration including time range, attributes,
345
+ * groupBy, operator, colors, and UI components.
346
+ *
347
+ * @example
348
+ * ```tsx
349
+ * function MyChart() {
350
+ * const { timeRange, colors, appearance } = useScope();
351
+ * // Use configuration...
352
+ * }
353
+ * ```
354
+ */
355
+ declare function useScope(): UseScopeReturn;
356
+
357
+ type UnblindProviderProps = UnblindClientProviderProps & UnblindScopeProps & PropsWithChildren;
358
+ /**
359
+ * UnblindProvider is required for all Unblind hooks to work.
360
+ * It sets up both the QueryClientProvider (for React Query) and the Unblind configuration context.
361
+ * This is a convenience wrapper around UnblindClientProvider and UnblindScope.
362
+ *
363
+ * @example
364
+ * ```tsx
365
+ * import { UnblindProvider } from '@unblind/react';
366
+ *
367
+ * function App() {
368
+ * return (
369
+ * <UnblindProvider apiBaseUrl="/api/unblind">
370
+ * <YourComponents />
371
+ * </UnblindProvider>
372
+ * );
373
+ * }
374
+ * ```
375
+ */
376
+ declare function UnblindProvider({ children, queryClient, apiBaseUrl, fetchImpl, timeRange, startTime, endTime, interval, attributes, groupBy, operator, appearance, }: UnblindProviderProps): react_jsx_runtime.JSX.Element;
377
+
378
+ interface UseMetricsReturn {
379
+ list: MetricMetadataList | undefined;
380
+ isLoading: boolean;
381
+ hasError: boolean;
382
+ refetch: () => void;
383
+ }
384
+ /**
385
+ * Hook to fetch the list of available metrics metadata.
386
+ *
387
+ * @returns Object containing the metrics list, loading state, error state, and refetch function.
388
+ */
389
+ declare function useMetrics(): UseMetricsReturn;
390
+
391
+ interface UseTimeseriesParams extends Pick<TimeseriesQueryConfig, "timeRange" | "startTime" | "endTime" | "interval"> {
392
+ /**
393
+ * Array of queries to execute.
394
+ */
395
+ queries: Array<TimeseriesQuery>;
396
+ }
397
+ interface UseTimeseriesReturn {
398
+ data: {
399
+ series: Serie[];
400
+ times: number[];
401
+ metadata: Record<string, MetricMetadata>;
402
+ };
403
+ isLoading: boolean;
404
+ isFetching: boolean;
405
+ hasError: boolean;
406
+ refetch: () => void;
407
+ }
408
+ /**
409
+ * Hook to fetch timeseries data for metrics.
410
+ *
411
+ * @param params - Configuration object with queries, and either timeRange or startTime/endTime, plus optional interval.
412
+ * @returns Object containing timeseries data, loading states, and error state.
413
+ */
414
+ declare function useTimeseries({ queries, timeRange, startTime, endTime, interval, }: UseTimeseriesParams): UseTimeseriesReturn;
415
+
416
+ interface Usage {
417
+ date: string;
418
+ metrics: {
419
+ units: number;
420
+ };
421
+ logs: {
422
+ bytes: number;
423
+ units: number;
424
+ };
425
+ }
426
+ type UseUsageParams = TimeConfig;
427
+ interface UseUsageReturn {
428
+ usage: Array<Usage>;
429
+ isLoading: boolean;
430
+ hasError: boolean;
431
+ refetch: () => void;
432
+ }
433
+ /**
434
+ * Hook to fetch usage data.
435
+ *
436
+ * @param params - Configuration object with optional timeRange.
437
+ * @returns Object containing usage data, loading state, and error state.
438
+ */
439
+ declare function useUsage({ timeRange, startTime, endTime, }: UseUsageParams): UseUsageReturn;
440
+
441
+ type UseLogsParams = {
442
+ /**
443
+ * Array of filters to apply to the logs query.
444
+ */
445
+ filters: Array<AttributeWithValue>;
446
+ } & TimeConfig;
447
+ interface UseLogsReturn {
448
+ logs: Array<Log>;
449
+ isLoading: boolean;
450
+ hasError: boolean;
451
+ hasNextPage: boolean;
452
+ fetchNextPage: () => void;
453
+ isFetchingNextPage: boolean;
454
+ refetch: () => void;
455
+ }
456
+ /**
457
+ * Hook to fetch logs data with infinite scroll pagination.
458
+ *
459
+ * @param params - Configuration object with timeRange and filters.
460
+ * @returns Object containing logs data, loading states, and pagination controls.
461
+ */
462
+ declare function useLogs({ timeRange, filters, startTime, endTime, }: UseLogsParams): UseLogsReturn;
463
+
464
+ declare function useTheme(): boolean;
465
+
466
+ type TimeseriesChartProps = TimeseriesProps & {
467
+ /**
468
+ * Chart type. Defaults to "line".
469
+ */
470
+ type?: ChartType;
471
+ /**
472
+ * Optional className for the chart container.
473
+ */
474
+ className?: string;
475
+ /**
476
+ * Optional appearance configuration for this chart
477
+ */
478
+ appearance?: Appearance;
479
+ };
480
+ /**
481
+ * TimeseriesChart component that displays time series data for the given metrics.
482
+ * It uses values from the UnblindProvider for timeRange, attributes, groupBy, and operator
483
+ * if not explicitly provided as props.
484
+ *
485
+ * @example Using [UnblindProvider]
486
+ * ```tsx
487
+ * <UnblindProvider timeRange="1h">
488
+ * <TimeseriesChart metrics={["host.cpu"]} />
489
+ * <TimeseriesChart metrics={["host.memory"]} />
490
+ * </UnblindProvider>
491
+ * ```
492
+ *
493
+ * @example Using <UnblindScope>
494
+ * ```tsx
495
+ * <UnblindScope timeRange="1h">
496
+ * <TimeseriesChart metrics={["host.cpu"]} />
497
+ * <TimeseriesChart metrics={["host.memory"]} />
498
+ * </UnblindScope>
499
+ * ```
500
+ */
501
+ declare function TimeseriesChart({ metrics, operator: propOperator, attributes: propAttributes, groupBy: propGroupBy, timeRange: propTimeRange, startTime: propStartTime, endTime: propEndTime, interval: propInterval, type, className, appearance: propAppearance, }: TimeseriesChartProps): react_jsx_runtime.JSX.Element;
502
+
503
+ interface ChartProps extends ChartVisualConfig {
504
+ times: Array<number>;
505
+ series: Serie[];
506
+ metadata: Record<string, MetricMetadata>;
507
+ type: "bar" | "line" | "area" | "step";
508
+ className?: string;
509
+ timeZone?: string;
510
+ options?: uPlot.Options;
511
+ tooltipAppearance?: React.ComponentType<TooltipProps>;
512
+ }
513
+ /**
514
+ * Renders a chart for time series data
515
+ */
516
+ declare function Chart(props: ChartProps): react_jsx_runtime.JSX.Element;
517
+
518
+ declare function Divider({ className, ...props }: React$1.ComponentPropsWithoutRef<"hr">): react_jsx_runtime.JSX.Element;
519
+
520
+ export { type AggregationOperator, type Appearance, type AttributeWithValue, Chart, type ChartProps, type ChartType, type ChartVisualConfig, type Colors, Divider, type Interval, type Log, type MetricMetadata, type MetricMetadataList, type MetricType, type PaginatedResponse, type Serie, type Severity, type TimeConfig, type TimeRange, TimeseriesChart, type TimeseriesChartProps, type TimeseriesProps, type TimeseriesQuery, type TimeseriesQueryConfig, type TooltipProps, type UnblindClientConfig, UnblindClientProvider, type UnblindClientProviderProps, UnblindProvider, type UnblindProviderProps, UnblindScope, type UnblindScopeConfig, type UnblindScopeProps, type Usage, type UseLogsParams, type UseLogsReturn, type UseMetricsReturn, type UseScopeReturn, type UseTimeseriesParams, type UseTimeseriesReturn, type UseUsageParams, type UseUsageReturn, useLogs, useMetrics, useRefresh, useScope, useTheme, useTimeseries, useUnblindClientConfig, useUsage };
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";var We=Object.create;var K=Object.defineProperty;var Ke=Object.getOwnPropertyDescriptor;var Ye=Object.getOwnPropertyNames;var Xe=Object.getPrototypeOf,Je=Object.prototype.hasOwnProperty;var Ze=(e,t)=>{for(var r in t)K(e,r,{get:t[r],enumerable:!0})},ge=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of Ye(t))!Je.call(e,o)&&o!==r&&K(e,o,{get:()=>t[o],enumerable:!(i=Ke(t,o))||i.enumerable});return e};var Y=(e,t,r)=>(r=e!=null?We(Xe(e)):{},ge(t||!e||!e.__esModule?K(r,"default",{value:e,enumerable:!0}):r,e)),et=e=>ge(K({},"__esModule",{value:!0}),e);var Ut={};Ze(Ut,{Chart:()=>ie,Divider:()=>re,TimeseriesChart:()=>$e,UnblindClientProvider:()=>X,UnblindProvider:()=>be,UnblindScope:()=>J,useLogs:()=>Se,useMetrics:()=>we,useRefresh:()=>se,useScope:()=>j,useTheme:()=>te,useTimeseries:()=>Z,useUnblindClientConfig:()=>S,useUsage:()=>Ce});module.exports=et(Ut);var B=require("@tanstack/react-query"),L=require("react"),ae=require("react/jsx-runtime"),he=(0,L.createContext)(void 0);function X({children:e,queryClient:t,queryClientConfig:r,apiBaseUrl:i="/api/unblind",fetchImpl:o}){let s=(0,L.useMemo)(()=>{if(t)return t;let n={refetchOnWindowFocus:!1,refetchOnReconnect:!1,refetchOnMount:!1},l={defaultOptions:{queries:n}};return r?new B.QueryClient({...r,defaultOptions:{...r.defaultOptions,queries:{...n,...r.defaultOptions?.queries}}}):new B.QueryClient(l)},[t,r]),a=(0,L.useMemo)(()=>({apiBaseUrl:i,fetchImpl:o}),[i,o]);return(0,ae.jsx)(B.QueryClientProvider,{client:s,children:(0,ae.jsx)(he.Provider,{value:a,children:e})})}function S(){let e=(0,L.useContext)(he);if(!e)throw new Error("useUnblindConfig must be used within an UnblindClientProvider. Please wrap your app or component tree with <UnblindClientProvider>.");return e}function se(){let e=(0,B.useQueryClient)();return(0,L.useCallback)(async()=>{await e.refetchQueries({queryKey:["unblind","timeseries"]})},[e])}var A=require("react"),E=require("react/jsx-runtime"),le=(0,A.createContext)(void 0);function J({children:e,timeRange:t,startTime:r,endTime:i,interval:o,attributes:s,groupBy:a,operator:n,appearance:l}){let c=(0,A.useContext)(le),p=l?.components?.Loading,u=l?.components?.Error,m=l?.components?.Tooltip,d=(0,A.useMemo)(()=>{if(!(!p&&!u&&!m))return{components:{...p&&{Loading:p},...u&&{Error:u},...m&&{Tooltip:m}}}},[p,u,m]),h=(0,A.useMemo)(()=>({timeRange:t??c?.timeRange,startTime:r??c?.startTime,endTime:i??c?.endTime,interval:o??c?.interval,attributes:s??c?.attributes,groupBy:a??c?.groupBy,operator:n??c?.operator,appearance:d??c?.appearance}),[t,r,i,o,s,a,n,d,c]);return(0,E.jsx)(le.Provider,{value:h,children:e})}var tt=()=>(0,E.jsx)("div",{className:"flex h-full items-center justify-center text-sm text-gray-500",children:"Loading data..."}),rt=({error:e})=>(0,E.jsx)("div",{className:"flex h-full items-center justify-center text-sm text-red-500",children:e?.message??"Something went wrong"}),ot=()=>(0,E.jsx)("div",{className:"flex h-full items-center justify-center",children:(0,E.jsxs)("div",{className:"text-center",children:[(0,E.jsx)("div",{className:"mx-auto flex h-10 w-10 items-center justify-center rounded-full bg-gray-100 dark:bg-zinc-800",children:(0,E.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",strokeWidth:1.5,stroke:"currentColor",className:"size-5 text-gray-400 dark:text-gray-500",children:(0,E.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",d:"M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z"})})}),(0,E.jsx)("p",{className:"mt-2 text-sm text-gray-500 dark:text-gray-400",children:"No data available for this time range"})]})}),it=["#7c3aed","#eab308","#2563eb","#dc2626","#16a34a","#f97316","#0891b2","#9333ea","#ca8a04","#4f46e5","#0d9488","#be185d"],nt="6h";function j(){let e=(0,A.useContext)(le);return{timeRange:e?.timeRange||nt,startTime:e?.startTime,endTime:e?.endTime,interval:e?.interval,attributes:e?.attributes,groupBy:e?.groupBy,operator:e?.operator,appearance:{components:{Loading:e?.appearance?.components?.Loading??tt,Error:e?.appearance?.components?.Error??rt,Empty:e?.appearance?.components?.Empty??ot,Tooltip:e?.appearance?.components?.Tooltip},colors:e?.appearance?.colors||it}}}var ce=require("react/jsx-runtime");function be({children:e,queryClient:t,apiBaseUrl:r,fetchImpl:i,timeRange:o,startTime:s,endTime:a,interval:n,attributes:l,groupBy:c,operator:p,appearance:u}){return(0,ce.jsx)(X,{queryClient:t,apiBaseUrl:r,fetchImpl:i,children:(0,ce.jsx)(J,{timeRange:o,startTime:s,endTime:a,interval:n,attributes:l,groupBy:c,operator:p,appearance:u,children:e})})}var ye=require("@tanstack/react-query");function we(){let{apiBaseUrl:e,fetchImpl:t=fetch}=S(),r=(0,ye.useQuery)({queryKey:["unblind","metrics"],queryFn:async()=>{let i=await t(`${e}/metrics`,{headers:{"Content-Type":"application/json"}});if(!i.ok)throw new Error("Error loading metrics metadata");if(i.status===200){let{data:o}=await i.json();return o}else throw new Error("Unexpected status code")}});return{list:r.data,isLoading:r.isLoading,hasError:r.isError,refetch:r.refetch}}var ve=require("@tanstack/react-query"),q=require("react");var xe=Y(require("ms"));function at(e){let t=Date.now();return[t-(0,xe.default)(e),t]}function H(e,t,r){let i,o;if(typeof t=="number"&&typeof r=="number")i=t,o=r;else if(e){let[s,a]=at(e);i=s,o=a}else throw new Error("Either timeRange or both startTime and endTime must be provided");return[i,o]}function Z({queries:e,timeRange:t,startTime:r,endTime:i,interval:o}){let{apiBaseUrl:s,fetchImpl:a=fetch}=S(),n=(0,q.useMemo)(()=>e.map(b=>b.metrics.join(",")).join(","),[e]),l=(0,q.useMemo)(()=>e.map(b=>{let T=b.attributes;if(!T)return"";let y=Object.keys(T);return y.length===0?"":y.map(x=>x+":"+T[x]?.join(",")).join(",")}).join(","),[e]),c=(0,q.useMemo)(()=>e.map(b=>b.operator),[e]),p=(0,q.useMemo)(()=>e.map(b=>b.groupBy).join(", "),[e]),m=(0,ve.useQuery)({queryKey:["unblind","timeseries",n,l,r,i,t,o,c,p],queryFn:async()=>{if(!n)throw new Error("Missing required parameters");if(n.length===0)throw new Error("No series provided");let[b,T]=H(t,r,i),y={queries:e,startTime:b,endTime:T,interval:o},x=await a(`${s}/tenants/timeseries`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(y)});if(!x.ok)throw new Error("Error fetching metric");let{series:C,times:P,metadata:R}=await x.json();if(!C)throw console.error("Series not found"),new Error("Series not found");return{series:C,times:P,metadata:R}},enabled:!!n&&(typeof r=="number"&&typeof i=="number"||!!t)}),{metadata:d,series:h,times:k}=(0,q.useMemo)(()=>m.data?{series:m.data.series,times:m.data.times,metadata:m.data.metadata}:{series:[],times:[],metadata:{}},[m]),w=m.isLoading,f=m.isFetching,g=m.isError;return{data:{series:h,times:k,metadata:d},isLoading:w,isFetching:f,hasError:g,refetch:m.refetch}}var ke=require("@tanstack/react-query"),Te=require("react");function Ce({timeRange:e,startTime:t,endTime:r}){let{apiBaseUrl:i,fetchImpl:o=fetch}=S(),a=(0,ke.useQuery)({queryKey:["unblind","usage",e,t,r],queryFn:async()=>{let[p,u]=H(e,t,r),m=`${i}/tenants/usage`,d=await o(m,{headers:{"Content-Type":"application/json"},body:JSON.stringify({startTime:p,endTime:u})});if(!d.ok)throw new Error("Error fetching usage");let{data:h}=await d.json();if(!h)throw new Error("usage not found");return h},enabled:typeof t=="number"&&typeof r=="number"||!!e}),n=(0,Te.useMemo)(()=>a.data?a.data||[]:[],[a]),l=a.isLoading||a.isRefetching,c=a.isError;return{usage:n,isLoading:l,hasError:c,refetch:a.refetch}}var Pe=require("@tanstack/react-query"),Ue=require("react");function Se({timeRange:e,filters:t,startTime:r,endTime:i}){let{apiBaseUrl:o,fetchImpl:s=fetch}=S(),a=typeof r=="number"&&typeof i=="number"||!!e,n=(0,Pe.useInfiniteQuery)({queryKey:["unblind","logs",e,t.map(c=>c.name+":"+c.value).sort().join(",")],queryFn:async({pageParam:c})=>{let p=t.reduce((C,P)=>(C[P.name]||(C[P.name]=[]),C[P.name].push(P.value),C),{}),{body:u=[],severity:m=[],"service.name":d=[],"trace.id":h=[],"span.id":k=[],...w}=p,[f,g]=H(e,r,i),b=Date.now(),T=await s(`${o}/tenants/logs`,{method:"POST",body:JSON.stringify({filter:{attributes:w,body:u,severity:m,traceId:h,spanId:k,service:d},startTime:f,endTime:g,pagination:{page:c}}),headers:{"Content-Type":"application/json"}});if(!T.ok)throw new Error("Error fetching logs");let{data:y,next_page:x}=await T.json();if(!y)throw new Error("logs not found");return{data:y,next_page:x}},enabled:a,initialPageParam:void 0,getNextPageParam:c=>c.next_page});return{logs:(0,Ue.useMemo)(()=>n.data?n.data.pages.flatMap(c=>c.data||[]):[],[n.data]),isLoading:n.isLoading,hasError:n.isError,hasNextPage:n.hasNextPage??!1,fetchNextPage:n.fetchNextPage,isFetchingNextPage:n.isFetchingNextPage,refetch:n.refetch}}var ee=require("react");function te(){let[e,t]=(0,ee.useState)(!1);return(0,ee.useEffect)(()=>{let r=()=>t(document.documentElement.classList.contains("dark"));return r(),window.addEventListener("storage",r),window.addEventListener("theme-change",r),()=>{window.removeEventListener("storage",r),window.removeEventListener("theme-change",r)}},[]),e}var oe=require("react"),Ge=Y(require("uplot"));var W=Y(require("uplot")),je=require("@grafana/data");var N=require("@grafana/data");var U={millisecond:1,second:1e3,minute:6e4,hour:36e5,day:864e5,month:24192e5,year:31536e6},_={second:[1,2,5,10,15,30],minute:[1,2,5,10,15,30],hour:[1,2,3,4,6,8,12],day:[1,2,3,7,14],month:[1,2,3,6],year:[1,2,5,10,20,50,100]};function st(e,t,r,i){if(t>U.day){let o=N.systemDateFormats.interval.year,s=Math.round(U.year/U.day)*U.day;return Math.round(t/U.day)*U.day===s?o=N.systemDateFormats.interval.year:t<=U.year?o=N.systemDateFormats.interval.month:o=N.systemDateFormats.interval.day,e.map(n=>(0,N.dateTimeFormat)(n,{format:o,timeZone:i}))}return e.map(o=>{let s=new Date(o),a=t<U.minute,n=t<U.second,l=s.toLocaleTimeString("en-GB",{hour:"2-digit",minute:"2-digit",hour12:!1,timeZone:i});return(l==="00:00"||l==="24:00")&&!a&&!n?s.toLocaleDateString(void 0,{day:"2-digit",month:"short",timeZone:i}):s.toLocaleTimeString(void 0,{hour:"2-digit",minute:"2-digit",second:a?"2-digit":void 0,fractionalSecondDigits:n?3:void 0,hour12:!1,timeZone:i})})}function Me(e){let t=[{size:U.second/1e3,increments:_.second},{size:U.minute/1e3,increments:_.minute},{size:U.hour/1e3,increments:_.hour},{size:U.day/1e3,increments:_.day},{size:U.month/1e3,increments:_.month},{size:U.year/1e3,increments:_.year}];for(let o of t)for(let s of o.increments){let a=o.size*s;if(a>=e)return{increment:a*1e3,multiplier:s}}let r=t[t.length-1],i=r.increments[r.increments.length-1];return{increment:r.size*i*1e3,multiplier:i}}function Ee(e,t,r){return[t,r]}function lt(e,t,r,i){let o=r-t,s=e.width,a=Math.floor(s/100),n=o/a,{increment:l,multiplier:c}=Me(n),p=l/1e3,u=[];if(o<12*3600){let d=Math.ceil(t/p)*p;for(;d<=r;d+=p)u.push(d);return u}if(o<3*86400){if(l>=6*3600*1e3){let h=l/1e3/3600,k=new Date(t*1e3);if(i==="UTC"){let f=k.getUTCHours(),g=Math.floor(f/h)*h;k.setUTCHours(g,0,0,0)}else{let f=k.getHours(),g=Math.floor(f/h)*h;k.setHours(g,0,0,0)}let w=k.getTime()/1e3;for(w<t&&(w+=p);w<=r;)u.push(w),w+=p;return u}let d=Math.ceil(t/p)*p;for(;d<=r;d+=p)u.push(d);return u}if(l>=U.day){let d=new Date(t*1e3);i==="UTC"?(d.setUTCHours(0,0,0,0),d.getTime()/1e3<t&&d.setUTCDate(d.getUTCDate()+c)):(d.setHours(0,0,0,0),d.getTime()/1e3<t&&d.setDate(d.getDate()+c));let h=d.getTime()/1e3;for(;h<=r;)u.push(h),i==="UTC"?d.setUTCDate(d.getUTCDate()+c):d.setDate(d.getDate()+c),h=d.getTime()/1e3;return u}let m=Math.ceil(t/p)*p;for(;m<=r;m+=p)u.push(m);return u}function Re(e,t,r){return t.length===0?[]:t.map((i,o)=>o===0||o===t.length-1?(0,N.dateTimeFormatTimeAgo)(i*1e3,{timeZone:r}):"")}function ct(e,t,r){let i=e.scales.x,o=((i?.max??0)-(i?.min??0))*1e3,s=Math.floor(e.width/100),a=o/1e3/s,{increment:n}=Me(a),l=t.map(c=>c*1e3);return st(l,n,o,r)}function Le(e,t=!1){let r=t?(s,a,n,l)=>Ee(s,n,l):(s,a,n,l)=>lt(s,n,l,e),i=t?(s,a)=>Re(s,a,e):(s,a)=>ct(s,a,e),o=t?(s,a,n,l,c)=>{let u=document.createElement("canvas").getContext("2d");if(!u)return 0;u.font=F;let m=Re(s,Ee(s,n,l),e),d=Math.max(u.measureText(m[0]||"").width,u.measureText(m[1]||"").width);return Math.ceil(d/2)+15}:void 0;return{font:F,labelFont:F,grid:{show:!1,width:.5},ticks:{width:.5},splits:r,values:i,size:20}}var Q=require("@floating-ui/dom"),Ve=Y(require("uplot"));var Ne=require("react-dom/client"),pe=class{overlay=null;reactRoot=null;initialize(){this.overlay||(this.overlay=document.createElement("div"),this.overlay.id="unblind-tooltip-overlay",this.overlay.style.display="none",this.overlay.style.position="fixed",this.overlay.style.pointerEvents="none",this.overlay.style.zIndex="9999",document.body.appendChild(this.overlay),this.reactRoot=(0,Ne.createRoot)(this.overlay))}getOverlay(){return this.overlay}render(t){this.reactRoot&&this.reactRoot.render(t)}show(){this.overlay&&(this.overlay.style.display="block")}hide(){this.overlay&&(this.overlay.style.display="none"),this.render(null)}destroy(){this.reactRoot&&(this.reactRoot.unmount(),this.reactRoot=null),this.overlay&&(this.overlay.remove(),this.overlay=null)}},G=new pe;var de=require("@grafana/data"),Ie=require("react");var ze=require("react/jsx-runtime");function re({className:e="h-px bg-gray-200 border-gray-200 dark:bg-white/15",...t}){return(0,ze.jsx)("hr",{role:"presentation",...t,className:e})}var v=require("react/jsx-runtime");function pt(e){return typeof e.metric=="string"?e.metric:e.metric?.textContent||"Unknown Metric"}function Ae(e){let t=e.attributes||{};if(t["service.name"])return String(t["service.name"]);let i=Object.keys(t)[0];return i?String(t[i]):"z-fallback"}function De(e){return[...e].sort((t,r)=>(Number(r.value)||0)-(Number(t.value)||0))}function dt(e){return[...e].sort((t,r)=>Ae(t).localeCompare(Ae(r)))}function ut(e){let t={};return e.forEach(r=>{let i=pt(r);t[i]||(t[i]=[]),t[i].push(r)}),t}function mt(e,t){let r=ut(e);return Object.keys(r).sort((o,s)=>o.localeCompare(s)).map(o=>{let s=r[o];if(!s)return{metricName:o,items:[]};let a=t?De(s):dt(s);return{metricName:o,items:a}})}function ft({item:e,groupIdx:t,idx:r}){let i=e.attributes||{},o=Object.entries(i),s=typeof e.metric=="string"?e.metric:e.metric?.textContent||"Unknown",a=o,n=o.find(([l])=>l==="service.name");return n?(s=String(n[1]),a=o.filter(([l])=>l!=="service.name")):o.length>0&&o[0]&&(s=`${o[0][0]}: ${o[0][1]}`,a=o.slice(1)),(0,v.jsxs)("div",{className:"group flex flex-col px-3 py-1 hover:bg-slate-50 dark:hover:bg-white/5 transition-colors",children:[(0,v.jsxs)("div",{className:"flex items-center justify-between gap-4",children:[(0,v.jsxs)("div",{className:"flex items-center gap-2.5 min-w-0 overflow-hidden",children:[(0,v.jsx)("span",{className:"size-2 mt-0.5 shrink-0 rounded-full shadow-sm ring-1 ring-black/5 dark:ring-white/10",style:{backgroundColor:e.color}}),(0,v.jsx)("span",{className:"truncate font-medium text-slate-600 dark:text-slate-300",title:s,children:s})]}),(0,v.jsx)("div",{className:"font-semibold tabular-nums text-slate-900 dark:text-white whitespace-nowrap",children:e.formattedValue??(0,v.jsx)("span",{className:"font-normal text-slate-400",children:"\u2014"})})]}),a.length>0&&(0,v.jsx)("div",{className:"mt-0.5 flex flex-wrap gap-x-3 gap-y-0.5 pl-4.5 text-xs text-slate-500 dark:text-slate-400",children:a.map(([l,c])=>(0,v.jsxs)("span",{className:"flex items-center gap-1",children:[(0,v.jsxs)("span",{className:"opacity-70",children:[l,":"]}),(0,v.jsx)("span",{className:"font-medium text-slate-600 dark:text-slate-300",children:String(c)})]},l))})]},`item-${t}-${r}`)}function gt({group:e,groupIdx:t,hasAttributes:r}){return(0,v.jsxs)("div",{className:"flex flex-col",children:[r&&(0,v.jsx)("div",{className:`sticky top-0 z-10 bg-white/95 dark:bg-zinc-900/95 backdrop-blur-sm px-3 py-1.5 font-semibold text-slate-900 dark:text-white ${t>0?"mt-2 border-t border-gray-100 dark:border-white/5 pt-3":""}`,children:e.metricName}),(0,v.jsx)("div",{className:"flex flex-col gap-1",children:e.items.map((i,o)=>(0,v.jsx)(ft,{item:i,groupIdx:t,idx:o},`item-${t}-${o}`))})]},e.metricName)}function Oe({timestamp:e,items:t,timeZone:r,spansMultipleDays:i,orderByValues:o,hasAttributes:s}){let a=i?(0,de.dateTimeFormat)(e*1e3,{format:"MMM DD, HH:mm:ss",timeZone:r}):(0,de.dateTimeFormat)(e*1e3,{format:"HH:mm:ss",timeZone:r}),n=(0,Ie.useMemo)(()=>{let l=mt(t,o);if(!s&&o&&l.length>0){let c=l.flatMap(m=>m.items),p=De(c);return[{metricName:l[0]?.metricName||"Metrics",items:p}]}return l},[t,o,s]);return(0,v.jsxs)("div",{style:{fontSize:"13px"},className:"flex w-[320px] flex-col gap-1 text-sm rounded-lg text-slate-900 dark:text-slate-200 border border-gray-200/80 bg-white shadow-xl ring-1 ring-gray-200/40 dark:ring-zinc-800/40 dark:border-white/10 dark:bg-zinc-900",children:[(0,v.jsx)("div",{className:"flex items-center justify-between px-3 pt-2.5 font-medium text-slate-700 dark:text-slate-100",children:a}),(0,v.jsx)(re,{className:"my-1 border-gray-100 dark:border-white/5"}),n.length>0?(0,v.jsx)("div",{className:"flex flex-col pb-2",children:n.map((l,c)=>(0,v.jsx)(gt,{group:l,groupIdx:c,hasAttributes:s},l.metricName))}):(0,v.jsx)("div",{className:"px-3 pb-3 italic text-zinc-400 text-xs",children:"No data available"})]})}var ue=require("react/jsx-runtime"),ht=4,bt=8;function yt(e,t){if(!e||e.length===0)return!1;let r=e[0],i=e[e.length-1];if(r==null||i==null)return!1;let o=new Date(r*1e3),s=new Date(i*1e3),a=n=>t==="UTC"?`${n.getUTCFullYear()}-${n.getUTCMonth()}-${n.getUTCDate()}`:n.toLocaleDateString(void 0,{timeZone:t});return a(o)!==a(s)}function wt(e,t){let r=!1;for(let o=1;o<e.series.length;o++)if(e.data[o]?.[t]!=null){r=!0;break}if(r)return t;let i=e.data[0].length;for(let o=1;t+o<i||t-o>=0;o++){let s=t-o,a=t+o;if(s>=0){for(let n=1;n<e.series.length;n++)if(e.data[n]?.[s]!=null)return s}if(a<i){for(let n=1;n<e.series.length;n++)if(e.data[n]?.[a]!=null)return a}}return t}function xt(e,t,r,i,o){let s=!1,a=[];for(let n=1;n<e.series.length;n++){let l=e.data[n]?.[t]??null;if(i&&l!=null&&n>1){let k=e.data[n-1]?.[t]??0;l=l-k}let c=e.series[n],p=o?.[n-1],u=c?.label??`Series ${n}`,m=c?.stroke,d=typeof m=="function"?m(Ve.default,n):m??"#ffffff00",h=l==null?void 0:r?r(l):String(l);p?.attributes&&Object.keys(p?.attributes).length>0&&(s=!0),a.push({metric:u,color:d,value:l===null?void 0:l,formattedValue:h,attributes:p?.attributes})}return{items:a,hasAttributes:s}}async function vt(e,t){let{x:r,y:i}=await(0,Q.computePosition)({getBoundingClientRect:()=>({x:t.left,y:t.top,width:0,height:0,top:t.top,left:t.left,right:t.left,bottom:t.top})},e,{placement:"top-start",strategy:"fixed",middleware:[(0,Q.offset)({mainAxis:ht,crossAxis:bt}),(0,Q.flip)()]});e.style.left=`${r}px`,e.style.top=`${i}px`}function Be(e,t,r,i,o,s){let a,n,l,c=!1;function p(){let d=a.getBoundingClientRect();n=d.left,l=d.top}function u(){G.hide()}function m(){G.show()}return{hooks:{init:d=>{G.initialize(),a=d.over,window.addEventListener("scroll",p,!0),window.addEventListener("resize",p),a.onmouseenter=()=>{c=!0,m()},a.onmouseleave=()=>{c=!1,u()},p()},setSize:()=>{p()},setCursor:d=>{let{left:h,top:k,idx:w}=d.cursor;if(!c||w==null){u();return}let g=d.data[0],b=yt(g,r),T=wt(d,w),y=d.data[0][T];if(y===void 0)return;let{items:x,hasAttributes:C}=xt(d,T,e,t,o),P={left:(h||0)+n,top:(k||0)+l};m();let R=i,D=R?(0,ue.jsx)(R,{timestamp:y,items:x,timeZone:r}):(0,ue.jsx)(Oe,{timestamp:y,items:x,timeZone:r,spansMultipleDays:b,stacked:t,hasAttributes:C,orderByValues:s});G.render(D);let O=G.getOverlay();O&&vt(O,P)},destroy(){window.removeEventListener("scroll",p,!0),window.removeEventListener("resize",p)}}}}var F='11px "Inter", sans-serif';var Fe=(e,t)=>{let r=e;return t&&t.unit&&t.unit.code&&t.unit.code!=="1"&&(!r&&t.unit?r=t.unit.code:r&&t.unit.code!==r&&(r=void 0)),r},me=(e,t,r)=>Array.isArray(r)?r[t]:r(e,t),kt=e=>{let t=W.default.paths.bars({size:[.6,100],radius:0,gap:0}),r=W.default.paths.linear({alignGaps:0}),i=W.default.paths.spline({alignGaps:1}),o=W.default.paths.stepped({alignGaps:1});switch(e){case"line":return r;case"bar":return t;case"area":return r;case"step":return o;case"spline":return i;default:return r}},Tt=(e,t,r,i)=>{switch(i){case"area":return me(e,t,r);case"bar":return me(e,t,r);default:return}},Ct=e=>{switch(e){case"bar":return 1;case"line":return 2;case"area":return 2;case"step":return 1.5;default:return 1}},He=(e,t,r,i,o,s,a,n,l,c,p)=>{let u=e?.clientWidth??1050,m=e?.clientHeight??250,d=typeof t=="string"?String(t).toLowerCase().replaceAll("by","bytes"):t,h=(0,je.getValueFormat)(d==="1"?null:d),k=Ct(i),w={width:u,height:m,scales:{y:{range:{min:{mode:1,soft:0},max:{pad:2}}}},plugins:[Be(f=>{let g=h(f,2);return g.text+(g.suffix?.trim()||"")},o,n,l,r,p)],padding:c?[10,15,10,15]:[8,15,8,15],cursor:{y:!1,sync:{key:"_"},drag:{setScale:!0,x:!0,y:!1},move:(f,g,b)=>{let T=f.posToVal(g,"x"),y=f.data[0];if(!y||y.length===0)return[g,b];let x=0,C=0,P=y.length-1;for(;P-C>1;){let z=Math.floor((C+P)/2),$=y[z];$!=null&&$<T?C=z:P=z}let R=y[C],D=y[P];R!=null&&D!=null?x=Math.abs(R-T)<Math.abs(D-T)?C:P:R!=null?x=C:D!=null&&(x=P);let O=x;for(let z=x;z>=0;z--){let $=!1;for(let ne=1;ne<f.data.length;ne++){let fe=f.data[ne];if(fe&&fe[z]!=null){$=!0;break}}if($){O=z;break}}let V=y[O];return V==null?[g,b]:[f.valToPos(V,"x"),b]}},series:[{},...r.map((f,g)=>({label:f.metric,stroke:me(f,g,a),width:k,points:{show:!1},spanGaps:!0,paths:kt(i),fill:Tt(f,g,a,i)}))],axes:[Le(n,c),qe(h)],legend:{show:!1}};if(s){let f=w.axes?.[0],g=w.axes?.[1];f&&(f.stroke="#dadada",f.grid&&(f.grid.stroke="#2c3235")),g&&(g.stroke="#dadada",g.grid&&(g.grid.stroke="#2c3235"))}else{let f=w.axes?.[0],g=w.axes?.[1];f&&(f.stroke="#45556c"),g&&(g.stroke="#45556c")}return w};var Pt=(e,t,r,i)=>{let o=e.axes[r];if(i>1)return o?._size;let s=(o?.ticks?.size||0)+(o?.gap||0),a=(t??[]).reduce((n,l)=>l.length>n.length?l:n,"");return a!=""&&(e.ctx.font=o?.font?.[0]??e.ctx.font,s+=e.ctx.measureText(a).width/devicePixelRatio),Math.ceil(s)};function qe(e){return{gap:0,font:F,labelFont:F,grid:{show:!0,width:.5},ticks:{width:.5},values:(t,r)=>r.map(i=>{let o=e(i);return o.text+(o.suffix?.trim()||"")}),size:Pt}}function _e(e,t){let r=[],i=e[0],o=i.length,s=Array(o).fill(0),a=[i];return e.forEach((n,l)=>{l!==0&&(t?a.push(n):a.push(n.map((c,p)=>s[p]=s[p]+(c||0))))}),e.forEach((n,l)=>{l===0||t||r.push({series:[e.findIndex((c,p)=>p>l),l]})}),{data:a,bands:r.filter(n=>n.series[1]>-1)}}var Qe=require("react/jsx-runtime");function ie(e){let{times:t,series:r,metadata:i,type:o,className:s,timeZone:a,options:n,tooltipAppearance:l,colors:c,orderByValues:p}=e,u=(0,oe.useRef)(null),m=te(),d=j(),h=c||d.appearance.colors;return(0,oe.useEffect)(()=>{if(!r||r.length===0){console.warn("No series provided");return}let k=[t],w;r.forEach(x=>{let C=i[x.metric];w=Fe(w,C),k.push(x.values)});let f=o==="bar"||o==="area",g=_e(k,!f),b=u.current,T=He(b,w,r,o,f,m,h,a,l,p),y=null;if(b){T.bands=g.bands,y=new Ge.default({...T,...n},g.data,b);let x=new ResizeObserver(()=>{y?.setSize({width:b.clientWidth,height:b.clientHeight})});return x.observe(b),()=>{y?.destroy(),x.disconnect()}}},[r,t,o,m,i,a,l,h,p]),(0,Qe.jsx)("div",{ref:u,className:s})}var I=require("react/jsx-runtime");function $e({metrics:e,operator:t,attributes:r,groupBy:i,timeRange:o,startTime:s,endTime:a,interval:n,type:l="line",className:c,appearance:p}){let u=j(),m=o??u.timeRange,d=s??u.startTime,h=a??u.endTime,k=n??u.interval,w=r??u.attributes,f=i??u.groupBy,g=t??u.operator,b=p?.colors??u.appearance.colors,T=p?.orderByValues??u.appearance.orderByValues,{isLoading:y,data:x,hasError:C}=Z({queries:e.map(M=>({metrics:[M],operator:g,attributes:w,groupBy:f})),timeRange:m,startTime:d,endTime:h,interval:k}),{series:P,times:R,metadata:D}=x,O=P.every(M=>M.isEmpty),V=c||"h-full w-full";if(y){let M=p?.components?.Loading??u.appearance.components.Loading;return(0,I.jsx)("div",{className:V,children:(0,I.jsx)(M,{})})}if(O){let M=p?.components?.Empty??u.appearance.components.Empty;return(0,I.jsx)("div",{className:V,children:(0,I.jsx)(M,{})})}if(C){let M=p?.components?.Error??u.appearance.components.Error;return(0,I.jsx)("div",{className:V,children:(0,I.jsx)(M,{})})}return(0,I.jsx)(ie,{times:R,series:P,metadata:D,type:l,className:V,tooltipAppearance:p?.components?.Tooltip??u.appearance.components.Tooltip,colors:b,orderByValues:T})}0&&(module.exports={Chart,Divider,TimeseriesChart,UnblindClientProvider,UnblindProvider,UnblindScope,useLogs,useMetrics,useRefresh,useScope,useTheme,useTimeseries,useUnblindClientConfig,useUsage});
2
+ //# sourceMappingURL=index.js.map