@localstack/appinspector-ui 1.0.0-dev-c7a4c87a → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -37,7 +37,7 @@ module.exports = __toCommonJS(index_exports);
37
37
 
38
38
  // src/pages/spans-list-page.tsx
39
39
  var import_material7 = require("@mui/material");
40
- var import_react7 = require("react");
40
+ var import_react8 = require("react");
41
41
  var import_react_router_dom = require("react-router-dom");
42
42
 
43
43
  // src/api/use-api.tsx
@@ -3291,16 +3291,58 @@ var AppInspectorContextProvider = (props) => {
3291
3291
  ) });
3292
3292
  };
3293
3293
 
3294
- // src/hooks/use-status.tsx
3294
+ // src/hooks/use-local-storage.tsx
3295
3295
  var import_react6 = require("react");
3296
+ function useLocalStorage(key, initialValue) {
3297
+ const [storedValue, setStoredValue] = (0, import_react6.useState)(() => {
3298
+ try {
3299
+ const item = globalThis.localStorage.getItem(key);
3300
+ return item ? JSON.parse(item) : initialValue;
3301
+ } catch (error) {
3302
+ console.error(`Error reading localStorage key "${key}":`, error);
3303
+ return initialValue;
3304
+ }
3305
+ });
3306
+ const setValue = (0, import_react6.useCallback)((value) => {
3307
+ try {
3308
+ setStoredValue(value);
3309
+ globalThis.localStorage.setItem(key, JSON.stringify(value));
3310
+ globalThis.dispatchEvent(new StorageEvent("storage", {
3311
+ key,
3312
+ newValue: JSON.stringify(value)
3313
+ }));
3314
+ } catch (error) {
3315
+ console.error(`Error setting localStorage key "${key}":`, error);
3316
+ }
3317
+ }, [key]);
3318
+ (0, import_react6.useEffect)(() => {
3319
+ const handleStorageChange = (event) => {
3320
+ if (event.key === key && event.newValue !== null) {
3321
+ try {
3322
+ setStoredValue(JSON.parse(event.newValue));
3323
+ } catch (error) {
3324
+ console.error(`Error parsing localStorage key "${key}":`, error);
3325
+ }
3326
+ }
3327
+ };
3328
+ globalThis.addEventListener("storage", handleStorageChange);
3329
+ return () => {
3330
+ globalThis.removeEventListener("storage", handleStorageChange);
3331
+ };
3332
+ }, [key]);
3333
+ return [storedValue, setValue];
3334
+ }
3335
+
3336
+ // src/hooks/use-status.tsx
3337
+ var import_react7 = require("react");
3296
3338
  var useStatus = () => {
3297
3339
  const api = useAppInspectorApi();
3298
- const [checking, setChecking] = (0, import_react6.useState)(true);
3299
- const [status, setStatus] = (0, import_react6.useState)();
3300
- const [error, setError] = (0, import_react6.useState)();
3301
- const hasFetchedReference = (0, import_react6.useRef)(false);
3302
- const abortControllerReference = (0, import_react6.useRef)(null);
3303
- const checkStatus = (0, import_react6.useCallback)(async () => {
3340
+ const [checking, setChecking] = (0, import_react7.useState)(true);
3341
+ const [status, setStatus] = (0, import_react7.useState)();
3342
+ const [error, setError] = (0, import_react7.useState)();
3343
+ const hasFetchedReference = (0, import_react7.useRef)(false);
3344
+ const abortControllerReference = (0, import_react7.useRef)(null);
3345
+ const checkStatus = (0, import_react7.useCallback)(async () => {
3304
3346
  if (abortControllerReference.current) {
3305
3347
  abortControllerReference.current.abort();
3306
3348
  }
@@ -3324,7 +3366,7 @@ var useStatus = () => {
3324
3366
  }
3325
3367
  }
3326
3368
  }, [api]);
3327
- (0, import_react6.useEffect)(() => {
3369
+ (0, import_react7.useEffect)(() => {
3328
3370
  if (!hasFetchedReference.current) {
3329
3371
  hasFetchedReference.current = true;
3330
3372
  void checkStatus();
@@ -3338,13 +3380,13 @@ var import_jsx_runtime128 = require("react/jsx-runtime");
3338
3380
  var MAX_WIDTH = 1400;
3339
3381
  var SpansListPage = () => {
3340
3382
  const api = useAppInspectorApi();
3341
- const [spans, setSpans] = (0, import_react7.useState)();
3342
- const [loading, setLoading] = (0, import_react7.useState)(false);
3343
- const hasFetched = (0, import_react7.useRef)(false);
3344
- const [filterWriteOperations, setFilterWriteOperations] = (0, import_react7.useState)(true);
3345
- const [fetchError, setFetchError] = (0, import_react7.useState)();
3383
+ const [spans, setSpans] = (0, import_react8.useState)();
3384
+ const [loading, setLoading] = (0, import_react8.useState)(false);
3385
+ const hasFetched = (0, import_react8.useRef)(false);
3386
+ const [filterWriteOperations, setFilterWriteOperations] = useLocalStorage("filterWriteOperations", true);
3387
+ const [fetchError, setFetchError] = (0, import_react8.useState)();
3346
3388
  const { checkStatus, error: statusError, status } = useStatus();
3347
- const fetchSpans = (0, import_react7.useCallback)(async () => {
3389
+ const fetchSpans = (0, import_react8.useCallback)(async () => {
3348
3390
  setLoading(true);
3349
3391
  try {
3350
3392
  const response = await api.getSpans({
@@ -3360,26 +3402,26 @@ var SpansListPage = () => {
3360
3402
  setLoading(false);
3361
3403
  }
3362
3404
  }, [api, filterWriteOperations]);
3363
- const fetchSpansSync = (0, import_react7.useCallback)(() => {
3405
+ const fetchSpansSync = (0, import_react8.useCallback)(() => {
3364
3406
  void fetchSpans();
3365
3407
  }, [fetchSpans]);
3366
- (0, import_react7.useEffect)(() => {
3408
+ (0, import_react8.useEffect)(() => {
3367
3409
  if (hasFetched.current) return;
3368
3410
  if (status?.status !== "ENABLED") return;
3369
3411
  hasFetched.current = true;
3370
3412
  void fetchSpans();
3371
3413
  }, [fetchSpans, status]);
3372
- (0, import_react7.useEffect)(() => {
3414
+ (0, import_react8.useEffect)(() => {
3373
3415
  if (!hasFetched.current) return;
3374
3416
  void fetchSpans();
3375
3417
  }, [fetchSpans]);
3376
3418
  const navigate = (0, import_react_router_dom.useNavigate)();
3377
3419
  const { resolveLink } = useAppInspector();
3378
- const navigateToSpan = (0, import_react7.useCallback)((span) => {
3420
+ const navigateToSpan = (0, import_react8.useCallback)((span) => {
3379
3421
  const url = resolveLink({ to: "trace-graph", traceId: span.trace_id });
3380
3422
  navigate(`${url}?spanId=${span.span_id}`);
3381
3423
  }, [navigate, resolveLink]);
3382
- const clearSpans = (0, import_react7.useCallback)(async () => {
3424
+ const clearSpans = (0, import_react8.useCallback)(async () => {
3383
3425
  setLoading(true);
3384
3426
  try {
3385
3427
  await api.deleteSpans();
@@ -3393,7 +3435,7 @@ var SpansListPage = () => {
3393
3435
  setLoading(false);
3394
3436
  }
3395
3437
  }, [api, fetchSpans]);
3396
- const handleRetry = (0, import_react7.useCallback)(() => {
3438
+ const handleRetry = (0, import_react8.useCallback)(() => {
3397
3439
  void checkStatus();
3398
3440
  }, [checkStatus]);
3399
3441
  const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
@@ -3457,8 +3499,8 @@ var SpansListPage = () => {
3457
3499
  // src/pages/trace-graph-page.tsx
3458
3500
  var import_material14 = require("@mui/material");
3459
3501
  var import_styles = require("@mui/material/styles");
3460
- var import_react15 = require("@xyflow/react");
3461
- var import_react16 = require("react");
3502
+ var import_react16 = require("@xyflow/react");
3503
+ var import_react17 = require("react");
3462
3504
  var import_react_router_dom2 = require("react-router-dom");
3463
3505
 
3464
3506
  // src/components/event-details/event-details.tsx
@@ -3499,10 +3541,10 @@ var EventDetailsHeader = ({ event, onClose }) => {
3499
3541
  // src/components/event-details/toggle-section.tsx
3500
3542
  var import_icons_material3 = require("@mui/icons-material");
3501
3543
  var import_material9 = require("@mui/material");
3502
- var import_react8 = require("react");
3544
+ var import_react9 = require("react");
3503
3545
  var import_jsx_runtime130 = require("react/jsx-runtime");
3504
3546
  var ToggleSection = ({ children, headline, initialOpen = true }) => {
3505
- const [isOpen, setIsOpen] = (0, import_react8.useState)(initialOpen);
3547
+ const [isOpen, setIsOpen] = (0, import_react9.useState)(initialOpen);
3506
3548
  return /* @__PURE__ */ (0, import_jsx_runtime130.jsxs)(import_material9.Box, { sx: { mt: 4 }, children: [
3507
3549
  /* @__PURE__ */ (0, import_jsx_runtime130.jsx)(
3508
3550
  import_material9.Box,
@@ -3611,22 +3653,22 @@ var EventDetails = ({ selectedEvent }) => {
3611
3653
  // src/components/trace-graph/trace-graph.tsx
3612
3654
  var import_base = require("@xyflow/react/dist/base.css");
3613
3655
  var import_material13 = require("@mui/material");
3614
- var import_react13 = require("@xyflow/react");
3615
- var import_react14 = require("react");
3656
+ var import_react14 = require("@xyflow/react");
3657
+ var import_react15 = require("react");
3616
3658
 
3617
3659
  // src/components/trace-graph/service-node.tsx
3618
3660
  var import_material12 = require("@mui/material");
3619
3661
  var import_style = require("@xyflow/react/dist/style.css");
3620
- var import_react10 = require("@xyflow/react");
3621
- var import_react11 = require("react");
3662
+ var import_react11 = require("@xyflow/react");
3663
+ var import_react12 = require("react");
3622
3664
 
3623
3665
  // src/components/trace-graph/problem-indicator.tsx
3624
3666
  var import_icons_material4 = require("@mui/icons-material");
3625
3667
  var import_material11 = require("@mui/material");
3626
- var import_react9 = require("react");
3668
+ var import_react10 = require("react");
3627
3669
  var import_jsx_runtime132 = require("react/jsx-runtime");
3628
3670
  var ProblemIndicator = ({ error }) => {
3629
- const icon = (0, import_react9.useMemo)(() => {
3671
+ const icon = (0, import_react10.useMemo)(() => {
3630
3672
  switch (error.level) {
3631
3673
  case "error": {
3632
3674
  return /* @__PURE__ */ (0, import_jsx_runtime132.jsx)(import_icons_material4.Error, { sx: { color: "#d32f2f", fontSize: "14px" } });
@@ -3639,7 +3681,7 @@ var ProblemIndicator = ({ error }) => {
3639
3681
  }
3640
3682
  }
3641
3683
  }, [error.level]);
3642
- const color = (0, import_react9.useMemo)(() => {
3684
+ const color = (0, import_react10.useMemo)(() => {
3643
3685
  switch (error.level) {
3644
3686
  case "error": {
3645
3687
  return "#d32f2f";
@@ -3678,11 +3720,11 @@ var handleStyle = {
3678
3720
  borderColor: "lightgray",
3679
3721
  opacity: 0
3680
3722
  };
3681
- var ServiceNode = (0, import_react11.memo)(function ServiceNode2({ data, selected }) {
3682
- const handleClick = (0, import_react11.useCallback)(() => {
3723
+ var ServiceNode = (0, import_react12.memo)(function ServiceNode2({ data, selected }) {
3724
+ const handleClick = (0, import_react12.useCallback)(() => {
3683
3725
  data.onEventSelect(data.event);
3684
3726
  }, [data]);
3685
- const handleKeyPress = (0, import_react11.useCallback)(
3727
+ const handleKeyPress = (0, import_react12.useCallback)(
3686
3728
  (event) => {
3687
3729
  if (event.key === "Enter" || event.key === " ") {
3688
3730
  handleClick();
@@ -3715,8 +3757,8 @@ var ServiceNode = (0, import_react11.memo)(function ServiceNode2({ data, selecte
3715
3757
  },
3716
3758
  tabIndex: 0,
3717
3759
  children: [
3718
- /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_react10.Handle, { position: import_react10.Position.Left, style: handleStyle, type: "target" }),
3719
- /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_react10.Handle, { position: import_react10.Position.Right, style: handleStyle, type: "source" }),
3760
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_react11.Handle, { position: import_react11.Position.Left, style: handleStyle, type: "target" }),
3761
+ /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(import_react11.Handle, { position: import_react11.Position.Right, style: handleStyle, type: "source" }),
3720
3762
  /* @__PURE__ */ (0, import_jsx_runtime133.jsx)(
3721
3763
  ServiceCell,
3722
3764
  {
@@ -3777,7 +3819,7 @@ var ServiceNode = (0, import_react11.memo)(function ServiceNode2({ data, selecte
3777
3819
 
3778
3820
  // src/components/trace-graph/utils.ts
3779
3821
  var import_dagre = __toESM(require("@dagrejs/dagre"), 1);
3780
- var import_react12 = require("@xyflow/react");
3822
+ var import_react13 = require("@xyflow/react");
3781
3823
  var generateNodesAndEdges = (event, onEventSelect, parentId) => {
3782
3824
  const nodes = [];
3783
3825
  const edges = [];
@@ -3794,8 +3836,8 @@ var generateNodesAndEdges = (event, onEventSelect, parentId) => {
3794
3836
  id: event.span_id,
3795
3837
  position: { x: 0, y: 0 },
3796
3838
  // Will be set by layout
3797
- sourcePosition: import_react12.Position.Right,
3798
- targetPosition: import_react12.Position.Left,
3839
+ sourcePosition: import_react13.Position.Right,
3840
+ targetPosition: import_react13.Position.Left,
3799
3841
  type: "service"
3800
3842
  });
3801
3843
  if (parentId) {
@@ -3805,7 +3847,7 @@ var generateNodesAndEdges = (event, onEventSelect, parentId) => {
3805
3847
  markerEnd: {
3806
3848
  color: "lightgray",
3807
3849
  height: 16,
3808
- type: import_react12.MarkerType.Arrow,
3850
+ type: import_react13.MarkerType.Arrow,
3809
3851
  width: 16
3810
3852
  },
3811
3853
  source: parentId,
@@ -3879,12 +3921,12 @@ var TraceGraph = ({
3879
3921
  spans,
3880
3922
  viewPortPixelWidth
3881
3923
  }) => {
3882
- const [nodes, setNodes] = (0, import_react14.useState)([]);
3883
- const [edges, setEdges] = (0, import_react14.useState)([]);
3884
- const [initialViewSet, setInitialViewSet] = (0, import_react14.useState)(false);
3885
- const { fitView, setCenter } = (0, import_react13.useReactFlow)();
3886
- const store = (0, import_react13.useStoreApi)();
3887
- const updateSelectedNode = (0, import_react14.useCallback)(
3924
+ const [nodes, setNodes] = (0, import_react15.useState)([]);
3925
+ const [edges, setEdges] = (0, import_react15.useState)([]);
3926
+ const [initialViewSet, setInitialViewSet] = (0, import_react15.useState)(false);
3927
+ const { fitView, setCenter } = (0, import_react14.useReactFlow)();
3928
+ const store = (0, import_react14.useStoreApi)();
3929
+ const updateSelectedNode = (0, import_react15.useCallback)(
3888
3930
  (nodeId) => {
3889
3931
  const { addSelectedNodes } = store.getState();
3890
3932
  if (nodeId) {
@@ -3896,7 +3938,7 @@ var TraceGraph = ({
3896
3938
  },
3897
3939
  [nodes, store]
3898
3940
  );
3899
- (0, import_react14.useEffect)(() => {
3941
+ (0, import_react15.useEffect)(() => {
3900
3942
  const spansMap = /* @__PURE__ */ new Map();
3901
3943
  const rootSpans = [];
3902
3944
  for (const span of spans.data ?? []) {
@@ -3928,7 +3970,7 @@ var TraceGraph = ({
3928
3970
  setNodes(layoutedNodes);
3929
3971
  setEdges(layoutedEdges);
3930
3972
  }, [onEventSelect, spans.data]);
3931
- (0, import_react14.useEffect)(() => {
3973
+ (0, import_react15.useEffect)(() => {
3932
3974
  const shouldSetInitialView = !spans.loading && nodes.length > 0 && !initialViewSet;
3933
3975
  if (shouldSetInitialView) {
3934
3976
  if (initialFocusEventId) {
@@ -3948,12 +3990,12 @@ var TraceGraph = ({
3948
3990
  setInitialViewSet(true);
3949
3991
  }
3950
3992
  }, [spans.loading, nodes, initialFocusEventId, viewPortPixelWidth, setCenter, fitView, onEventSelect, initialViewSet]);
3951
- (0, import_react14.useEffect)(() => {
3993
+ (0, import_react15.useEffect)(() => {
3952
3994
  if (initialFocusEventId) {
3953
3995
  updateSelectedNode(initialFocusEventId);
3954
3996
  }
3955
3997
  }, [initialFocusEventId, updateSelectedNode]);
3956
- const onNodeClick = (0, import_react14.useCallback)((_event, node) => {
3998
+ const onNodeClick = (0, import_react15.useCallback)((_event, node) => {
3957
3999
  onEventSelect(node.data.event);
3958
4000
  updateSelectedNode(node.id);
3959
4001
  }, [onEventSelect, updateSelectedNode]);
@@ -3973,7 +4015,7 @@ var TraceGraph = ({
3973
4015
  }
3974
4016
  ),
3975
4017
  /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(
3976
- import_react13.ReactFlow,
4018
+ import_react14.ReactFlow,
3977
4019
  {
3978
4020
  "data-testid": "trace-graph",
3979
4021
  defaultViewport: { x: 0, y: 0, zoom: 1 },
@@ -3986,8 +4028,8 @@ var TraceGraph = ({
3986
4028
  onNodeClick,
3987
4029
  selectNodesOnDrag: false,
3988
4030
  children: [
3989
- /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_react13.Controls, { showInteractive: false }),
3990
- /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_react13.Background, {})
4031
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_react14.Controls, { showInteractive: false }),
4032
+ /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(import_react14.Background, {})
3991
4033
  ]
3992
4034
  }
3993
4035
  )
@@ -4031,10 +4073,10 @@ var TraceGraphPage = () => {
4031
4073
  const [searchParameters] = (0, import_react_router_dom2.useSearchParams)();
4032
4074
  const spanId = searchParameters.get("spanId");
4033
4075
  const api = useAppInspectorApi();
4034
- const [spans, setSpans] = (0, import_react16.useState)();
4035
- const [loading, setLoading] = (0, import_react16.useState)(false);
4036
- const [fetchError, setFetchError] = (0, import_react16.useState)();
4037
- const fetchSpans = (0, import_react16.useCallback)(async () => {
4076
+ const [spans, setSpans] = (0, import_react17.useState)();
4077
+ const [loading, setLoading] = (0, import_react17.useState)(false);
4078
+ const [fetchError, setFetchError] = (0, import_react17.useState)();
4079
+ const fetchSpans = (0, import_react17.useCallback)(async () => {
4038
4080
  setLoading(true);
4039
4081
  try {
4040
4082
  const response = await api.getSpans({
@@ -4049,14 +4091,14 @@ var TraceGraphPage = () => {
4049
4091
  setLoading(false);
4050
4092
  }
4051
4093
  }, [api, traceId]);
4052
- (0, import_react16.useEffect)(() => {
4094
+ (0, import_react17.useEffect)(() => {
4053
4095
  void fetchSpans();
4054
4096
  }, [fetchSpans]);
4055
- const [open, setOpen] = (0, import_react16.useState)(true);
4056
- const [selectedEvent, setSelectedEvent] = (0, import_react16.useState)();
4057
- const [viewPortPixelWidth, setViewPortPixelWidth] = (0, import_react16.useState)(0);
4097
+ const [open, setOpen] = (0, import_react17.useState)(true);
4098
+ const [selectedEvent, setSelectedEvent] = (0, import_react17.useState)();
4099
+ const [viewPortPixelWidth, setViewPortPixelWidth] = (0, import_react17.useState)(0);
4058
4100
  const { checkStatus, error: statusError, status } = useStatus();
4059
- const calculateDrawerWidth = (0, import_react16.useCallback)(() => {
4101
+ const calculateDrawerWidth = (0, import_react17.useCallback)(() => {
4060
4102
  const percentageMatch = /(\d+)%/.exec(DRAWER_WIDTH);
4061
4103
  if (percentageMatch && open) {
4062
4104
  const percentage = Number.parseInt(percentageMatch[1], 10);
@@ -4064,7 +4106,7 @@ var TraceGraphPage = () => {
4064
4106
  }
4065
4107
  return 0;
4066
4108
  }, [open]);
4067
- (0, import_react16.useEffect)(() => {
4109
+ (0, import_react17.useEffect)(() => {
4068
4110
  const updateViewportWidth = () => {
4069
4111
  const totalWidth = window.innerWidth;
4070
4112
  const drawerPixelWidth = open ? calculateDrawerWidth() : 0;
@@ -4078,11 +4120,11 @@ var TraceGraphPage = () => {
4078
4120
  clearTimeout(timeoutId);
4079
4121
  };
4080
4122
  }, [open, calculateDrawerWidth]);
4081
- const handleEventSelect = (0, import_react16.useCallback)((event) => {
4123
+ const handleEventSelect = (0, import_react17.useCallback)((event) => {
4082
4124
  setSelectedEvent(event);
4083
4125
  setOpen(true);
4084
4126
  }, []);
4085
- const handleRetry = (0, import_react16.useCallback)(() => {
4127
+ const handleRetry = (0, import_react17.useCallback)(() => {
4086
4128
  void checkStatus();
4087
4129
  }, [checkStatus]);
4088
4130
  const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
@@ -4122,7 +4164,7 @@ var TraceGraphPage = () => {
4122
4164
  height: "100%",
4123
4165
  overflow: "auto"
4124
4166
  },
4125
- children: traceId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(import_react15.ReactFlowProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
4167
+ children: traceId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(import_react16.ReactFlowProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime135.jsx)(
4126
4168
  TraceGraph,
4127
4169
  {
4128
4170
  initialFocusEventId: spanId,