@localstack/appinspector-ui 1.0.33 → 1.0.35

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/index.js CHANGED
@@ -1,7 +1,6 @@
1
1
  // src/pages/spans-list-page.tsx
2
- import { Box as Box7 } from "@mui/material";
3
- import { useCallback as useCallback6, useEffect as useEffect4, useMemo as useMemo5, useRef as useRef3, useState as useState5 } from "react";
4
- import { useNavigate } from "react-router-dom";
2
+ import { Box as Box19 } from "@mui/material";
3
+ import { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo7, useRef as useRef4, useState as useState10 } from "react";
5
4
 
6
5
  // src/api/use-api.tsx
7
6
  import { createContext, useContext } from "react";
@@ -3233,167 +3232,8 @@ var StatusMessage = ({
3233
3232
  return /* @__PURE__ */ jsx128(Fragment4, {});
3234
3233
  };
3235
3234
 
3236
- // src/context.tsx
3237
- import { createContext as createContext2, useContext as useContext2 } from "react";
3238
- import { useCallback as useCallback2, useMemo as useMemo3 } from "react";
3239
-
3240
- // src/constants/error-messages.ts
3241
- var ERROR_MESSAGES = {
3242
- APP_INSPECTOR_DISABLED: "App Inspector is currently disabled.",
3243
- APP_INSPECTOR_NOT_FOUND: "App Inspector extension not found. Please ensure App Inspector is licensed and enabled.",
3244
- CONNECTION_FAILED: "Failed to connect to LocalStack. Please ensure LocalStack is running and accessible."
3245
- };
3246
-
3247
- // src/api/client.ts
3248
- var apiLogger = createScopedLogger("API");
3249
- var makeRequest = async (options) => {
3250
- const url = getAppInspectorApiUrl(options.localstackEndpoint, options.endpoint);
3251
- try {
3252
- apiLogger.info("Making request to:", { options, url });
3253
- const headers = new Headers(options.request?.headers);
3254
- headers.set("Content-Type", "application/json");
3255
- const response = await fetch(url, {
3256
- ...options.request,
3257
- headers
3258
- });
3259
- if (!response.ok) {
3260
- if (response.status === 404) {
3261
- throw new AppInspectorNotFoundError(
3262
- ERROR_MESSAGES.APP_INSPECTOR_NOT_FOUND,
3263
- new Error(`404 from ${url}: ${response.statusText}`)
3264
- );
3265
- }
3266
- throw new Error(`API request failed: ${response.status.toString()} ${response.statusText}`);
3267
- }
3268
- return await response.json();
3269
- } catch (error) {
3270
- if (error instanceof TypeError) {
3271
- const message = error.message.toLowerCase();
3272
- const isNetworkError = message.includes("fetch") || message.includes("network") || message.includes("failed to fetch");
3273
- if (isNetworkError) {
3274
- throw new ConnectionError(ERROR_MESSAGES.CONNECTION_FAILED, error);
3275
- }
3276
- }
3277
- if (error instanceof Error) {
3278
- throw error;
3279
- }
3280
- throw new Error("Unknown error occurred");
3281
- }
3282
- };
3283
- var buildSpansEndpoint = (request) => {
3284
- if (!request) {
3285
- return API_ENDPOINTS.SPANS;
3286
- }
3287
- const queryParameters = new URLSearchParams();
3288
- if (request.limit !== void 0) {
3289
- queryParameters.set("limit", request.limit.toString());
3290
- }
3291
- if (request.pagination_token) {
3292
- queryParameters.set("pagination_token", request.pagination_token);
3293
- }
3294
- for (const [key, value] of Object.entries(request)) {
3295
- if (value !== void 0 && key !== "limit" && key !== "pagination_token" && value !== null) {
3296
- queryParameters.set(key, String(value));
3297
- }
3298
- }
3299
- const queryString = queryParameters.toString();
3300
- return queryString ? `${API_ENDPOINTS.SPANS}?${queryString}` : API_ENDPOINTS.SPANS;
3301
- };
3302
- var buildEventsEndpoint = (request) => {
3303
- if (!request) {
3304
- return API_ENDPOINTS.EVENTS;
3305
- }
3306
- const basePath = API_ENDPOINTS.EVENTS;
3307
- const queryParameters = new URLSearchParams();
3308
- if (request.limit !== void 0) {
3309
- queryParameters.set("limit", request.limit.toString());
3310
- }
3311
- if (request.pagination_token) {
3312
- queryParameters.set("pagination_token", request.pagination_token);
3313
- }
3314
- for (const [key, value] of Object.entries(request)) {
3315
- if (value !== void 0 && key !== "limit" && key !== "pagination_token" && value !== null) {
3316
- queryParameters.set(key, String(value));
3317
- }
3318
- }
3319
- const queryString = queryParameters.toString();
3320
- return queryString ? `${basePath}?${queryString}` : basePath;
3321
- };
3322
- var createApiClient = ({ localstackEndpoint }) => {
3323
- return {
3324
- deleteSpans: async (_request) => {
3325
- return makeRequest({
3326
- endpoint: API_ENDPOINTS.SPANS,
3327
- localstackEndpoint,
3328
- request: {
3329
- method: "DELETE"
3330
- }
3331
- });
3332
- },
3333
- getEvents: async (request) => {
3334
- const endpoint = buildEventsEndpoint(request);
3335
- return makeRequest({ endpoint, localstackEndpoint });
3336
- },
3337
- getIamEvents: async (request) => {
3338
- const iamEventsRequest = {
3339
- ...request,
3340
- event_type: "iam.policy_evaluation"
3341
- };
3342
- const endpoint = buildEventsEndpoint(iamEventsRequest);
3343
- return makeRequest({ endpoint, localstackEndpoint });
3344
- },
3345
- getSpans: async (request) => {
3346
- const endpoint = buildSpansEndpoint(request);
3347
- return makeRequest({ endpoint, localstackEndpoint });
3348
- },
3349
- getStatus: async () => {
3350
- return makeRequest({
3351
- endpoint: API_ENDPOINTS.STATUS,
3352
- localstackEndpoint
3353
- });
3354
- }
3355
- };
3356
- };
3357
-
3358
- // src/context.tsx
3359
- import { jsx as jsx129 } from "react/jsx-runtime";
3360
- var AppInspectorContext = createContext2(void 0);
3361
- var useAppInspector = () => {
3362
- const context = useContext2(AppInspectorContext);
3363
- if (!context) {
3364
- throw new Error("@localstack-studio/ui: components must be used within a <AppInspectorContextProvider>");
3365
- }
3366
- return context;
3367
- };
3368
- var AppInspectorContextProvider = (props) => {
3369
- const api = useMemo3(() => {
3370
- return false ? createApiClientMock() : createApiClient({ localstackEndpoint: props.localstackEndpoint });
3371
- }, [props.localstackEndpoint]);
3372
- const resolveLink = useCallback2(
3373
- (options) => {
3374
- if (options.to === "settings") {
3375
- return `${props.routePrefix}/settings`;
3376
- }
3377
- if (options.to === "trace-graph") {
3378
- return `${props.routePrefix}/traces/${options.traceId}`;
3379
- }
3380
- return `${props.routePrefix}/spans`;
3381
- },
3382
- [props.routePrefix]
3383
- );
3384
- const contextValue = useMemo3(
3385
- () => ({
3386
- linkComponent: props.linkComponent,
3387
- localstackEndpoint: props.localstackEndpoint,
3388
- resolveLink
3389
- }),
3390
- [props.linkComponent, props.localstackEndpoint, resolveLink]
3391
- );
3392
- return /* @__PURE__ */ jsx129(ApiProvider, { api, children: /* @__PURE__ */ jsx129(AppInspectorContext.Provider, { value: contextValue, children: props.children }) });
3393
- };
3394
-
3395
3235
  // src/hooks/use-local-storage.tsx
3396
- import { useCallback as useCallback3, useEffect as useEffect2, useState as useState3 } from "react";
3236
+ import { useCallback as useCallback2, useEffect as useEffect2, useState as useState3 } from "react";
3397
3237
  function useLocalStorage(key, initialValue) {
3398
3238
  const [storedValue, setStoredValue] = useState3(() => {
3399
3239
  try {
@@ -3404,7 +3244,7 @@ function useLocalStorage(key, initialValue) {
3404
3244
  return initialValue;
3405
3245
  }
3406
3246
  });
3407
- const setValue = useCallback3((value) => {
3247
+ const setValue = useCallback2((value) => {
3408
3248
  try {
3409
3249
  setStoredValue(value);
3410
3250
  globalThis.localStorage.setItem(key, JSON.stringify(value));
@@ -3435,7 +3275,7 @@ function useLocalStorage(key, initialValue) {
3435
3275
  }
3436
3276
 
3437
3277
  // src/hooks/use-status.tsx
3438
- import { useCallback as useCallback4, useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
3278
+ import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2, useState as useState4 } from "react";
3439
3279
  var useStatus = () => {
3440
3280
  const api = useAppInspectorApi();
3441
3281
  const [checking, setChecking] = useState4(true);
@@ -3443,7 +3283,7 @@ var useStatus = () => {
3443
3283
  const [error, setError] = useState4();
3444
3284
  const hasFetchedReference = useRef2(false);
3445
3285
  const abortControllerReference = useRef2(null);
3446
- const checkStatus = useCallback4(async () => {
3286
+ const checkStatus = useCallback3(async () => {
3447
3287
  if (abortControllerReference.current) {
3448
3288
  abortControllerReference.current.abort();
3449
3289
  }
@@ -3476,191 +3316,16 @@ var useStatus = () => {
3476
3316
  return { checking, checkStatus, error, status };
3477
3317
  };
3478
3318
 
3479
- // src/utils/use-search-param-codec.ts
3480
- import { useCallback as useCallback5, useMemo as useMemo4 } from "react";
3481
- import { useSearchParams } from "react-router-dom";
3482
- var useSearchParamCodec = (key, codec) => {
3483
- const [searchParams, setSearchParams] = useSearchParams();
3484
- const raw = searchParams.get(key) ?? void 0;
3485
- const value = useMemo4(() => {
3486
- return codec.decode(raw);
3487
- }, [raw, codec]);
3488
- const setValue = useCallback5(
3489
- (next) => {
3490
- setSearchParams((previous) => {
3491
- const nextParams = new URLSearchParams(previous);
3492
- nextParams.set(key, codec.encode(next));
3493
- return nextParams;
3494
- });
3495
- },
3496
- [key, codec, setSearchParams]
3497
- );
3498
- return [value, setValue];
3499
- };
3500
-
3501
- // src/pages/spans-list-page.tsx
3502
- import { jsx as jsx130 } from "react/jsx-runtime";
3503
- var spansPerPageOptions = [25, 50, 100];
3504
- var SpansListPage = () => {
3505
- const api = useAppInspectorApi();
3506
- const [spans, setSpans] = useState5();
3507
- const [loading, setLoading] = useState5(false);
3508
- const hasFetched = useRef3(false);
3509
- const [filterWriteOperations, setFilterWriteOperations] = useLocalStorage("filterWriteOperations", true);
3510
- const mapPageToNextCursor = useRef3({});
3511
- const [page, setPage] = useSearchParamCodec("page", {
3512
- decode: (raw) => {
3513
- const defaultPage = 0;
3514
- if (!raw) {
3515
- return defaultPage;
3516
- }
3517
- const parsed = Number.parseInt(raw, 10);
3518
- return Number.isNaN(parsed) || parsed < 0 ? defaultPage : parsed;
3519
- },
3520
- encode: (value) => value.toString()
3521
- });
3522
- const [pageSize, setPageSize] = useSearchParamCodec("pageSize", {
3523
- decode: (raw) => {
3524
- const defaultPageSize = 100;
3525
- if (!raw) {
3526
- return defaultPageSize;
3527
- }
3528
- const parsed = Number.parseInt(raw, 10);
3529
- return spansPerPageOptions.includes(parsed) ? parsed : defaultPageSize;
3530
- },
3531
- encode: (value) => value.toString()
3532
- });
3533
- const [spanCount, setSpanCount] = useState5(0);
3534
- const queryOptions = useMemo5(() => {
3535
- return {
3536
- is_write_operation: filterWriteOperations ? true : void 0,
3537
- limit: pageSize,
3538
- pagination_token: mapPageToNextCursor.current[page - 1]
3539
- };
3540
- }, [filterWriteOperations, pageSize, page]);
3541
- const [fetchError, setFetchError] = useState5();
3542
- const { checkStatus, error: statusError, status } = useStatus();
3543
- const fetchSpans = useCallback6(async () => {
3544
- setLoading(true);
3545
- try {
3546
- const response = await api.getSpans(queryOptions);
3547
- setSpans(response.spans);
3548
- setSpanCount(response.pagination.total_count);
3549
- setFetchError(void 0);
3550
- if (response.pagination.cursor) {
3551
- mapPageToNextCursor.current[page] = response.pagination.cursor;
3552
- }
3553
- } catch (error) {
3554
- console.error(error);
3555
- setFetchError(error instanceof Error ? error : new Error("Unknown error", { cause: error }));
3556
- } finally {
3557
- setLoading(false);
3558
- }
3559
- }, [api, page, queryOptions]);
3560
- const fetchSpansSync = useCallback6(() => {
3561
- void fetchSpans();
3562
- }, [fetchSpans]);
3563
- useEffect4(() => {
3564
- if (hasFetched.current) return;
3565
- if (status?.status !== "ENABLED") return;
3566
- hasFetched.current = true;
3567
- void fetchSpans();
3568
- }, [fetchSpans, status]);
3569
- useEffect4(() => {
3570
- if (!hasFetched.current) return;
3571
- void fetchSpans();
3572
- }, [fetchSpans]);
3573
- const navigate = useNavigate();
3574
- const { resolveLink } = useAppInspector();
3575
- const navigateToSpan = useCallback6((span) => {
3576
- const url = resolveLink({ to: "trace-graph", traceId: span.trace_id });
3577
- const searchParams = new URLSearchParams({
3578
- page: String(page),
3579
- pageSize: String(pageSize),
3580
- spanId: span.span_id
3581
- });
3582
- navigate(`${url}?${searchParams.toString()}`);
3583
- }, [navigate, resolveLink, page, pageSize]);
3584
- const clearSpans = useCallback6(async () => {
3585
- setLoading(true);
3586
- try {
3587
- await api.deleteSpans();
3588
- setSpans([]);
3589
- setFetchError(void 0);
3590
- await fetchSpans();
3591
- } catch (error) {
3592
- console.error("Failed to delete spans:", error);
3593
- setFetchError(error instanceof Error ? error : new Error("Failed to delete spans", { cause: error }));
3594
- } finally {
3595
- setLoading(false);
3596
- }
3597
- }, [api, fetchSpans]);
3598
- const handleRetry = useCallback6(() => {
3599
- void checkStatus();
3600
- }, [checkStatus]);
3601
- const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
3602
- return /* @__PURE__ */ jsx130(
3603
- Box7,
3604
- {
3605
- "data-testid": "spans-list-page",
3606
- sx: {
3607
- alignItems: "center",
3608
- display: "flex",
3609
- flexDirection: "column",
3610
- flexGrow: 1,
3611
- width: "100%"
3612
- },
3613
- children: shouldShowStatusMessage ? /* @__PURE__ */ jsx130(
3614
- StatusMessage,
3615
- {
3616
- error: statusError,
3617
- onRetry: handleRetry,
3618
- status
3619
- }
3620
- ) : /* @__PURE__ */ jsx130(
3621
- SpansList,
3622
- {
3623
- filterWriteOperations,
3624
- onClearSpans: () => {
3625
- void clearSpans();
3626
- },
3627
- onFilterWriteOperationsChange: (value) => {
3628
- setFilterWriteOperations(value);
3629
- },
3630
- onPageChange: setPage,
3631
- onPageSizeChange: setPageSize,
3632
- onRefresh: () => {
3633
- fetchSpansSync();
3634
- },
3635
- onSpanClick: (span) => {
3636
- navigateToSpan(span);
3637
- },
3638
- page,
3639
- pageSize,
3640
- spanCount,
3641
- spans: {
3642
- data: spans,
3643
- error: fetchError,
3644
- loading
3645
- },
3646
- spansPerPageOptions
3647
- }
3648
- )
3649
- }
3650
- );
3651
- };
3652
-
3653
3319
  // src/pages/trace-graph-page.tsx
3654
3320
  import { ArrowBack } from "@mui/icons-material";
3655
- import { Box as Box19, Button as Button5, Drawer, Paper as Paper2 } from "@mui/material";
3321
+ import { Box as Box18, Button as Button5, Drawer, Paper as Paper2 } from "@mui/material";
3656
3322
  import { styled } from "@mui/material/styles";
3657
3323
  import { ReactFlowProvider } from "@xyflow/react";
3658
- import { useCallback as useCallback8, useEffect as useEffect7, useState as useState10 } from "react";
3659
- import { useNavigate as useNavigate2, useParams, useSearchParams as useSearchParams2 } from "react-router-dom";
3324
+ import { useCallback as useCallback4, useEffect as useEffect6, useState as useState9 } from "react";
3660
3325
 
3661
3326
  // src/components/event-details/event-details.tsx
3662
- import { Box as Box15, Chip as Chip3, Divider as Divider2, Stack as Stack2, Typography as Typography9 } from "@mui/material";
3663
- import { useMemo as useMemo8 } from "react";
3327
+ import { Box as Box14, Chip as Chip3, Divider as Divider2, Stack as Stack2, Typography as Typography9 } from "@mui/material";
3328
+ import { useMemo as useMemo5 } from "react";
3664
3329
 
3665
3330
  // src/utils/iam-utils.ts
3666
3331
  function determinePermissionStatus(payload) {
@@ -3858,11 +3523,11 @@ var getEventGroupsByType = (events) => {
3858
3523
 
3859
3524
  // src/components/event-details/event-details-header.tsx
3860
3525
  import { Close } from "@mui/icons-material";
3861
- import { Box as Box8, IconButton, Typography as Typography4 } from "@mui/material";
3862
- import { jsx as jsx131, jsxs as jsxs123 } from "react/jsx-runtime";
3526
+ import { Box as Box7, IconButton, Typography as Typography4 } from "@mui/material";
3527
+ import { jsx as jsx129, jsxs as jsxs123 } from "react/jsx-runtime";
3863
3528
  var EventDetailsHeader = ({ event, onClose }) => {
3864
3529
  return /* @__PURE__ */ jsxs123(
3865
- Box8,
3530
+ Box7,
3866
3531
  {
3867
3532
  sx: {
3868
3533
  alignItems: "center",
@@ -3873,8 +3538,8 @@ var EventDetailsHeader = ({ event, onClose }) => {
3873
3538
  p: 2
3874
3539
  },
3875
3540
  children: [
3876
- /* @__PURE__ */ jsxs123(Box8, { children: [
3877
- /* @__PURE__ */ jsx131(Typography4, { sx: { fontWeight: 600 }, variant: "h6", children: "Event Details" }),
3541
+ /* @__PURE__ */ jsxs123(Box7, { children: [
3542
+ /* @__PURE__ */ jsx129(Typography4, { sx: { fontWeight: 600 }, variant: "h6", children: "Event Details" }),
3878
3543
  /* @__PURE__ */ jsxs123(Typography4, { color: "text.secondary", variant: "body2", children: [
3879
3544
  event.service_name,
3880
3545
  " ",
@@ -3882,50 +3547,50 @@ var EventDetailsHeader = ({ event, onClose }) => {
3882
3547
  event.operation_name
3883
3548
  ] })
3884
3549
  ] }),
3885
- onClose && /* @__PURE__ */ jsx131(IconButton, { onClick: onClose, size: "small", children: /* @__PURE__ */ jsx131(Close, {}) })
3550
+ onClose && /* @__PURE__ */ jsx129(IconButton, { onClick: onClose, size: "small", children: /* @__PURE__ */ jsx129(Close, {}) })
3886
3551
  ]
3887
3552
  }
3888
3553
  );
3889
3554
  };
3890
3555
 
3891
3556
  // src/components/event-details/event-section.tsx
3892
- import { Box as Box14 } from "@mui/material";
3557
+ import { Box as Box13 } from "@mui/material";
3893
3558
 
3894
3559
  // src/components/event-details/event-detail.tsx
3895
3560
  import { KeyboardArrowDown as KeyboardArrowDown2, KeyboardArrowRight as KeyboardArrowRight2 } from "@mui/icons-material";
3896
- import { Box as Box12, Grid as Grid3, IconButton as IconButton3, Typography as Typography7 } from "@mui/material";
3897
- import { useEffect as useEffect5, useMemo as useMemo7, useRef as useRef4, useState as useState7 } from "react";
3561
+ import { Box as Box11, Grid as Grid3, IconButton as IconButton3, Typography as Typography7 } from "@mui/material";
3562
+ import { useEffect as useEffect4, useMemo as useMemo4, useRef as useRef3, useState as useState6 } from "react";
3898
3563
 
3899
3564
  // src/components/status-icon.tsx
3900
3565
  import { Cancel, CheckCircle, Error as Error2, Info, RemoveCircle } from "@mui/icons-material";
3901
- import { Box as Box9 } from "@mui/material";
3902
- import { jsx as jsx132 } from "react/jsx-runtime";
3566
+ import { Box as Box8 } from "@mui/material";
3567
+ import { jsx as jsx130 } from "react/jsx-runtime";
3903
3568
  var StatusIcon = ({ errorLevel }) => {
3904
3569
  switch (errorLevel) {
3905
3570
  case EventLevel.LevelError: {
3906
- return /* @__PURE__ */ jsx132(Cancel, { sx: { color: "red" } });
3571
+ return /* @__PURE__ */ jsx130(Cancel, { sx: { color: "red" } });
3907
3572
  }
3908
3573
  case EventLevel.LevelInfo: {
3909
- return /* @__PURE__ */ jsx132(Info, { sx: { color: "gray" } });
3574
+ return /* @__PURE__ */ jsx130(Info, { sx: { color: "gray" } });
3910
3575
  }
3911
3576
  case EventLevel.LevelPermission: {
3912
- return /* @__PURE__ */ jsx132(RemoveCircle, { sx: { color: "blue" } });
3577
+ return /* @__PURE__ */ jsx130(RemoveCircle, { sx: { color: "blue" } });
3913
3578
  }
3914
3579
  case EventLevel.LevelWarning: {
3915
- return /* @__PURE__ */ jsx132(Error2, { sx: { color: "orange" } });
3580
+ return /* @__PURE__ */ jsx130(Error2, { sx: { color: "orange" } });
3916
3581
  }
3917
3582
  default: {
3918
- return /* @__PURE__ */ jsx132(CheckCircle, { sx: { color: "lightgray" } });
3583
+ return /* @__PURE__ */ jsx130(CheckCircle, { sx: { color: "lightgray" } });
3919
3584
  }
3920
3585
  }
3921
3586
  };
3922
3587
 
3923
3588
  // src/components/event-details/iam-event-detail.tsx
3924
3589
  import { CheckCircle as CheckCircle2, Error as ErrorIcon, Warning } from "@mui/icons-material";
3925
- import { Box as Box10, Chip, Grid as Grid2, Typography as Typography5 } from "@mui/material";
3926
- import { jsx as jsx133, jsxs as jsxs124 } from "react/jsx-runtime";
3590
+ import { Box as Box9, Chip, Grid as Grid2, Typography as Typography5 } from "@mui/material";
3591
+ import { jsx as jsx131, jsxs as jsxs124 } from "react/jsx-runtime";
3927
3592
  var DetailRow = ({ content, label }) => /* @__PURE__ */ jsxs124(Grid2, { container: true, spacing: 0, sx: { mb: 1 }, children: [
3928
- /* @__PURE__ */ jsx133(Grid2, { item: true, sx: { pr: 1 }, xs: 3, children: /* @__PURE__ */ jsx133(
3593
+ /* @__PURE__ */ jsx131(Grid2, { item: true, sx: { pr: 1 }, xs: 3, children: /* @__PURE__ */ jsx131(
3929
3594
  Typography5,
3930
3595
  {
3931
3596
  sx: {
@@ -3936,7 +3601,7 @@ var DetailRow = ({ content, label }) => /* @__PURE__ */ jsxs124(Grid2, { contain
3936
3601
  children: label
3937
3602
  }
3938
3603
  ) }),
3939
- /* @__PURE__ */ jsx133(Grid2, { item: true, xs: 9, children: typeof content === "string" ? /* @__PURE__ */ jsx133(
3604
+ /* @__PURE__ */ jsx131(Grid2, { item: true, xs: 9, children: typeof content === "string" ? /* @__PURE__ */ jsx131(
3940
3605
  Typography5,
3941
3606
  {
3942
3607
  sx: {
@@ -3952,30 +3617,30 @@ var PermissionIcon = ({ status }) => {
3952
3617
  switch (status) {
3953
3618
  case "explicitly_allowed":
3954
3619
  case "implicitly_allowed": {
3955
- return /* @__PURE__ */ jsx133(CheckCircle2, { sx: { color: "success.main", fontSize: "1rem" } });
3620
+ return /* @__PURE__ */ jsx131(CheckCircle2, { sx: { color: "success.main", fontSize: "1rem" } });
3956
3621
  }
3957
3622
  case "explicitly_denied": {
3958
- return /* @__PURE__ */ jsx133(ErrorIcon, { sx: { color: "error.main", fontSize: "1rem" } });
3623
+ return /* @__PURE__ */ jsx131(ErrorIcon, { sx: { color: "error.main", fontSize: "1rem" } });
3959
3624
  }
3960
3625
  case "implicitly_denied": {
3961
- return /* @__PURE__ */ jsx133(Warning, { sx: { color: "warning.main", fontSize: "1rem" } });
3626
+ return /* @__PURE__ */ jsx131(Warning, { sx: { color: "warning.main", fontSize: "1rem" } });
3962
3627
  }
3963
3628
  }
3964
3629
  };
3965
3630
  var IAMEventDetail = ({ event }) => {
3966
3631
  const payloadString = event.attributes?.payload;
3967
3632
  if (!payloadString) {
3968
- return /* @__PURE__ */ jsx133(Box10, { sx: { p: 2 }, children: /* @__PURE__ */ jsx133(Typography5, { sx: { fontWeight: 600 }, variant: "body2", children: "No IAM policy evaluation data available" }) });
3633
+ return /* @__PURE__ */ jsx131(Box9, { sx: { p: 2 }, children: /* @__PURE__ */ jsx131(Typography5, { sx: { fontWeight: 600 }, variant: "body2", children: "No IAM policy evaluation data available" }) });
3969
3634
  }
3970
3635
  const parsedIAM = parseIAMEvent(payloadString);
3971
3636
  if (!parsedIAM) {
3972
- return /* @__PURE__ */ jsx133(Box10, { sx: { p: 2 }, children: /* @__PURE__ */ jsx133(Typography5, { sx: { fontWeight: 600 }, variant: "body2", children: "Failed to parse IAM event data" }) });
3637
+ return /* @__PURE__ */ jsx131(Box9, { sx: { p: 2 }, children: /* @__PURE__ */ jsx131(Typography5, { sx: { fontWeight: 600 }, variant: "body2", children: "Failed to parse IAM event data" }) });
3973
3638
  }
3974
- return /* @__PURE__ */ jsxs124(Box10, { sx: { p: 2 }, children: [
3975
- /* @__PURE__ */ jsx133(Box10, { sx: { mb: 2 }, children: /* @__PURE__ */ jsx133(
3639
+ return /* @__PURE__ */ jsxs124(Box9, { sx: { p: 2 }, children: [
3640
+ /* @__PURE__ */ jsx131(Box9, { sx: { mb: 2 }, children: /* @__PURE__ */ jsx131(
3976
3641
  Chip,
3977
3642
  {
3978
- icon: /* @__PURE__ */ jsx133(PermissionIcon, { status: parsedIAM.permission }),
3643
+ icon: /* @__PURE__ */ jsx131(PermissionIcon, { status: parsedIAM.permission }),
3979
3644
  label: formatPermissionStatus(parsedIAM.permission),
3980
3645
  size: "small",
3981
3646
  sx: {
@@ -3985,12 +3650,12 @@ var IAMEventDetail = ({ event }) => {
3985
3650
  variant: "outlined"
3986
3651
  }
3987
3652
  ) }),
3988
- /* @__PURE__ */ jsx133(DetailRow, { content: `${parsedIAM.service}:${parsedIAM.operation}`, label: "Operation" }),
3989
- /* @__PURE__ */ jsx133(DetailRow, { content: parsedIAM.principal, label: "Principal" }),
3990
- parsedIAM.details.actions && parsedIAM.details.actions.length > 0 && /* @__PURE__ */ jsx133(
3653
+ /* @__PURE__ */ jsx131(DetailRow, { content: `${parsedIAM.service}:${parsedIAM.operation}`, label: "Operation" }),
3654
+ /* @__PURE__ */ jsx131(DetailRow, { content: parsedIAM.principal, label: "Principal" }),
3655
+ parsedIAM.details.actions && parsedIAM.details.actions.length > 0 && /* @__PURE__ */ jsx131(
3991
3656
  DetailRow,
3992
3657
  {
3993
- content: /* @__PURE__ */ jsx133(Box10, { children: parsedIAM.details.actions.map((action) => /* @__PURE__ */ jsx133(
3658
+ content: /* @__PURE__ */ jsx131(Box9, { children: parsedIAM.details.actions.map((action) => /* @__PURE__ */ jsx131(
3994
3659
  Typography5,
3995
3660
  {
3996
3661
  sx: {
@@ -4004,10 +3669,10 @@ var IAMEventDetail = ({ event }) => {
4004
3669
  label: "Actions"
4005
3670
  }
4006
3671
  ),
4007
- parsedIAM.details.resources && parsedIAM.details.resources.length > 0 && /* @__PURE__ */ jsx133(
3672
+ parsedIAM.details.resources && parsedIAM.details.resources.length > 0 && /* @__PURE__ */ jsx131(
4008
3673
  DetailRow,
4009
3674
  {
4010
- content: /* @__PURE__ */ jsx133(Box10, { children: parsedIAM.details.resources.map((resource) => /* @__PURE__ */ jsx133(
3675
+ content: /* @__PURE__ */ jsx131(Box9, { children: parsedIAM.details.resources.map((resource) => /* @__PURE__ */ jsx131(
4011
3676
  Typography5,
4012
3677
  {
4013
3678
  sx: {
@@ -4022,20 +3687,20 @@ var IAMEventDetail = ({ event }) => {
4022
3687
  label: "Resources"
4023
3688
  }
4024
3689
  ),
4025
- /* @__PURE__ */ jsxs124(Box10, { sx: { mt: 2 }, children: [
4026
- /* @__PURE__ */ jsx133(Typography5, { sx: { fontWeight: 600, mb: 1 }, variant: "caption", children: "Policy Evaluation" }),
3690
+ /* @__PURE__ */ jsxs124(Box9, { sx: { mt: 2 }, children: [
3691
+ /* @__PURE__ */ jsx131(Typography5, { sx: { fontWeight: 600, mb: 1 }, variant: "caption", children: "Policy Evaluation" }),
4027
3692
  /* @__PURE__ */ jsxs124(Grid2, { container: true, spacing: 2, children: [
4028
- parsedIAM.details.explicitAllows !== void 0 && /* @__PURE__ */ jsx133(Grid2, { item: true, xs: 4, children: /* @__PURE__ */ jsxs124(Box10, { sx: { textAlign: "center" }, children: [
4029
- /* @__PURE__ */ jsx133(Typography5, { color: "success.main", sx: { fontWeight: "bold" }, variant: "h6", children: parsedIAM.details.explicitAllows }),
4030
- /* @__PURE__ */ jsx133(Typography5, { sx: { fontWeight: 600 }, variant: "caption", children: "Explicit Allows" })
3693
+ parsedIAM.details.explicitAllows !== void 0 && /* @__PURE__ */ jsx131(Grid2, { item: true, xs: 4, children: /* @__PURE__ */ jsxs124(Box9, { sx: { textAlign: "center" }, children: [
3694
+ /* @__PURE__ */ jsx131(Typography5, { color: "success.main", sx: { fontWeight: "bold" }, variant: "h6", children: parsedIAM.details.explicitAllows }),
3695
+ /* @__PURE__ */ jsx131(Typography5, { sx: { fontWeight: 600 }, variant: "caption", children: "Explicit Allows" })
4031
3696
  ] }) }),
4032
- parsedIAM.details.explicitDenies !== void 0 && /* @__PURE__ */ jsx133(Grid2, { item: true, xs: 4, children: /* @__PURE__ */ jsxs124(Box10, { sx: { textAlign: "center" }, children: [
4033
- /* @__PURE__ */ jsx133(Typography5, { color: "error.main", sx: { fontWeight: "bold" }, variant: "h6", children: parsedIAM.details.explicitDenies }),
4034
- /* @__PURE__ */ jsx133(Typography5, { sx: { fontWeight: 600 }, variant: "caption", children: "Explicit Denies" })
3697
+ parsedIAM.details.explicitDenies !== void 0 && /* @__PURE__ */ jsx131(Grid2, { item: true, xs: 4, children: /* @__PURE__ */ jsxs124(Box9, { sx: { textAlign: "center" }, children: [
3698
+ /* @__PURE__ */ jsx131(Typography5, { color: "error.main", sx: { fontWeight: "bold" }, variant: "h6", children: parsedIAM.details.explicitDenies }),
3699
+ /* @__PURE__ */ jsx131(Typography5, { sx: { fontWeight: 600 }, variant: "caption", children: "Explicit Denies" })
4035
3700
  ] }) }),
4036
- parsedIAM.details.implicitDenies !== void 0 && /* @__PURE__ */ jsx133(Grid2, { item: true, xs: 4, children: /* @__PURE__ */ jsxs124(Box10, { sx: { textAlign: "center" }, children: [
4037
- /* @__PURE__ */ jsx133(Typography5, { color: "warning.main", sx: { fontWeight: "bold" }, variant: "h6", children: parsedIAM.details.implicitDenies }),
4038
- /* @__PURE__ */ jsx133(Typography5, { sx: { fontWeight: 600 }, variant: "caption", children: "Implicit Denies" })
3701
+ parsedIAM.details.implicitDenies !== void 0 && /* @__PURE__ */ jsx131(Grid2, { item: true, xs: 4, children: /* @__PURE__ */ jsxs124(Box9, { sx: { textAlign: "center" }, children: [
3702
+ /* @__PURE__ */ jsx131(Typography5, { color: "warning.main", sx: { fontWeight: "bold" }, variant: "h6", children: parsedIAM.details.implicitDenies }),
3703
+ /* @__PURE__ */ jsx131(Typography5, { sx: { fontWeight: 600 }, variant: "caption", children: "Implicit Denies" })
4039
3704
  ] }) })
4040
3705
  ] })
4041
3706
  ] })
@@ -4044,9 +3709,9 @@ var IAMEventDetail = ({ event }) => {
4044
3709
 
4045
3710
  // src/components/event-details/iam-permission-detail.tsx
4046
3711
  import { KeyboardArrowDown, KeyboardArrowRight } from "@mui/icons-material";
4047
- import { Box as Box11, Chip as Chip2, IconButton as IconButton2, Typography as Typography6 } from "@mui/material";
4048
- import { useMemo as useMemo6, useState as useState6 } from "react";
4049
- import { jsx as jsx134, jsxs as jsxs125 } from "react/jsx-runtime";
3712
+ import { Box as Box10, Chip as Chip2, IconButton as IconButton2, Typography as Typography6 } from "@mui/material";
3713
+ import { useMemo as useMemo3, useState as useState5 } from "react";
3714
+ import { jsx as jsx132, jsxs as jsxs125 } from "react/jsx-runtime";
4050
3715
  var getChipColors = (status) => {
4051
3716
  const isAllowed = status === "explicitly_allowed" || status === "implicitly_allowed";
4052
3717
  return {
@@ -4055,8 +3720,8 @@ var getChipColors = (status) => {
4055
3720
  };
4056
3721
  };
4057
3722
  var IAMPermissionItem = ({ event }) => {
4058
- const [isOpen, setIsOpen] = useState6(false);
4059
- const parsedData = useMemo6(() => {
3723
+ const [isOpen, setIsOpen] = useState5(false);
3724
+ const parsedData = useMemo3(() => {
4060
3725
  const payloadString = event.attributes?.payload;
4061
3726
  if (!payloadString) {
4062
3727
  return;
@@ -4074,12 +3739,12 @@ var IAMPermissionItem = ({ event }) => {
4074
3739
  return null;
4075
3740
  }
4076
3741
  const { chipColors, parsedIAM } = parsedData;
4077
- return /* @__PURE__ */ jsxs125(Box11, { sx: { mb: 1 }, children: [
4078
- /* @__PURE__ */ jsxs125(Box11, { sx: { alignItems: "center", display: "flex" }, children: [
4079
- /* @__PURE__ */ jsx134(IconButton2, { onClick: () => {
3742
+ return /* @__PURE__ */ jsxs125(Box10, { sx: { mb: 1 }, children: [
3743
+ /* @__PURE__ */ jsxs125(Box10, { sx: { alignItems: "center", display: "flex" }, children: [
3744
+ /* @__PURE__ */ jsx132(IconButton2, { onClick: () => {
4080
3745
  setIsOpen(!isOpen);
4081
- }, size: "small", sx: { mr: 1, p: 0 }, children: isOpen ? /* @__PURE__ */ jsx134(KeyboardArrowDown, {}) : /* @__PURE__ */ jsx134(KeyboardArrowRight, {}) }),
4082
- /* @__PURE__ */ jsx134(
3746
+ }, size: "small", sx: { mr: 1, p: 0 }, children: isOpen ? /* @__PURE__ */ jsx132(KeyboardArrowDown, {}) : /* @__PURE__ */ jsx132(KeyboardArrowRight, {}) }),
3747
+ /* @__PURE__ */ jsx132(
4083
3748
  Chip2,
4084
3749
  {
4085
3750
  label: formatPermissionStatus(parsedIAM.permission),
@@ -4091,18 +3756,18 @@ var IAMPermissionItem = ({ event }) => {
4091
3756
  }
4092
3757
  )
4093
3758
  ] }),
4094
- isOpen && /* @__PURE__ */ jsx134(Box11, { sx: { ml: 4, mt: 1 }, children: /* @__PURE__ */ jsxs125(Box11, { children: [
4095
- /* @__PURE__ */ jsx134(Typography6, { sx: { fontWeight: 600 }, variant: "caption", children: "Principal" }),
4096
- /* @__PURE__ */ jsx134(Typography6, { variant: "body2", children: parsedIAM.principal })
3759
+ isOpen && /* @__PURE__ */ jsx132(Box10, { sx: { ml: 4, mt: 1 }, children: /* @__PURE__ */ jsxs125(Box10, { children: [
3760
+ /* @__PURE__ */ jsx132(Typography6, { sx: { fontWeight: 600 }, variant: "caption", children: "Principal" }),
3761
+ /* @__PURE__ */ jsx132(Typography6, { variant: "body2", children: parsedIAM.principal })
4097
3762
  ] }) })
4098
3763
  ] });
4099
3764
  };
4100
- var IAMPermissionDetail = ({ events }) => /* @__PURE__ */ jsx134(Box11, { sx: { mt: 2 }, children: events.map((event) => /* @__PURE__ */ jsx134(IAMPermissionItem, { event }, `${event.span_id}-${event.event_id}`)) });
3765
+ var IAMPermissionDetail = ({ events }) => /* @__PURE__ */ jsx132(Box10, { sx: { mt: 2 }, children: events.map((event) => /* @__PURE__ */ jsx132(IAMPermissionItem, { event }, `${event.span_id}-${event.event_id}`)) });
4101
3766
 
4102
3767
  // src/components/event-details/event-detail.tsx
4103
- import { Fragment as Fragment5, jsx as jsx135, jsxs as jsxs126 } from "react/jsx-runtime";
3768
+ import { Fragment as Fragment5, jsx as jsx133, jsxs as jsxs126 } from "react/jsx-runtime";
4104
3769
  var DetailRow2 = ({ content, label }) => /* @__PURE__ */ jsxs126(Grid3, { container: true, spacing: 0, sx: { mb: 1 }, children: [
4105
- /* @__PURE__ */ jsx135(Grid3, { item: true, sx: { pr: 1 }, xs: 3, children: /* @__PURE__ */ jsx135(
3770
+ /* @__PURE__ */ jsx133(Grid3, { item: true, sx: { pr: 1 }, xs: 3, children: /* @__PURE__ */ jsx133(
4106
3771
  Typography7,
4107
3772
  {
4108
3773
  sx: {
@@ -4113,7 +3778,7 @@ var DetailRow2 = ({ content, label }) => /* @__PURE__ */ jsxs126(Grid3, { contai
4113
3778
  children: label
4114
3779
  }
4115
3780
  ) }),
4116
- /* @__PURE__ */ jsx135(Grid3, { item: true, xs: 9, children: typeof content === "string" ? /* @__PURE__ */ jsx135(
3781
+ /* @__PURE__ */ jsx133(Grid3, { item: true, xs: 9, children: typeof content === "string" ? /* @__PURE__ */ jsx133(
4117
3782
  Typography7,
4118
3783
  {
4119
3784
  sx: {
@@ -4126,15 +3791,15 @@ var DetailRow2 = ({ content, label }) => /* @__PURE__ */ jsxs126(Grid3, { contai
4126
3791
  ) : content })
4127
3792
  ] });
4128
3793
  var EventMessage = ({ event }) => {
4129
- const [isOpen, setIsOpen] = useState7(false);
4130
- const [isOverflowing, setIsOverflowing] = useState7(false);
4131
- const textReference = useRef4(null);
4132
- const parsedMessage = useMemo7(() => parseEventMessage(event), [event]);
4133
- const isIAMPolicyEvent = useMemo7(
3794
+ const [isOpen, setIsOpen] = useState6(false);
3795
+ const [isOverflowing, setIsOverflowing] = useState6(false);
3796
+ const textReference = useRef3(null);
3797
+ const parsedMessage = useMemo4(() => parseEventMessage(event), [event]);
3798
+ const isIAMPolicyEvent = useMemo4(
4134
3799
  () => event.event_type === "iam.policy_evaluation" && event.attributes?.payload && typeof event.attributes.payload === "string",
4135
3800
  [event]
4136
3801
  );
4137
- useEffect5(() => {
3802
+ useEffect4(() => {
4138
3803
  const checkOverflow = () => {
4139
3804
  const element = textReference.current;
4140
3805
  if (element) {
@@ -4147,17 +3812,17 @@ var EventMessage = ({ event }) => {
4147
3812
  window.removeEventListener("resize", checkOverflow);
4148
3813
  };
4149
3814
  }, [parsedMessage.headline]);
4150
- const hasAdditionalContent = useMemo7(
3815
+ const hasAdditionalContent = useMemo4(
4151
3816
  () => parsedMessage.message || parsedMessage.details || isIAMPolicyEvent,
4152
3817
  [parsedMessage.message, parsedMessage.details, isIAMPolicyEvent]
4153
3818
  );
4154
- const shouldShowToggle = useMemo7(
3819
+ const shouldShowToggle = useMemo4(
4155
3820
  () => isOverflowing || hasAdditionalContent,
4156
3821
  [isOverflowing, hasAdditionalContent]
4157
3822
  );
4158
- return /* @__PURE__ */ jsxs126(Box12, { sx: { display: "flex", flexDirection: "column" }, children: [
4159
- /* @__PURE__ */ jsxs126(Box12, { sx: { alignItems: "flex-start", display: "flex" }, children: [
4160
- Boolean(shouldShowToggle) && /* @__PURE__ */ jsx135(
3823
+ return /* @__PURE__ */ jsxs126(Box11, { sx: { display: "flex", flexDirection: "column" }, children: [
3824
+ /* @__PURE__ */ jsxs126(Box11, { sx: { alignItems: "flex-start", display: "flex" }, children: [
3825
+ Boolean(shouldShowToggle) && /* @__PURE__ */ jsx133(
4161
3826
  IconButton3,
4162
3827
  {
4163
3828
  onClick: () => {
@@ -4165,10 +3830,10 @@ var EventMessage = ({ event }) => {
4165
3830
  },
4166
3831
  size: "small",
4167
3832
  sx: { mr: 1, mt: -0.5, p: 0 },
4168
- children: isOpen ? /* @__PURE__ */ jsx135(KeyboardArrowDown2, {}) : /* @__PURE__ */ jsx135(KeyboardArrowRight2, {})
3833
+ children: isOpen ? /* @__PURE__ */ jsx133(KeyboardArrowDown2, {}) : /* @__PURE__ */ jsx133(KeyboardArrowRight2, {})
4169
3834
  }
4170
3835
  ),
4171
- /* @__PURE__ */ jsx135(
3836
+ /* @__PURE__ */ jsx133(
4172
3837
  Typography7,
4173
3838
  {
4174
3839
  ref: textReference,
@@ -4186,9 +3851,9 @@ var EventMessage = ({ event }) => {
4186
3851
  }
4187
3852
  )
4188
3853
  ] }),
4189
- isOpen && /* @__PURE__ */ jsx135(Box12, { sx: { ml: 4, mt: 1 }, children: isIAMPolicyEvent ? /* @__PURE__ */ jsx135(IAMEventDetail, { event }) : /* @__PURE__ */ jsxs126(Fragment5, { children: [
4190
- Boolean(parsedMessage.message) && /* @__PURE__ */ jsx135(DetailRow2, { content: parsedMessage.message, label: "Message:" }),
4191
- Boolean(parsedMessage.details) && /* @__PURE__ */ jsx135(DetailRow2, { content: parsedMessage.details, label: "Details:" })
3854
+ isOpen && /* @__PURE__ */ jsx133(Box11, { sx: { ml: 4, mt: 1 }, children: isIAMPolicyEvent ? /* @__PURE__ */ jsx133(IAMEventDetail, { event }) : /* @__PURE__ */ jsxs126(Fragment5, { children: [
3855
+ Boolean(parsedMessage.message) && /* @__PURE__ */ jsx133(DetailRow2, { content: parsedMessage.message, label: "Message:" }),
3856
+ Boolean(parsedMessage.details) && /* @__PURE__ */ jsx133(DetailRow2, { content: parsedMessage.details, label: "Details:" })
4192
3857
  ] }) })
4193
3858
  ] });
4194
3859
  };
@@ -4217,16 +3882,16 @@ var EventDetail = ({
4217
3882
  type
4218
3883
  }) => {
4219
3884
  if (type === "permission") {
4220
- return /* @__PURE__ */ jsxs126(Box12, { children: [
4221
- /* @__PURE__ */ jsx135(
4222
- Box12,
3885
+ return /* @__PURE__ */ jsxs126(Box11, { children: [
3886
+ /* @__PURE__ */ jsx133(
3887
+ Box11,
4223
3888
  {
4224
3889
  sx: {
4225
3890
  alignItems: "left",
4226
3891
  display: "flex",
4227
3892
  mb: 1
4228
3893
  },
4229
- children: /* @__PURE__ */ jsx135(
3894
+ children: /* @__PURE__ */ jsx133(
4230
3895
  Typography7,
4231
3896
  {
4232
3897
  sx: {
@@ -4241,13 +3906,13 @@ var EventDetail = ({
4241
3906
  )
4242
3907
  }
4243
3908
  ),
4244
- /* @__PURE__ */ jsx135(IAMPermissionDetail, { events })
3909
+ /* @__PURE__ */ jsx133(IAMPermissionDetail, { events })
4245
3910
  ] });
4246
3911
  }
4247
3912
  const eventLevel = getEventLevelFromGroup(type);
4248
- return /* @__PURE__ */ jsxs126(Box12, { children: [
3913
+ return /* @__PURE__ */ jsxs126(Box11, { children: [
4249
3914
  /* @__PURE__ */ jsxs126(
4250
- Box12,
3915
+ Box11,
4251
3916
  {
4252
3917
  sx: {
4253
3918
  alignItems: "left",
@@ -4256,8 +3921,8 @@ var EventDetail = ({
4256
3921
  mb: 1
4257
3922
  },
4258
3923
  children: [
4259
- /* @__PURE__ */ jsx135(StatusIcon, { errorLevel: eventLevel }),
4260
- /* @__PURE__ */ jsx135(
3924
+ /* @__PURE__ */ jsx133(StatusIcon, { errorLevel: eventLevel }),
3925
+ /* @__PURE__ */ jsx133(
4261
3926
  Typography7,
4262
3927
  {
4263
3928
  sx: {
@@ -4276,14 +3941,14 @@ var EventDetail = ({
4276
3941
  ]
4277
3942
  }
4278
3943
  ),
4279
- /* @__PURE__ */ jsx135(Box12, { sx: { mt: 2 }, children: events.map((event) => /* @__PURE__ */ jsx135(
4280
- Box12,
3944
+ /* @__PURE__ */ jsx133(Box11, { sx: { mt: 2 }, children: events.map((event) => /* @__PURE__ */ jsx133(
3945
+ Box11,
4281
3946
  {
4282
3947
  sx: {
4283
3948
  maxWidth: "100%",
4284
3949
  mb: 1
4285
3950
  },
4286
- children: /* @__PURE__ */ jsx135(EventMessage, { event })
3951
+ children: /* @__PURE__ */ jsx133(EventMessage, { event })
4287
3952
  },
4288
3953
  `${event.span_id}-${event.event_id}`
4289
3954
  )) })
@@ -4292,14 +3957,14 @@ var EventDetail = ({
4292
3957
 
4293
3958
  // src/components/event-details/toggle-section.tsx
4294
3959
  import { KeyboardArrowDown as KeyboardArrowDown3, KeyboardArrowRight as KeyboardArrowRight3 } from "@mui/icons-material";
4295
- import { Box as Box13, Typography as Typography8 } from "@mui/material";
4296
- import { useState as useState8 } from "react";
4297
- import { jsx as jsx136, jsxs as jsxs127 } from "react/jsx-runtime";
3960
+ import { Box as Box12, Typography as Typography8 } from "@mui/material";
3961
+ import { useState as useState7 } from "react";
3962
+ import { jsx as jsx134, jsxs as jsxs127 } from "react/jsx-runtime";
4298
3963
  var ToggleSection = ({ children, headline, initialOpen = true }) => {
4299
- const [isOpen, setIsOpen] = useState8(initialOpen);
4300
- return /* @__PURE__ */ jsxs127(Box13, { sx: { mt: 4 }, children: [
4301
- /* @__PURE__ */ jsx136(
4302
- Box13,
3964
+ const [isOpen, setIsOpen] = useState7(initialOpen);
3965
+ return /* @__PURE__ */ jsxs127(Box12, { sx: { mt: 4 }, children: [
3966
+ /* @__PURE__ */ jsx134(
3967
+ Box12,
4303
3968
  {
4304
3969
  onClick: () => {
4305
3970
  setIsOpen(!isOpen);
@@ -4309,7 +3974,7 @@ var ToggleSection = ({ children, headline, initialOpen = true }) => {
4309
3974
  mb: 1
4310
3975
  },
4311
3976
  children: /* @__PURE__ */ jsxs127(
4312
- Box13,
3977
+ Box12,
4313
3978
  {
4314
3979
  role: "button",
4315
3980
  sx: {
@@ -4318,24 +3983,24 @@ var ToggleSection = ({ children, headline, initialOpen = true }) => {
4318
3983
  gap: 1
4319
3984
  },
4320
3985
  children: [
4321
- /* @__PURE__ */ jsx136(Typography8, { sx: { fontWeight: 600 }, variant: "subtitle2", children: headline }),
4322
- isOpen ? /* @__PURE__ */ jsx136(KeyboardArrowDown3, { sx: { color: "text.secondary", height: 20, width: 20 } }) : /* @__PURE__ */ jsx136(KeyboardArrowRight3, { sx: { color: "text.secondary", height: 20, width: 20 } })
3986
+ /* @__PURE__ */ jsx134(Typography8, { sx: { fontWeight: 600 }, variant: "subtitle2", children: headline }),
3987
+ isOpen ? /* @__PURE__ */ jsx134(KeyboardArrowDown3, { sx: { color: "text.secondary", height: 20, width: 20 } }) : /* @__PURE__ */ jsx134(KeyboardArrowRight3, { sx: { color: "text.secondary", height: 20, width: 20 } })
4323
3988
  ]
4324
3989
  }
4325
3990
  )
4326
3991
  }
4327
3992
  ),
4328
- isOpen && /* @__PURE__ */ jsx136(Box13, { children })
3993
+ isOpen && /* @__PURE__ */ jsx134(Box12, { children })
4329
3994
  ] });
4330
3995
  };
4331
3996
 
4332
3997
  // src/components/event-details/event-section.tsx
4333
- import { jsx as jsx137, jsxs as jsxs128 } from "react/jsx-runtime";
3998
+ import { jsx as jsx135, jsxs as jsxs128 } from "react/jsx-runtime";
4334
3999
  var EventSection = ({
4335
4000
  eventGroups,
4336
4001
  headline
4337
- }) => /* @__PURE__ */ jsx137(ToggleSection, { headline, children: /* @__PURE__ */ jsxs128(Box14, { children: [
4338
- eventGroups.errors && /* @__PURE__ */ jsx137(
4002
+ }) => /* @__PURE__ */ jsx135(ToggleSection, { headline, children: /* @__PURE__ */ jsxs128(Box13, { children: [
4003
+ eventGroups.errors && /* @__PURE__ */ jsx135(
4339
4004
  EventDetail,
4340
4005
  {
4341
4006
  displayText: "Error",
@@ -4343,7 +4008,7 @@ var EventSection = ({
4343
4008
  type: "error"
4344
4009
  }
4345
4010
  ),
4346
- eventGroups.warnings && /* @__PURE__ */ jsx137(
4011
+ eventGroups.warnings && /* @__PURE__ */ jsx135(
4347
4012
  EventDetail,
4348
4013
  {
4349
4014
  displayText: "Warning",
@@ -4351,7 +4016,7 @@ var EventSection = ({
4351
4016
  type: "warning"
4352
4017
  }
4353
4018
  ),
4354
- eventGroups.permissions && /* @__PURE__ */ jsx137(
4019
+ eventGroups.permissions && /* @__PURE__ */ jsx135(
4355
4020
  EventDetail,
4356
4021
  {
4357
4022
  displayText: "IAM Permission",
@@ -4359,7 +4024,7 @@ var EventSection = ({
4359
4024
  type: "permission"
4360
4025
  }
4361
4026
  ),
4362
- eventGroups.info && /* @__PURE__ */ jsx137(
4027
+ eventGroups.info && /* @__PURE__ */ jsx135(
4363
4028
  EventDetail,
4364
4029
  {
4365
4030
  displayText: "Info",
@@ -4370,55 +4035,55 @@ var EventSection = ({
4370
4035
  ] }) });
4371
4036
 
4372
4037
  // src/components/event-details/event-details.tsx
4373
- import { Fragment as Fragment6, jsx as jsx138, jsxs as jsxs129 } from "react/jsx-runtime";
4038
+ import { Fragment as Fragment6, jsx as jsx136, jsxs as jsxs129 } from "react/jsx-runtime";
4374
4039
  var EventDetails = ({ onClose, selectedEvent }) => {
4375
- const attributes = useMemo8(() => {
4040
+ const attributes = useMemo5(() => {
4376
4041
  const attributes2 = Object.entries(selectedEvent?.attributes ?? {});
4377
4042
  return attributes2.filter(([key]) => key !== "localstack.aws.account_id" && key !== "localstack.aws.service");
4378
4043
  }, [selectedEvent?.attributes]);
4379
4044
  if (!selectedEvent) {
4380
- return /* @__PURE__ */ jsx138(Box15, { sx: { p: 3, textAlign: "center" }, children: /* @__PURE__ */ jsx138(Typography9, { color: "text.secondary", variant: "body2", children: "Select an event to view details" }) });
4045
+ return /* @__PURE__ */ jsx136(Box14, { sx: { p: 3, textAlign: "center" }, children: /* @__PURE__ */ jsx136(Typography9, { color: "text.secondary", variant: "body2", children: "Select an event to view details" }) });
4381
4046
  }
4382
- return /* @__PURE__ */ jsxs129(Box15, { "data-testid": "event-details", sx: { display: "flex", flexDirection: "column", height: "100%" }, children: [
4383
- /* @__PURE__ */ jsx138(EventDetailsHeader, { event: selectedEvent, onClose }),
4384
- /* @__PURE__ */ jsx138(Box15, { sx: { flexGrow: 1, overflow: "auto", p: 2 }, children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 2, children: [
4385
- /* @__PURE__ */ jsx138(ToggleSection, { headline: "Basic Information", children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 1, children: [
4386
- /* @__PURE__ */ jsxs129(Box15, { children: [
4387
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Span ID" }),
4388
- /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: selectedEvent.span_id })
4047
+ return /* @__PURE__ */ jsxs129(Box14, { "data-testid": "event-details", sx: { display: "flex", flexDirection: "column", height: "100%" }, children: [
4048
+ /* @__PURE__ */ jsx136(EventDetailsHeader, { event: selectedEvent, onClose }),
4049
+ /* @__PURE__ */ jsx136(Box14, { sx: { flexGrow: 1, overflow: "auto", p: 2 }, children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 2, children: [
4050
+ /* @__PURE__ */ jsx136(ToggleSection, { headline: "Basic Information", children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 1, children: [
4051
+ /* @__PURE__ */ jsxs129(Box14, { children: [
4052
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Span ID" }),
4053
+ /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: selectedEvent.span_id })
4389
4054
  ] }),
4390
- /* @__PURE__ */ jsxs129(Box15, { children: [
4391
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Trace ID" }),
4392
- /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: selectedEvent.trace_id })
4055
+ /* @__PURE__ */ jsxs129(Box14, { children: [
4056
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Trace ID" }),
4057
+ /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: selectedEvent.trace_id })
4393
4058
  ] }),
4394
- /* @__PURE__ */ jsxs129(Box15, { children: [
4395
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Operation" }),
4396
- /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: selectedEvent.operation_name })
4059
+ /* @__PURE__ */ jsxs129(Box14, { children: [
4060
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Operation" }),
4061
+ /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: selectedEvent.operation_name })
4397
4062
  ] })
4398
4063
  ] }) }),
4399
- /* @__PURE__ */ jsx138(Divider2, {}),
4400
- /* @__PURE__ */ jsx138(ToggleSection, { headline: "Service Information", children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 1, children: [
4401
- /* @__PURE__ */ jsxs129(Box15, { children: [
4402
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Service" }),
4403
- /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: selectedEvent.service_name })
4064
+ /* @__PURE__ */ jsx136(Divider2, {}),
4065
+ /* @__PURE__ */ jsx136(ToggleSection, { headline: "Service Information", children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 1, children: [
4066
+ /* @__PURE__ */ jsxs129(Box14, { children: [
4067
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Service" }),
4068
+ /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: selectedEvent.service_name })
4404
4069
  ] }),
4405
- /* @__PURE__ */ jsxs129(Box15, { children: [
4406
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Resource" }),
4407
- /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: selectedEvent.resource_name })
4070
+ /* @__PURE__ */ jsxs129(Box14, { children: [
4071
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Resource" }),
4072
+ /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: selectedEvent.resource_name })
4408
4073
  ] }),
4409
- Boolean(selectedEvent.region) && /* @__PURE__ */ jsxs129(Box15, { children: [
4410
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Region" }),
4411
- /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: selectedEvent.region })
4074
+ Boolean(selectedEvent.region) && /* @__PURE__ */ jsxs129(Box14, { children: [
4075
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Region" }),
4076
+ /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: selectedEvent.region })
4412
4077
  ] })
4413
4078
  ] }) }),
4414
- /* @__PURE__ */ jsx138(Divider2, {}),
4415
- /* @__PURE__ */ jsx138(ToggleSection, { headline: "Timing", children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 1, children: [
4416
- /* @__PURE__ */ jsxs129(Box15, { children: [
4417
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Start Time" }),
4418
- /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: unixNanoToDate(selectedEvent.start_time_unix_nano)?.toISOString() })
4079
+ /* @__PURE__ */ jsx136(Divider2, {}),
4080
+ /* @__PURE__ */ jsx136(ToggleSection, { headline: "Timing", children: /* @__PURE__ */ jsxs129(Stack2, { spacing: 1, children: [
4081
+ /* @__PURE__ */ jsxs129(Box14, { children: [
4082
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Start Time" }),
4083
+ /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: unixNanoToDate(selectedEvent.start_time_unix_nano)?.toISOString() })
4419
4084
  ] }),
4420
- Boolean(selectedEvent.end_time_unix_nano) && /* @__PURE__ */ jsxs129(Box15, { children: [
4421
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Duration" }),
4085
+ Boolean(selectedEvent.end_time_unix_nano) && /* @__PURE__ */ jsxs129(Box14, { children: [
4086
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: "Duration" }),
4422
4087
  /* @__PURE__ */ jsxs129(Typography9, { variant: "body2", children: [
4423
4088
  ((BigInt(selectedEvent.end_time_unix_nano) - BigInt(selectedEvent.start_time_unix_nano)) / BigInt("1000000")).toString(),
4424
4089
  " ",
@@ -4426,9 +4091,9 @@ var EventDetails = ({ onClose, selectedEvent }) => {
4426
4091
  ] })
4427
4092
  ] })
4428
4093
  ] }) }),
4429
- /* @__PURE__ */ jsx138(Divider2, {}),
4430
- /* @__PURE__ */ jsx138(ToggleSection, { headline: "Status", children: /* @__PURE__ */ jsxs129(Stack2, { direction: "row", spacing: 1, children: [
4431
- /* @__PURE__ */ jsx138(
4094
+ /* @__PURE__ */ jsx136(Divider2, {}),
4095
+ /* @__PURE__ */ jsx136(ToggleSection, { headline: "Status", children: /* @__PURE__ */ jsxs129(Stack2, { direction: "row", spacing: 1, children: [
4096
+ /* @__PURE__ */ jsx136(
4432
4097
  Chip3,
4433
4098
  {
4434
4099
  color: selectedEvent.status_code === 2 ? "error" : selectedEvent.status_code === 1 ? "success" : "default",
@@ -4436,11 +4101,11 @@ var EventDetails = ({ onClose, selectedEvent }) => {
4436
4101
  size: "small"
4437
4102
  }
4438
4103
  ),
4439
- Boolean(selectedEvent.status_message) && /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: selectedEvent.status_message })
4104
+ Boolean(selectedEvent.status_message) && /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: selectedEvent.status_message })
4440
4105
  ] }) }),
4441
4106
  selectedEvent.events.length > 0 && /* @__PURE__ */ jsxs129(Fragment6, { children: [
4442
- /* @__PURE__ */ jsx138(Divider2, {}),
4443
- /* @__PURE__ */ jsx138(
4107
+ /* @__PURE__ */ jsx136(Divider2, {}),
4108
+ /* @__PURE__ */ jsx136(
4444
4109
  EventSection,
4445
4110
  {
4446
4111
  eventGroups: getEventGroupsByType(selectedEvent.events),
@@ -4449,9 +4114,9 @@ var EventDetails = ({ onClose, selectedEvent }) => {
4449
4114
  )
4450
4115
  ] }),
4451
4116
  attributes.length > 0 && /* @__PURE__ */ jsxs129(Fragment6, { children: [
4452
- /* @__PURE__ */ jsx138(Divider2, {}),
4453
- /* @__PURE__ */ jsx138(ToggleSection, { headline: "Attributes", children: /* @__PURE__ */ jsx138(Stack2, { spacing: 1, children: attributes.map(([key, value]) => /* @__PURE__ */ jsxs129(Box15, { children: [
4454
- /* @__PURE__ */ jsx138(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: key }),
4117
+ /* @__PURE__ */ jsx136(Divider2, {}),
4118
+ /* @__PURE__ */ jsx136(ToggleSection, { headline: "Attributes", children: /* @__PURE__ */ jsx136(Stack2, { spacing: 1, children: attributes.map(([key, value]) => /* @__PURE__ */ jsxs129(Box14, { children: [
4119
+ /* @__PURE__ */ jsx136(Typography9, { sx: { fontWeight: 600 }, variant: "caption", children: key }),
4455
4120
  renderKeyValue(key, value)
4456
4121
  ] }, key)) }) })
4457
4122
  ] })
@@ -4460,46 +4125,46 @@ var EventDetails = ({ onClose, selectedEvent }) => {
4460
4125
  };
4461
4126
  function renderKeyValue(key, value) {
4462
4127
  if (typeof value === "string" && (key === "localstack.aws.service.request" || key === "localstack.aws.service.response" || key === "localstack.aws.service.exception")) {
4463
- return /* @__PURE__ */ jsx138(Box15, { sx: { backgroundColor: (theme) => theme.palette.background.default, borderRadius: 1, p: 1 }, children: /* @__PURE__ */ jsx138("pre", { style: { margin: 0, overflow: "auto" }, children: /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: JSON.stringify(JSON.parse(value), void 0, 2) }) }) });
4128
+ return /* @__PURE__ */ jsx136(Box14, { sx: { backgroundColor: (theme) => theme.palette.background.default, borderRadius: 1, p: 1 }, children: /* @__PURE__ */ jsx136("pre", { style: { margin: 0, overflow: "auto" }, children: /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: JSON.stringify(JSON.parse(value), void 0, 2) }) }) });
4464
4129
  }
4465
4130
  if (typeof value === "boolean") {
4466
- return /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: value ? "yes" : "no" });
4131
+ return /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: value ? "yes" : "no" });
4467
4132
  }
4468
- return /* @__PURE__ */ jsx138(Typography9, { variant: "body2", children: value });
4133
+ return /* @__PURE__ */ jsx136(Typography9, { variant: "body2", children: value });
4469
4134
  }
4470
4135
 
4471
4136
  // src/components/trace-graph/trace-graph.tsx
4472
4137
  import "@xyflow/react/dist/base.css";
4473
4138
  import { Alert as Alert3, Button as Button4, useTheme as useTheme2 } from "@mui/material";
4474
- import { Background, ReactFlow, useReactFlow as useReactFlow2 } from "@xyflow/react";
4475
- import { useCallback as useCallback7, useEffect as useEffect6, useState as useState9 } from "react";
4139
+ import { Background, ReactFlow, useNodesState, useReactFlow as useReactFlow2 } from "@xyflow/react";
4140
+ import { useEffect as useEffect5, useState as useState8 } from "react";
4476
4141
 
4477
4142
  // src/components/trace-graph/service-node.tsx
4478
- import { Box as Box17, Stack as Stack3, Typography as Typography10 } from "@mui/material";
4143
+ import { Box as Box16, Stack as Stack3, Typography as Typography10 } from "@mui/material";
4479
4144
  import "@xyflow/react/dist/style.css";
4480
4145
  import { Handle, Position } from "@xyflow/react";
4481
4146
  import { memo as memo2 } from "react";
4482
4147
 
4483
4148
  // src/components/trace-graph/problem-indicator.tsx
4484
4149
  import { Error as ErrorIcon2, Info as Info2, Warning as Warning2 } from "@mui/icons-material";
4485
- import { Box as Box16, Tooltip as Tooltip4 } from "@mui/material";
4486
- import { useMemo as useMemo9 } from "react";
4487
- import { jsx as jsx139 } from "react/jsx-runtime";
4150
+ import { Box as Box15, Tooltip as Tooltip4 } from "@mui/material";
4151
+ import { useMemo as useMemo6 } from "react";
4152
+ import { jsx as jsx137 } from "react/jsx-runtime";
4488
4153
  var ProblemIndicator = ({ error }) => {
4489
- const icon = useMemo9(() => {
4154
+ const icon = useMemo6(() => {
4490
4155
  switch (error.level) {
4491
4156
  case "error": {
4492
- return /* @__PURE__ */ jsx139(ErrorIcon2, { sx: { color: "#d32f2f", fontSize: "14px" } });
4157
+ return /* @__PURE__ */ jsx137(ErrorIcon2, { sx: { color: "#d32f2f", fontSize: "14px" } });
4493
4158
  }
4494
4159
  case "warning": {
4495
- return /* @__PURE__ */ jsx139(Warning2, { sx: { color: "#ff9800", fontSize: "14px" } });
4160
+ return /* @__PURE__ */ jsx137(Warning2, { sx: { color: "#ff9800", fontSize: "14px" } });
4496
4161
  }
4497
4162
  default: {
4498
- return /* @__PURE__ */ jsx139(Info2, { sx: { color: "#2196f3", fontSize: "14px" } });
4163
+ return /* @__PURE__ */ jsx137(Info2, { sx: { color: "#2196f3", fontSize: "14px" } });
4499
4164
  }
4500
4165
  }
4501
4166
  }, [error.level]);
4502
- const color = useMemo9(() => {
4167
+ const color = useMemo6(() => {
4503
4168
  switch (error.level) {
4504
4169
  case "error": {
4505
4170
  return "#d32f2f";
@@ -4512,8 +4177,8 @@ var ProblemIndicator = ({ error }) => {
4512
4177
  }
4513
4178
  }
4514
4179
  }, [error.level]);
4515
- return /* @__PURE__ */ jsx139(Tooltip4, { arrow: true, title: error.message ?? "Issue detected", children: /* @__PURE__ */ jsx139(
4516
- Box16,
4180
+ return /* @__PURE__ */ jsx137(Tooltip4, { arrow: true, title: error.message ?? "Issue detected", children: /* @__PURE__ */ jsx137(
4181
+ Box15,
4517
4182
  {
4518
4183
  sx: {
4519
4184
  alignItems: "center",
@@ -4532,7 +4197,7 @@ var ProblemIndicator = ({ error }) => {
4532
4197
  };
4533
4198
 
4534
4199
  // src/components/trace-graph/service-node.tsx
4535
- import { jsx as jsx140, jsxs as jsxs130 } from "react/jsx-runtime";
4200
+ import { jsx as jsx138, jsxs as jsxs130 } from "react/jsx-runtime";
4536
4201
  var handleStyle = {
4537
4202
  backgroundColor: "white",
4538
4203
  borderColor: "lightgray",
@@ -4540,9 +4205,9 @@ var handleStyle = {
4540
4205
  };
4541
4206
  var ServiceNode = memo2(({ data, selected }) => {
4542
4207
  const hasErrors = (data.event.errors && data.event.errors.length > 0) ?? false;
4543
- return /* @__PURE__ */ jsxs130(Box17, { sx: { maxWidth: 200 }, children: [
4208
+ return /* @__PURE__ */ jsxs130(Box16, { sx: { maxWidth: 200 }, children: [
4544
4209
  /* @__PURE__ */ jsxs130(
4545
- Box17,
4210
+ Box16,
4546
4211
  {
4547
4212
  role: "button",
4548
4213
  sx: {
@@ -4562,9 +4227,9 @@ var ServiceNode = memo2(({ data, selected }) => {
4562
4227
  },
4563
4228
  tabIndex: 0,
4564
4229
  children: [
4565
- /* @__PURE__ */ jsx140(Handle, { position: Position.Left, style: handleStyle, type: "target" }),
4566
- /* @__PURE__ */ jsx140(Handle, { position: Position.Right, style: handleStyle, type: "source" }),
4567
- /* @__PURE__ */ jsx140(
4230
+ /* @__PURE__ */ jsx138(Handle, { position: Position.Left, style: handleStyle, type: "target" }),
4231
+ /* @__PURE__ */ jsx138(Handle, { position: Position.Right, style: handleStyle, type: "source" }),
4232
+ /* @__PURE__ */ jsx138(
4568
4233
  ServiceCell,
4569
4234
  {
4570
4235
  height: "32px",
@@ -4588,7 +4253,7 @@ var ServiceNode = memo2(({ data, selected }) => {
4588
4253
  mt: 0.5
4589
4254
  },
4590
4255
  children: [
4591
- hasErrors && /* @__PURE__ */ jsx140(
4256
+ hasErrors && /* @__PURE__ */ jsx138(
4592
4257
  Stack3,
4593
4258
  {
4594
4259
  direction: "row",
@@ -4597,10 +4262,10 @@ var ServiceNode = memo2(({ data, selected }) => {
4597
4262
  flexWrap: "wrap",
4598
4263
  gap: "2px"
4599
4264
  },
4600
- children: data.event.errors?.map((error) => /* @__PURE__ */ jsx140(ProblemIndicator, { error }, error.span_id))
4265
+ children: data.event.errors?.map((error) => /* @__PURE__ */ jsx138(ProblemIndicator, { error }, error.span_id))
4601
4266
  }
4602
4267
  ),
4603
- /* @__PURE__ */ jsx140(
4268
+ /* @__PURE__ */ jsx138(
4604
4269
  Typography10,
4605
4270
  {
4606
4271
  sx: {
@@ -4717,7 +4382,7 @@ var calculateCenterX = (focusNodeX, viewPortPixelWidth, minX, maxX) => {
4717
4382
 
4718
4383
  // src/components/trace-graph/xyflow/controls.tsx
4719
4384
  import { Add, FitScreen, Remove } from "@mui/icons-material";
4720
- import { Box as Box18, IconButton as IconButton4 } from "@mui/material";
4385
+ import { Box as Box17, IconButton as IconButton4 } from "@mui/material";
4721
4386
  import { useReactFlow, useStore } from "@xyflow/react";
4722
4387
  import { memo as memo3 } from "react";
4723
4388
 
@@ -4760,7 +4425,7 @@ function shallow$1(objA, objB) {
4760
4425
  }
4761
4426
 
4762
4427
  // src/components/trace-graph/xyflow/controls.tsx
4763
- import { jsx as jsx141, jsxs as jsxs131 } from "react/jsx-runtime";
4428
+ import { jsx as jsx139, jsxs as jsxs131 } from "react/jsx-runtime";
4764
4429
  var selector = (s) => ({
4765
4430
  isInteractive: s.nodesDraggable || s.nodesConnectable || s.elementsSelectable,
4766
4431
  maxZoomReached: s.transform[2] >= s.maxZoom,
@@ -4779,7 +4444,7 @@ var Controls = memo3(() => {
4779
4444
  void fitView();
4780
4445
  };
4781
4446
  return /* @__PURE__ */ jsxs131(
4782
- Box18,
4447
+ Box17,
4783
4448
  {
4784
4449
  sx: {
4785
4450
  bottom: 0,
@@ -4792,33 +4457,33 @@ var Controls = memo3(() => {
4792
4457
  zIndex: 5
4793
4458
  },
4794
4459
  children: [
4795
- /* @__PURE__ */ jsx141(
4460
+ /* @__PURE__ */ jsx139(
4796
4461
  IconButton4,
4797
4462
  {
4798
4463
  className: "react-flow__controls-zoomin",
4799
4464
  disabled: maxZoomReached,
4800
4465
  onClick: onZoomInHandler,
4801
4466
  size: "small",
4802
- children: /* @__PURE__ */ jsx141(Add, {})
4467
+ children: /* @__PURE__ */ jsx139(Add, {})
4803
4468
  }
4804
4469
  ),
4805
- /* @__PURE__ */ jsx141(
4470
+ /* @__PURE__ */ jsx139(
4806
4471
  IconButton4,
4807
4472
  {
4808
4473
  className: "react-flow__controls-zoomout",
4809
4474
  disabled: minZoomReached,
4810
4475
  onClick: onZoomOutHandler,
4811
4476
  size: "small",
4812
- children: /* @__PURE__ */ jsx141(Remove, {})
4477
+ children: /* @__PURE__ */ jsx139(Remove, {})
4813
4478
  }
4814
4479
  ),
4815
- /* @__PURE__ */ jsx141(
4480
+ /* @__PURE__ */ jsx139(
4816
4481
  IconButton4,
4817
4482
  {
4818
4483
  className: "react-flow__controls-fitview",
4819
4484
  onClick: onFitViewHandler,
4820
4485
  size: "small",
4821
- children: /* @__PURE__ */ jsx141(FitScreen, {})
4486
+ children: /* @__PURE__ */ jsx139(FitScreen, {})
4822
4487
  }
4823
4488
  )
4824
4489
  ]
@@ -4827,7 +4492,7 @@ var Controls = memo3(() => {
4827
4492
  });
4828
4493
 
4829
4494
  // src/components/trace-graph/trace-graph.tsx
4830
- import { Fragment as Fragment7, jsx as jsx142, jsxs as jsxs132 } from "react/jsx-runtime";
4495
+ import { Fragment as Fragment7, jsx as jsx140, jsxs as jsxs132 } from "react/jsx-runtime";
4831
4496
  var nodeTypes = {
4832
4497
  service: ServiceNode
4833
4498
  };
@@ -4838,17 +4503,11 @@ var TraceGraph = ({
4838
4503
  spans,
4839
4504
  viewPortPixelWidth
4840
4505
  }) => {
4841
- const [nodes, setNodes] = useState9([]);
4842
- const [edges, setEdges] = useState9([]);
4843
- const [initialViewSet, setInitialViewSet] = useState9(false);
4506
+ const [nodes, setNodes, onNodesChange] = useNodesState([]);
4507
+ const [edges, setEdges] = useState8([]);
4508
+ const [initialViewSet, setInitialViewSet] = useState8(false);
4844
4509
  const { fitView, setCenter } = useReactFlow2();
4845
- const updateSelectedNode = useCallback7((nodeId) => {
4846
- const toSelect = new Set(nodeId ? [nodeId] : []);
4847
- setNodes((previousNodes) => {
4848
- return previousNodes.map((node) => ({ ...node, selected: toSelect.has(node.id) }));
4849
- });
4850
- }, []);
4851
- useEffect6(() => {
4510
+ useEffect5(() => {
4852
4511
  const spansMap = /* @__PURE__ */ new Map();
4853
4512
  const rootSpans = [];
4854
4513
  for (const span of spans.data ?? []) {
@@ -4882,8 +4541,8 @@ var TraceGraph = ({
4882
4541
  }
4883
4542
  setNodes(layoutedNodes);
4884
4543
  setEdges(layoutedEdges);
4885
- }, [spans.data, initialFocusEventId]);
4886
- useEffect6(() => {
4544
+ }, [spans.data, initialFocusEventId, setNodes]);
4545
+ useEffect5(() => {
4887
4546
  const shouldSetInitialView = !spans.loading && nodes.length > 0 && !initialViewSet;
4888
4547
  if (shouldSetInitialView) {
4889
4548
  if (initialFocusEventId) {
@@ -4903,21 +4562,12 @@ var TraceGraph = ({
4903
4562
  setInitialViewSet(true);
4904
4563
  }
4905
4564
  }, [spans.loading, nodes, initialFocusEventId, viewPortPixelWidth, setCenter, fitView, onEventSelect, initialViewSet]);
4906
- useEffect6(() => {
4907
- if (initialFocusEventId) {
4908
- updateSelectedNode(initialFocusEventId);
4909
- }
4910
- }, [initialFocusEventId, updateSelectedNode]);
4911
- const onNodeClick = useCallback7((_event, node) => {
4912
- onEventSelect(node.data.event);
4913
- updateSelectedNode(node.id);
4914
- }, [onEventSelect, updateSelectedNode]);
4915
4565
  const theme = useTheme2();
4916
4566
  return /* @__PURE__ */ jsxs132(Fragment7, { children: [
4917
4567
  spans.error && /* @__PURE__ */ jsxs132(
4918
4568
  Alert3,
4919
4569
  {
4920
- action: /* @__PURE__ */ jsx142(Button4, { onClick: () => {
4570
+ action: /* @__PURE__ */ jsx140(Button4, { onClick: () => {
4921
4571
  onRefresh();
4922
4572
  }, children: "Retry" }),
4923
4573
  severity: "error",
@@ -4939,11 +4589,14 @@ var TraceGraph = ({
4939
4589
  minZoom: 0.1,
4940
4590
  nodes,
4941
4591
  nodeTypes,
4942
- onNodeClick,
4592
+ onNodeClick: (_event, node) => {
4593
+ onEventSelect(node.data.event);
4594
+ },
4595
+ onNodesChange,
4943
4596
  selectNodesOnDrag: false,
4944
4597
  children: [
4945
- /* @__PURE__ */ jsx142(Controls, {}),
4946
- /* @__PURE__ */ jsx142(
4598
+ /* @__PURE__ */ jsx140(Controls, {}),
4599
+ /* @__PURE__ */ jsx140(
4947
4600
  Background,
4948
4601
  {
4949
4602
  bgColor: theme.palette.background.paper,
@@ -4957,7 +4610,7 @@ var TraceGraph = ({
4957
4610
  };
4958
4611
 
4959
4612
  // src/pages/trace-graph-page.tsx
4960
- import { Fragment as Fragment8, jsx as jsx143, jsxs as jsxs133 } from "react/jsx-runtime";
4613
+ import { Fragment as Fragment8, jsx as jsx141, jsxs as jsxs133 } from "react/jsx-runtime";
4961
4614
  var HEADER_HEIGHT = 56;
4962
4615
  var DRAWER_WIDTH = "35%";
4963
4616
  var Main = styled("main", { shouldForwardProp: (property) => property !== "open" })(({ open, theme }) => ({
@@ -5007,7 +4660,7 @@ var TraceGraphView = ({
5007
4660
  }) => {
5008
4661
  const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
5009
4662
  return /* @__PURE__ */ jsxs133(
5010
- Box19,
4663
+ Box18,
5011
4664
  {
5012
4665
  "data-testid": "trace-graph-page",
5013
4666
  sx: {
@@ -5019,13 +4672,13 @@ var TraceGraphView = ({
5019
4672
  overflow: "hidden"
5020
4673
  },
5021
4674
  children: [
5022
- /* @__PURE__ */ jsxs133(Box19, { sx: { display: "flex", width: "100%" }, children: [
5023
- /* @__PURE__ */ jsx143(Button5, { onClick: () => {
4675
+ /* @__PURE__ */ jsxs133(Box18, { sx: { display: "flex", width: "100%" }, children: [
4676
+ /* @__PURE__ */ jsx141(Button5, { onClick: () => {
5024
4677
  navigateToSpansList();
5025
- }, startIcon: /* @__PURE__ */ jsx143(ArrowBack, {}), children: "Go back" }),
5026
- /* @__PURE__ */ jsx143(Box19, { sx: { flexGrow: 1 } })
4678
+ }, startIcon: /* @__PURE__ */ jsx141(ArrowBack, {}), children: "Go back" }),
4679
+ /* @__PURE__ */ jsx141(Box18, { sx: { flexGrow: 1 } })
5027
4680
  ] }),
5028
- /* @__PURE__ */ jsx143(
4681
+ /* @__PURE__ */ jsx141(
5029
4682
  Paper2,
5030
4683
  {
5031
4684
  sx: {
@@ -5035,7 +4688,7 @@ var TraceGraphView = ({
5035
4688
  position: "relative",
5036
4689
  width: "100%"
5037
4690
  },
5038
- children: shouldShowStatusMessage ? /* @__PURE__ */ jsx143(
4691
+ children: shouldShowStatusMessage ? /* @__PURE__ */ jsx141(
5039
4692
  StatusMessage,
5040
4693
  {
5041
4694
  error: statusError,
@@ -5043,14 +4696,14 @@ var TraceGraphView = ({
5043
4696
  status
5044
4697
  }
5045
4698
  ) : /* @__PURE__ */ jsxs133(Fragment8, { children: [
5046
- /* @__PURE__ */ jsx143(Main, { open, children: /* @__PURE__ */ jsx143(
5047
- Box19,
4699
+ /* @__PURE__ */ jsx141(Main, { open, children: /* @__PURE__ */ jsx141(
4700
+ Box18,
5048
4701
  {
5049
4702
  sx: {
5050
4703
  height: "100%",
5051
4704
  overflow: "auto"
5052
4705
  },
5053
- children: traceId !== void 0 && /* @__PURE__ */ jsx143(ReactFlowProvider, { children: /* @__PURE__ */ jsx143(
4706
+ children: traceId !== void 0 && /* @__PURE__ */ jsx141(ReactFlowProvider, { children: /* @__PURE__ */ jsx141(
5054
4707
  TraceGraph,
5055
4708
  {
5056
4709
  initialFocusEventId: spanId,
@@ -5068,7 +4721,7 @@ var TraceGraphView = ({
5068
4721
  ) })
5069
4722
  }
5070
4723
  ) }),
5071
- /* @__PURE__ */ jsx143(StyledDrawer, { anchor: "right", open, variant: "persistent", children: /* @__PURE__ */ jsx143(EventDetails, { onClose: handleClose, selectedEvent }) })
4724
+ /* @__PURE__ */ jsx141(StyledDrawer, { anchor: "right", open, variant: "persistent", children: /* @__PURE__ */ jsx141(EventDetails, { onClose: handleClose, selectedEvent }) })
5072
4725
  ] })
5073
4726
  }
5074
4727
  )
@@ -5076,15 +4729,12 @@ var TraceGraphView = ({
5076
4729
  }
5077
4730
  );
5078
4731
  };
5079
- var TraceGraphPage = () => {
5080
- const { traceId } = useParams();
5081
- const [searchParameters] = useSearchParams2();
5082
- const spanId = searchParameters.get("spanId");
4732
+ var TraceGraphPage = ({ onClose, spanId, traceId }) => {
5083
4733
  const api = useAppInspectorApi();
5084
- const [spans, setSpans] = useState10();
5085
- const [loading, setLoading] = useState10(false);
5086
- const [fetchError, setFetchError] = useState10();
5087
- const fetchSpans = useCallback8(async () => {
4734
+ const [spans, setSpans] = useState9();
4735
+ const [loading, setLoading] = useState9(false);
4736
+ const [fetchError, setFetchError] = useState9();
4737
+ const fetchSpans = useCallback4(async () => {
5088
4738
  setLoading(true);
5089
4739
  try {
5090
4740
  const response = await api.getSpans({
@@ -5099,14 +4749,14 @@ var TraceGraphPage = () => {
5099
4749
  setLoading(false);
5100
4750
  }
5101
4751
  }, [api, traceId]);
5102
- useEffect7(() => {
4752
+ useEffect6(() => {
5103
4753
  void fetchSpans();
5104
4754
  }, [fetchSpans]);
5105
- const [open, setOpen] = useState10(true);
5106
- const [selectedEvent, setSelectedEvent] = useState10();
5107
- const [viewPortPixelWidth, setViewPortPixelWidth] = useState10(0);
4755
+ const [open, setOpen] = useState9(true);
4756
+ const [selectedEvent, setSelectedEvent] = useState9();
4757
+ const [viewPortPixelWidth, setViewPortPixelWidth] = useState9(0);
5108
4758
  const { checkStatus, error: statusError, status } = useStatus();
5109
- const calculateDrawerWidth = useCallback8(() => {
4759
+ const calculateDrawerWidth = useCallback4(() => {
5110
4760
  const percentageMatch = /(\d+)%/.exec(DRAWER_WIDTH);
5111
4761
  if (percentageMatch && open) {
5112
4762
  const percentage = Number.parseInt(percentageMatch[1], 10);
@@ -5114,7 +4764,7 @@ var TraceGraphPage = () => {
5114
4764
  }
5115
4765
  return 0;
5116
4766
  }, [open]);
5117
- useEffect7(() => {
4767
+ useEffect6(() => {
5118
4768
  const updateViewportWidth = () => {
5119
4769
  const totalWidth = window.innerWidth;
5120
4770
  const drawerPixelWidth = open ? calculateDrawerWidth() : 0;
@@ -5128,24 +4778,17 @@ var TraceGraphPage = () => {
5128
4778
  clearTimeout(timeoutId);
5129
4779
  };
5130
4780
  }, [open, calculateDrawerWidth]);
5131
- const handleEventSelect = useCallback8((event) => {
4781
+ const handleEventSelect = useCallback4((event) => {
5132
4782
  setSelectedEvent(event);
5133
4783
  setOpen(true);
5134
4784
  }, []);
5135
- const handleRetry = useCallback8(() => {
4785
+ const handleRetry = useCallback4(() => {
5136
4786
  void checkStatus();
5137
4787
  }, [checkStatus]);
5138
- const navigate = useNavigate2();
5139
- const { resolveLink } = useAppInspector();
5140
- const navigateToSpansList = useCallback8(() => {
5141
- const url = resolveLink({ to: "spans-list" });
5142
- const searchParams = new URLSearchParams({
5143
- page: searchParameters.get("page") ?? "",
5144
- pageSize: searchParameters.get("pageSize") ?? ""
5145
- });
5146
- navigate(`${url}?${searchParams.toString()}`);
5147
- }, [navigate, resolveLink, searchParameters]);
5148
- return /* @__PURE__ */ jsx143(
4788
+ const navigateToSpansList = useCallback4(() => {
4789
+ onClose?.();
4790
+ }, [onClose]);
4791
+ return /* @__PURE__ */ jsx141(
5149
4792
  TraceGraphView,
5150
4793
  {
5151
4794
  fetchError,
@@ -5169,16 +4812,302 @@ var TraceGraphPage = () => {
5169
4812
  );
5170
4813
  };
5171
4814
 
4815
+ // src/pages/spans-list-page.tsx
4816
+ import { Fragment as Fragment9, jsx as jsx142, jsxs as jsxs134 } from "react/jsx-runtime";
4817
+ var spansPerPageOptions = [25, 50, 100];
4818
+ var SpansListPage = () => {
4819
+ const api = useAppInspectorApi();
4820
+ const [spans, setSpans] = useState10();
4821
+ const [loading, setLoading] = useState10(false);
4822
+ const hasFetched = useRef4(false);
4823
+ const [filterWriteOperations, setFilterWriteOperations] = useLocalStorage("filterWriteOperations", true);
4824
+ const mapPageToNextCursor = useRef4({});
4825
+ const [page, setPage] = useState10(0);
4826
+ const [pageSize, setPageSize] = useState10(100);
4827
+ const [spanCount, setSpanCount] = useState10(0);
4828
+ const queryOptions = useMemo7(() => {
4829
+ return {
4830
+ is_write_operation: filterWriteOperations ? true : void 0,
4831
+ limit: pageSize,
4832
+ pagination_token: mapPageToNextCursor.current[page - 1]
4833
+ };
4834
+ }, [filterWriteOperations, pageSize, page]);
4835
+ const [fetchError, setFetchError] = useState10();
4836
+ const { checkStatus, error: statusError, status } = useStatus();
4837
+ const fetchSpans = useCallback5(async () => {
4838
+ setLoading(true);
4839
+ try {
4840
+ const response = await api.getSpans(queryOptions);
4841
+ setSpans(response.spans);
4842
+ setSpanCount(response.pagination.total_count);
4843
+ setFetchError(void 0);
4844
+ if (response.pagination.cursor) {
4845
+ mapPageToNextCursor.current[page] = response.pagination.cursor;
4846
+ }
4847
+ } catch (error) {
4848
+ console.error(error);
4849
+ setFetchError(error instanceof Error ? error : new Error("Unknown error", { cause: error }));
4850
+ } finally {
4851
+ setLoading(false);
4852
+ }
4853
+ }, [api, page, queryOptions]);
4854
+ const fetchSpansSync = useCallback5(() => {
4855
+ void fetchSpans();
4856
+ }, [fetchSpans]);
4857
+ useEffect7(() => {
4858
+ if (hasFetched.current) return;
4859
+ if (status?.status !== "ENABLED") return;
4860
+ hasFetched.current = true;
4861
+ void fetchSpans();
4862
+ }, [fetchSpans, status]);
4863
+ useEffect7(() => {
4864
+ if (!hasFetched.current) return;
4865
+ void fetchSpans();
4866
+ }, [fetchSpans]);
4867
+ const [selectedTraceId, setSelectedTraceId] = useState10();
4868
+ const [selectedSpanId, setSelectedSpanId] = useState10();
4869
+ const navigateToSpan = useCallback5((span) => {
4870
+ setSelectedTraceId(span.trace_id);
4871
+ setSelectedSpanId(span.span_id);
4872
+ }, []);
4873
+ const clearSpans = useCallback5(async () => {
4874
+ setLoading(true);
4875
+ try {
4876
+ await api.deleteSpans();
4877
+ setSpans([]);
4878
+ setFetchError(void 0);
4879
+ await fetchSpans();
4880
+ } catch (error) {
4881
+ console.error("Failed to delete spans:", error);
4882
+ setFetchError(error instanceof Error ? error : new Error("Failed to delete spans", { cause: error }));
4883
+ } finally {
4884
+ setLoading(false);
4885
+ }
4886
+ }, [api, fetchSpans]);
4887
+ const handleRetry = useCallback5(() => {
4888
+ void checkStatus();
4889
+ }, [checkStatus]);
4890
+ const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
4891
+ return /* @__PURE__ */ jsxs134(Fragment9, { children: [
4892
+ /* @__PURE__ */ jsx142(
4893
+ Box19,
4894
+ {
4895
+ "data-testid": "spans-list-page",
4896
+ sx: {
4897
+ alignItems: "center",
4898
+ display: "flex",
4899
+ flexDirection: "column",
4900
+ // Do not consume vertical space if trace graph is open
4901
+ flexGrow: selectedTraceId ? 0 : 1,
4902
+ height: selectedTraceId ? 0 : void 0,
4903
+ // Do not show if trace graph is open
4904
+ visibility: selectedTraceId ? "hidden" : "visible",
4905
+ width: "100%"
4906
+ },
4907
+ children: shouldShowStatusMessage ? /* @__PURE__ */ jsx142(
4908
+ StatusMessage,
4909
+ {
4910
+ error: statusError,
4911
+ onRetry: handleRetry,
4912
+ status
4913
+ }
4914
+ ) : /* @__PURE__ */ jsx142(
4915
+ SpansList,
4916
+ {
4917
+ filterWriteOperations,
4918
+ onClearSpans: () => {
4919
+ void clearSpans();
4920
+ },
4921
+ onFilterWriteOperationsChange: (value) => {
4922
+ setFilterWriteOperations(value);
4923
+ },
4924
+ onPageChange: setPage,
4925
+ onPageSizeChange: setPageSize,
4926
+ onRefresh: () => {
4927
+ fetchSpansSync();
4928
+ },
4929
+ onSpanClick: (span) => {
4930
+ navigateToSpan(span);
4931
+ },
4932
+ page,
4933
+ pageSize,
4934
+ spanCount,
4935
+ spans: {
4936
+ data: spans,
4937
+ error: fetchError,
4938
+ loading
4939
+ },
4940
+ spansPerPageOptions
4941
+ }
4942
+ )
4943
+ }
4944
+ ),
4945
+ selectedTraceId !== void 0 && /* @__PURE__ */ jsx142(TraceGraphPage, { onClose: () => {
4946
+ setSelectedTraceId(void 0);
4947
+ }, spanId: selectedSpanId, traceId: selectedTraceId })
4948
+ ] });
4949
+ };
4950
+
5172
4951
  // src/routes.ts
5173
4952
  var routes = {
5174
- APP_INSPECTOR_SPANS_LIST: "spans",
5175
- APP_INSPECTOR_TRACE_GRAPH: "traces/:traceId"
4953
+ APP_INSPECTOR_SPANS_LIST: "spans"
4954
+ };
4955
+
4956
+ // src/context.tsx
4957
+ import { createContext as createContext2, useContext as useContext2 } from "react";
4958
+ import { useCallback as useCallback6, useMemo as useMemo8 } from "react";
4959
+
4960
+ // src/constants/error-messages.ts
4961
+ var ERROR_MESSAGES = {
4962
+ APP_INSPECTOR_DISABLED: "App Inspector is currently disabled.",
4963
+ APP_INSPECTOR_NOT_FOUND: "App Inspector extension not found. Please ensure App Inspector is licensed and enabled.",
4964
+ CONNECTION_FAILED: "Failed to connect to LocalStack. Please ensure LocalStack is running and accessible."
4965
+ };
4966
+
4967
+ // src/api/client.ts
4968
+ var apiLogger = createScopedLogger("API");
4969
+ var makeRequest = async (options) => {
4970
+ const url = getAppInspectorApiUrl(options.localstackEndpoint, options.endpoint);
4971
+ try {
4972
+ apiLogger.info("Making request to:", { options, url });
4973
+ const headers = new Headers(options.request?.headers);
4974
+ headers.set("Content-Type", "application/json");
4975
+ const response = await fetch(url, {
4976
+ ...options.request,
4977
+ headers
4978
+ });
4979
+ if (!response.ok) {
4980
+ if (response.status === 404) {
4981
+ throw new AppInspectorNotFoundError(
4982
+ ERROR_MESSAGES.APP_INSPECTOR_NOT_FOUND,
4983
+ new Error(`404 from ${url}: ${response.statusText}`)
4984
+ );
4985
+ }
4986
+ throw new Error(`API request failed: ${response.status.toString()} ${response.statusText}`);
4987
+ }
4988
+ return await response.json();
4989
+ } catch (error) {
4990
+ if (error instanceof TypeError) {
4991
+ const message = error.message.toLowerCase();
4992
+ const isNetworkError = message.includes("fetch") || message.includes("network") || message.includes("failed to fetch");
4993
+ if (isNetworkError) {
4994
+ throw new ConnectionError(ERROR_MESSAGES.CONNECTION_FAILED, error);
4995
+ }
4996
+ }
4997
+ if (error instanceof Error) {
4998
+ throw error;
4999
+ }
5000
+ throw new Error("Unknown error occurred");
5001
+ }
5002
+ };
5003
+ var buildSpansEndpoint = (request) => {
5004
+ if (!request) {
5005
+ return API_ENDPOINTS.SPANS;
5006
+ }
5007
+ const queryParameters = new URLSearchParams();
5008
+ if (request.limit !== void 0) {
5009
+ queryParameters.set("limit", request.limit.toString());
5010
+ }
5011
+ if (request.pagination_token) {
5012
+ queryParameters.set("pagination_token", request.pagination_token);
5013
+ }
5014
+ for (const [key, value] of Object.entries(request)) {
5015
+ if (value !== void 0 && key !== "limit" && key !== "pagination_token" && value !== null) {
5016
+ queryParameters.set(key, String(value));
5017
+ }
5018
+ }
5019
+ const queryString = queryParameters.toString();
5020
+ return queryString ? `${API_ENDPOINTS.SPANS}?${queryString}` : API_ENDPOINTS.SPANS;
5021
+ };
5022
+ var buildEventsEndpoint = (request) => {
5023
+ if (!request) {
5024
+ return API_ENDPOINTS.EVENTS;
5025
+ }
5026
+ const basePath = API_ENDPOINTS.EVENTS;
5027
+ const queryParameters = new URLSearchParams();
5028
+ if (request.limit !== void 0) {
5029
+ queryParameters.set("limit", request.limit.toString());
5030
+ }
5031
+ if (request.pagination_token) {
5032
+ queryParameters.set("pagination_token", request.pagination_token);
5033
+ }
5034
+ for (const [key, value] of Object.entries(request)) {
5035
+ if (value !== void 0 && key !== "limit" && key !== "pagination_token" && value !== null) {
5036
+ queryParameters.set(key, String(value));
5037
+ }
5038
+ }
5039
+ const queryString = queryParameters.toString();
5040
+ return queryString ? `${basePath}?${queryString}` : basePath;
5041
+ };
5042
+ var createApiClient = ({ localstackEndpoint }) => {
5043
+ return {
5044
+ deleteSpans: async (_request) => {
5045
+ return makeRequest({
5046
+ endpoint: API_ENDPOINTS.SPANS,
5047
+ localstackEndpoint,
5048
+ request: {
5049
+ method: "DELETE"
5050
+ }
5051
+ });
5052
+ },
5053
+ getEvents: async (request) => {
5054
+ const endpoint = buildEventsEndpoint(request);
5055
+ return makeRequest({ endpoint, localstackEndpoint });
5056
+ },
5057
+ getIamEvents: async (request) => {
5058
+ const iamEventsRequest = {
5059
+ ...request,
5060
+ event_type: "iam.policy_evaluation"
5061
+ };
5062
+ const endpoint = buildEventsEndpoint(iamEventsRequest);
5063
+ return makeRequest({ endpoint, localstackEndpoint });
5064
+ },
5065
+ getSpans: async (request) => {
5066
+ const endpoint = buildSpansEndpoint(request);
5067
+ return makeRequest({ endpoint, localstackEndpoint });
5068
+ },
5069
+ getStatus: async () => {
5070
+ return makeRequest({
5071
+ endpoint: API_ENDPOINTS.STATUS,
5072
+ localstackEndpoint
5073
+ });
5074
+ }
5075
+ };
5076
+ };
5077
+
5078
+ // src/context.tsx
5079
+ import { jsx as jsx143 } from "react/jsx-runtime";
5080
+ var AppInspectorContext = createContext2(void 0);
5081
+ var AppInspectorContextProvider = (props) => {
5082
+ const api = useMemo8(() => {
5083
+ return false ? createApiClientMock() : createApiClient({ localstackEndpoint: props.localstackEndpoint });
5084
+ }, [props.localstackEndpoint]);
5085
+ const resolveLink = useCallback6(
5086
+ (options) => {
5087
+ if (options.to === "settings") {
5088
+ return `${props.routePrefix}/settings`;
5089
+ }
5090
+ if (options.to === "trace-graph") {
5091
+ return `${props.routePrefix}/traces/${options.traceId}`;
5092
+ }
5093
+ return `${props.routePrefix}/spans`;
5094
+ },
5095
+ [props.routePrefix]
5096
+ );
5097
+ const contextValue = useMemo8(
5098
+ () => ({
5099
+ linkComponent: props.linkComponent,
5100
+ localstackEndpoint: props.localstackEndpoint,
5101
+ resolveLink
5102
+ }),
5103
+ [props.linkComponent, props.localstackEndpoint, resolveLink]
5104
+ );
5105
+ return /* @__PURE__ */ jsx143(ApiProvider, { api, children: /* @__PURE__ */ jsx143(AppInspectorContext.Provider, { value: contextValue, children: props.children }) });
5176
5106
  };
5177
5107
 
5178
5108
  // src/index.ts
5179
5109
  var pages = {
5180
- APP_INSPECTOR_SPANS_LIST: [routes.APP_INSPECTOR_SPANS_LIST, SpansListPage],
5181
- APP_INSPECTOR_TRACE_GRAPH: [routes.APP_INSPECTOR_TRACE_GRAPH, TraceGraphPage]
5110
+ APP_INSPECTOR_SPANS_LIST: [routes.APP_INSPECTOR_SPANS_LIST, SpansListPage]
5182
5111
  };
5183
5112
  export {
5184
5113
  AppInspectorContextProvider,