@localstack/appinspector-ui 1.0.60 → 1.0.62

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
@@ -77,7 +77,7 @@ module.exports = __toCommonJS(index_exports);
77
77
 
78
78
  // src/pages/spans-list-page.tsx
79
79
  var import_material20 = require("@mui/material");
80
- var import_react61 = require("react");
80
+ var import_react62 = require("react");
81
81
 
82
82
  // src/components/spans-list/spans-list.tsx
83
83
  var import_material5 = require("@mui/material");
@@ -12148,6 +12148,16 @@ var newSpanBackgroundColor = {
12148
12148
  dark: "#887b02",
12149
12149
  light: "#ffde7b"
12150
12150
  };
12151
+ var LABEL_BEGINNING_OF_STREAM = "This is the beginning of the stream";
12152
+ var LABEL_END_OF_STREAM = "This is the end of the stream";
12153
+ var LABEL_NO_SPANS = "There are no spans";
12154
+ var LABEL_LOAD_OLDER = "Load older spans";
12155
+ var LABEL_LOAD_NEWER = "Load newer spans";
12156
+ var StreamBoundaryRow = ({ colSpan, label }) => /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableCell, { colSpan, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)("span", { children: label }) }) });
12157
+ var LoadSpansRow = ({ colSpan, fetching, label, onFetch }) => /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime124.jsxs)(import_material4.TableCell, { colSpan, sx: { textAlign: "center" }, children: [
12158
+ !fetching && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.Button, { onClick: onFetch, sx: { my: 1 }, children: label }),
12159
+ fetching && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.CircularProgress, { size: 24, sx: { m: 2 } })
12160
+ ] }) });
12151
12161
  var SpansDataGridRow = (0, import_react40.memo)(
12152
12162
  ({ row }) => {
12153
12163
  const theme = (0, import_material4.useTheme)();
@@ -12203,12 +12213,18 @@ var SpansDataGridRow = (0, import_react40.memo)(
12203
12213
  var SpansDataGrid = ({
12204
12214
  clearingSpans,
12205
12215
  fetchingBackward,
12216
+ fetchingForward,
12206
12217
  hasMoreBackward,
12207
12218
  hasMoreForward,
12208
12219
  onClearSpans,
12209
12220
  onFetchBackward,
12221
+ onFetchForward,
12222
+ onOrderChange,
12210
12223
  onSpanClick,
12211
- spans
12224
+ onToggleStream,
12225
+ order: order2,
12226
+ spans,
12227
+ streamPaused
12212
12228
  }) => {
12213
12229
  const columns = (0, import_react40.useMemo)(() => [
12214
12230
  columnHelper.accessor("trace_id", {
@@ -12297,6 +12313,38 @@ var SpansDataGrid = ({
12297
12313
  return /* @__PURE__ */ (0, import_jsx_runtime124.jsxs)(import_jsx_runtime124.Fragment, { children: [
12298
12314
  /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.Grid, { item: true, xs: 12, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsxs)(import_material4.Box, { sx: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
12299
12315
  /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.Box, { sx: { flexGrow: 1 } }),
12316
+ /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(
12317
+ import_material4.FormControlLabel,
12318
+ {
12319
+ control: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(
12320
+ import_material4.Button,
12321
+ {
12322
+ onClick: onToggleStream,
12323
+ startIcon: streamPaused ? /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_icons_material.PlayArrowOutlined, {}) : /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_icons_material.PauseOutlined, {}),
12324
+ variant: "text",
12325
+ children: streamPaused ? "Resume Stream" : "Pause Stream"
12326
+ }
12327
+ ),
12328
+ label: ""
12329
+ }
12330
+ ),
12331
+ /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(
12332
+ import_material4.FormControlLabel,
12333
+ {
12334
+ control: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(
12335
+ import_material4.Button,
12336
+ {
12337
+ onClick: () => {
12338
+ onOrderChange(order2 === "newest_first" ? "oldest_first" : "newest_first");
12339
+ },
12340
+ startIcon: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_icons_material.SwapVertOutlined, {}),
12341
+ variant: "text",
12342
+ children: order2 === "newest_first" ? "Newest First" : "Oldest First"
12343
+ }
12344
+ ),
12345
+ label: ""
12346
+ }
12347
+ ),
12300
12348
  /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(
12301
12349
  import_material4.FormControlLabel,
12302
12350
  {
@@ -12354,21 +12402,30 @@ var SpansDataGrid = ({
12354
12402
  }) }),
12355
12403
  /* @__PURE__ */ (0, import_jsx_runtime124.jsxs)(import_material4.TableBody, { children: [
12356
12404
  spans === void 0 && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.CircularProgress, { size: 48, sx: { m: 4 } }) }) }),
12357
- spans?.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)("span", { children: "There are no spans" }) }) }),
12358
- hasRows && !hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)("span", { children: "This is the beginning of the stream" }) }) }),
12359
- hasRows && hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime124.jsxs)(import_material4.TableCell, { colSpan: columnCount, sx: { textAlign: "center" }, children: [
12360
- !fetchingBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(
12361
- import_material4.Button,
12362
- {
12363
- onClick: onFetchBackward,
12364
- sx: { my: 1 },
12365
- children: "Load older spans"
12405
+ spans?.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_NO_SPANS }),
12406
+ order2 === "newest_first" && /* @__PURE__ */ (0, import_jsx_runtime124.jsxs)(import_jsx_runtime124.Fragment, { children: [
12407
+ hasRows && hasMoreForward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(LoadSpansRow, { colSpan: columnCount, fetching: fetchingForward, label: LABEL_LOAD_NEWER, onFetch: onFetchForward }),
12408
+ hasRows && !hasMoreForward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_END_OF_STREAM }),
12409
+ hasRows && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(AnimatePresence, { initial: false, children: (() => {
12410
+ const reversed = [];
12411
+ for (let index2 = rows.length - 1; index2 >= 0; index2--) {
12412
+ const row = rows.at(index2);
12413
+ reversed.push(
12414
+ /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(SpansDataGridRow, { row }, row.original.span_id)
12415
+ );
12366
12416
  }
12367
- ),
12368
- fetchingBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.CircularProgress, { size: 24, sx: { m: 2 } })
12369
- ] }) }),
12370
- hasRows && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(AnimatePresence, { initial: false, children: rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(SpansDataGridRow, { row }, row.original.span_id)) }),
12371
- hasRows && !hasMoreForward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableRow, { children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(import_material4.TableCell, { colSpan: columnCount, sx: { fontStyle: "italic", textAlign: "center" }, children: /* @__PURE__ */ (0, import_jsx_runtime124.jsx)("span", { children: "This is the end of the stream" }) }) })
12417
+ return reversed;
12418
+ })() }),
12419
+ hasRows && hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(LoadSpansRow, { colSpan: columnCount, fetching: fetchingBackward, label: LABEL_LOAD_OLDER, onFetch: onFetchBackward }),
12420
+ hasRows && !hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_BEGINNING_OF_STREAM })
12421
+ ] }),
12422
+ order2 === "oldest_first" && /* @__PURE__ */ (0, import_jsx_runtime124.jsxs)(import_jsx_runtime124.Fragment, { children: [
12423
+ hasRows && !hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_BEGINNING_OF_STREAM }),
12424
+ hasRows && hasMoreBackward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(LoadSpansRow, { colSpan: columnCount, fetching: fetchingBackward, label: LABEL_LOAD_OLDER, onFetch: onFetchBackward }),
12425
+ hasRows && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(AnimatePresence, { initial: false, children: rows.map((row) => /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(SpansDataGridRow, { row }, row.original.span_id)) }),
12426
+ hasRows && hasMoreForward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(LoadSpansRow, { colSpan: columnCount, fetching: fetchingForward, label: LABEL_LOAD_NEWER, onFetch: onFetchForward }),
12427
+ hasRows && !hasMoreForward && /* @__PURE__ */ (0, import_jsx_runtime124.jsx)(StreamBoundaryRow, { colSpan: columnCount, label: LABEL_END_OF_STREAM })
12428
+ ] })
12372
12429
  ] })
12373
12430
  ]
12374
12431
  }
@@ -12405,9 +12462,12 @@ var SpansList = (props) => {
12405
12462
  onClearSpans: props.onClearSpans,
12406
12463
  onFetchBackward: props.onFetchBackward,
12407
12464
  onFetchForward: props.onFetchForward,
12465
+ onOrderChange: props.onOrderChange,
12408
12466
  onSpanClick: props.onSpanClick,
12409
- refetching: props.refetching,
12410
- spans: props.spans
12467
+ onToggleStream: props.onToggleStream,
12468
+ order: props.order,
12469
+ spans: props.spans,
12470
+ streamPaused: props.streamPaused
12411
12471
  }
12412
12472
  )
12413
12473
  ] });
@@ -12710,18 +12770,63 @@ var StatusMessage = ({
12710
12770
  return /* @__PURE__ */ (0, import_jsx_runtime126.jsx)(import_jsx_runtime126.Fragment, {});
12711
12771
  };
12712
12772
 
12773
+ // src/hooks/use-local-storage.tsx
12774
+ var import_react41 = require("react");
12775
+ function useLocalStorage(key, initialValue) {
12776
+ const [storedValue, setStoredValue] = (0, import_react41.useState)(() => {
12777
+ try {
12778
+ const item = globalThis.localStorage.getItem(key);
12779
+ return item ? JSON.parse(item) : initialValue;
12780
+ } catch (error) {
12781
+ console.error(`Error reading localStorage key "${key}":`, error);
12782
+ return initialValue;
12783
+ }
12784
+ });
12785
+ const setValue = (0, import_react41.useCallback)((value) => {
12786
+ try {
12787
+ setStoredValue((previousState) => {
12788
+ const next = typeof value === "function" ? value(previousState) : value;
12789
+ globalThis.localStorage.setItem(key, JSON.stringify(next));
12790
+ globalThis.dispatchEvent(new StorageEvent("storage", {
12791
+ key,
12792
+ newValue: JSON.stringify(next)
12793
+ }));
12794
+ return next;
12795
+ });
12796
+ } catch (error) {
12797
+ console.error(`Error setting localStorage key "${key}":`, error);
12798
+ }
12799
+ }, [key]);
12800
+ (0, import_react41.useEffect)(() => {
12801
+ const handleStorageChange = (event) => {
12802
+ if (event.key === key && event.newValue !== null) {
12803
+ try {
12804
+ setStoredValue(JSON.parse(event.newValue));
12805
+ } catch (error) {
12806
+ console.error(`Error parsing localStorage key "${key}":`, error);
12807
+ }
12808
+ }
12809
+ };
12810
+ globalThis.addEventListener("storage", handleStorageChange);
12811
+ return () => {
12812
+ globalThis.removeEventListener("storage", handleStorageChange);
12813
+ };
12814
+ }, [key]);
12815
+ return [storedValue, setValue];
12816
+ }
12817
+
12713
12818
  // src/hooks/use-spans.ts
12714
- var import_react46 = require("react");
12819
+ var import_react47 = require("react");
12715
12820
 
12716
12821
  // src/api/use-api.tsx
12717
- var import_react41 = require("react");
12822
+ var import_react42 = require("react");
12718
12823
  var import_jsx_runtime127 = require("react/jsx-runtime");
12719
- var AppInspectorApiContext = (0, import_react41.createContext)(void 0);
12824
+ var AppInspectorApiContext = (0, import_react42.createContext)(void 0);
12720
12825
  var ApiProvider = (props) => {
12721
12826
  return /* @__PURE__ */ (0, import_jsx_runtime127.jsx)(AppInspectorApiContext.Provider, { value: props.api, children: props.children });
12722
12827
  };
12723
12828
  var useAppInspectorApi = () => {
12724
- const api = (0, import_react41.useContext)(AppInspectorApiContext);
12829
+ const api = (0, import_react42.useContext)(AppInspectorApiContext);
12725
12830
  if (!api) {
12726
12831
  throw new Error("useAppInspectorApi must be used within AppInspectorApiProvider");
12727
12832
  }
@@ -12729,15 +12834,15 @@ var useAppInspectorApi = () => {
12729
12834
  };
12730
12835
 
12731
12836
  // src/hooks/use-status.tsx
12732
- var import_react42 = require("react");
12837
+ var import_react43 = require("react");
12733
12838
  var useStatus = () => {
12734
12839
  const api = useAppInspectorApi();
12735
- const [checking, setChecking] = (0, import_react42.useState)(true);
12736
- const [status, setStatus] = (0, import_react42.useState)();
12737
- const [error, setError] = (0, import_react42.useState)();
12738
- const hasFetchedReference = (0, import_react42.useRef)(false);
12739
- const abortControllerReference = (0, import_react42.useRef)(null);
12740
- const checkStatus = (0, import_react42.useCallback)(async () => {
12840
+ const [checking, setChecking] = (0, import_react43.useState)(true);
12841
+ const [status, setStatus] = (0, import_react43.useState)();
12842
+ const [error, setError] = (0, import_react43.useState)();
12843
+ const hasFetchedReference = (0, import_react43.useRef)(false);
12844
+ const abortControllerReference = (0, import_react43.useRef)(null);
12845
+ const checkStatus = (0, import_react43.useCallback)(async () => {
12741
12846
  if (abortControllerReference.current !== null) {
12742
12847
  abortControllerReference.current.abort();
12743
12848
  }
@@ -12761,7 +12866,7 @@ var useStatus = () => {
12761
12866
  }
12762
12867
  }
12763
12868
  }, [api]);
12764
- (0, import_react42.useEffect)(() => {
12869
+ (0, import_react43.useEffect)(() => {
12765
12870
  if (!hasFetchedReference.current) {
12766
12871
  hasFetchedReference.current = true;
12767
12872
  void checkStatus();
@@ -12812,7 +12917,6 @@ var createPaginationBuffer = (options) => {
12812
12917
  let hasMoreBackward = void 0;
12813
12918
  let fetchingForward = false;
12814
12919
  let fetchingBackward = false;
12815
- const refetching = false;
12816
12920
  const reportDataChange = () => {
12817
12921
  options.onDataChange({
12818
12922
  hasMoreBackward: hasMoreBackward ?? false,
@@ -12823,8 +12927,7 @@ var createPaginationBuffer = (options) => {
12823
12927
  const reportStatusChange = () => {
12824
12928
  options.onStatusChange?.({
12825
12929
  fetchingBackward,
12826
- fetchingForward,
12827
- refetching
12930
+ fetchingForward
12828
12931
  });
12829
12932
  };
12830
12933
  const reportError = (error) => {
@@ -12832,6 +12935,25 @@ var createPaginationBuffer = (options) => {
12832
12935
  };
12833
12936
  let fetchForwardLater = false;
12834
12937
  let fetchBackwardLater = false;
12938
+ let fetchForwardSilentlyLater = false;
12939
+ const checkIfThereAreMoreItemsForward = async () => {
12940
+ if (hasMoreForward === true) {
12941
+ return;
12942
+ }
12943
+ fetchingForward = true;
12944
+ reportStatusChange();
12945
+ try {
12946
+ const newPage = await fetchPage(nextForwardToken);
12947
+ hasMoreForward = newPage.items.length > 0;
12948
+ reportDataChange();
12949
+ } catch (error) {
12950
+ reportError(error instanceof Error ? error : new Error("Failed to fetch forward page", { cause: error }));
12951
+ } finally {
12952
+ fetchingForward = false;
12953
+ reportStatusChange();
12954
+ }
12955
+ runPostFetchActions();
12956
+ };
12835
12957
  const fetchForward = async () => {
12836
12958
  fetchingForward = true;
12837
12959
  reportStatusChange();
@@ -12895,8 +13017,19 @@ var createPaginationBuffer = (options) => {
12895
13017
  fetchForwardLater = false;
12896
13018
  void fetchForward();
12897
13019
  }
13020
+ if (fetchForwardSilentlyLater) {
13021
+ fetchForwardSilentlyLater = false;
13022
+ void checkIfThereAreMoreItemsForward();
13023
+ }
12898
13024
  };
12899
13025
  return {
13026
+ checkIfThereAreMoreItemsForward: () => {
13027
+ if (fetchingForward || fetchingBackward) {
13028
+ fetchForwardSilentlyLater = true;
13029
+ return;
13030
+ }
13031
+ void checkIfThereAreMoreItemsForward();
13032
+ },
12900
13033
  clear: () => {
12901
13034
  if (items !== void 0) {
12902
13035
  items.length = 0;
@@ -12919,11 +13052,11 @@ var createPaginationBuffer = (options) => {
12919
13052
  };
12920
13053
 
12921
13054
  // src/hooks/use-spans-ws.tsx
12922
- var import_react45 = require("react");
13055
+ var import_react46 = require("react");
12923
13056
 
12924
13057
  // src/context.tsx
12925
- var import_react43 = require("react");
12926
13058
  var import_react44 = require("react");
13059
+ var import_react45 = require("react");
12927
13060
 
12928
13061
  // src/utils/time.ts
12929
13062
  function unixNanoToDate(unixNanoString) {
@@ -13116,19 +13249,19 @@ var createApiClient = ({ localstackEndpoint }) => {
13116
13249
 
13117
13250
  // src/context.tsx
13118
13251
  var import_jsx_runtime128 = require("react/jsx-runtime");
13119
- var AppInspectorContext = (0, import_react43.createContext)(void 0);
13252
+ var AppInspectorContext = (0, import_react44.createContext)(void 0);
13120
13253
  var useAppInspector = () => {
13121
- const context = (0, import_react43.useContext)(AppInspectorContext);
13254
+ const context = (0, import_react44.useContext)(AppInspectorContext);
13122
13255
  if (!context) {
13123
13256
  throw new Error("@localstack-studio/ui: components must be used within a <AppInspectorContextProvider>");
13124
13257
  }
13125
13258
  return context;
13126
13259
  };
13127
13260
  var AppInspectorContextProvider = (props) => {
13128
- const api = (0, import_react44.useMemo)(() => {
13261
+ const api = (0, import_react45.useMemo)(() => {
13129
13262
  return false ? createApiClientMock() : createApiClient({ localstackEndpoint: props.localstackEndpoint });
13130
13263
  }, [props.localstackEndpoint]);
13131
- const resolveLink = (0, import_react44.useCallback)(
13264
+ const resolveLink = (0, import_react45.useCallback)(
13132
13265
  (options) => {
13133
13266
  if (options.to === "settings") {
13134
13267
  return `${props.routePrefix}/settings`;
@@ -13140,7 +13273,7 @@ var AppInspectorContextProvider = (props) => {
13140
13273
  },
13141
13274
  [props.routePrefix]
13142
13275
  );
13143
- const contextValue = (0, import_react44.useMemo)(
13276
+ const contextValue = (0, import_react45.useMemo)(
13144
13277
  () => ({
13145
13278
  linkComponent: props.linkComponent,
13146
13279
  localstackEndpoint: props.localstackEndpoint,
@@ -13154,15 +13287,15 @@ var AppInspectorContextProvider = (props) => {
13154
13287
  // src/hooks/use-spans-ws.tsx
13155
13288
  function useSpansWebSocket(options) {
13156
13289
  const { onMessage } = options;
13157
- const onMessageRef = (0, import_react45.useRef)(onMessage);
13158
- (0, import_react45.useEffect)(() => {
13290
+ const onMessageRef = (0, import_react46.useRef)(onMessage);
13291
+ (0, import_react46.useEffect)(() => {
13159
13292
  onMessageRef.current = onMessage;
13160
13293
  }, [onMessage]);
13161
- const [connected, setConnected] = (0, import_react45.useState)(false);
13162
- const wsRef = (0, import_react45.useRef)(void 0);
13163
- const reconnectRef = (0, import_react45.useRef)(void 0);
13294
+ const [connected, setConnected] = (0, import_react46.useState)(false);
13295
+ const wsRef = (0, import_react46.useRef)(void 0);
13296
+ const reconnectRef = (0, import_react46.useRef)(void 0);
13164
13297
  const { localstackEndpoint } = useAppInspector();
13165
- const connect = (0, import_react45.useCallback)(() => {
13298
+ const connect = (0, import_react46.useCallback)(() => {
13166
13299
  if (wsRef.current !== void 0) return;
13167
13300
  const url = new URL(getAppInspectorApiUrl(localstackEndpoint, API_ENDPOINTS.WEBSOCKET_SPANS));
13168
13301
  url.protocol = globalThis.location.protocol === "https:" ? "wss" : "ws";
@@ -13188,7 +13321,7 @@ function useSpansWebSocket(options) {
13188
13321
  }
13189
13322
  });
13190
13323
  }, [localstackEndpoint]);
13191
- (0, import_react45.useEffect)(() => {
13324
+ (0, import_react46.useEffect)(() => {
13192
13325
  connect();
13193
13326
  return () => {
13194
13327
  if (reconnectRef.current !== void 0) clearTimeout(reconnectRef.current);
@@ -13208,12 +13341,11 @@ function useSpansWebSocket(options) {
13208
13341
  var PAGE_SIZE = 30;
13209
13342
  var useSpans = () => {
13210
13343
  const api = useAppInspectorApi();
13211
- const [spans, setSpans] = (0, import_react46.useState)();
13212
- const [fetchError, setFetchError] = (0, import_react46.useState)();
13213
- const [fetchingForward, setFetchingForward] = (0, import_react46.useState)(false);
13214
- const [fetchingBackward, setFetchingBackward] = (0, import_react46.useState)(false);
13215
- const [refetching, setRefetching] = (0, import_react46.useState)(false);
13216
- const paginationBuffer = (0, import_react46.useRef)(createPaginationBuffer({
13344
+ const [spans, setSpans] = (0, import_react47.useState)();
13345
+ const [fetchError, setFetchError] = (0, import_react47.useState)();
13346
+ const [fetchingForward, setFetchingForward] = (0, import_react47.useState)(false);
13347
+ const [fetchingBackward, setFetchingBackward] = (0, import_react47.useState)(false);
13348
+ const paginationBuffer = (0, import_react47.useRef)(createPaginationBuffer({
13217
13349
  async fetchPage(token) {
13218
13350
  const response = await api.getSpans({
13219
13351
  limit: PAGE_SIZE,
@@ -13239,7 +13371,6 @@ var useSpans = () => {
13239
13371
  onStatusChange(status2) {
13240
13372
  setFetchingBackward(status2.fetchingBackward);
13241
13373
  setFetchingForward(status2.fetchingForward);
13242
- setRefetching(status2.refetching);
13243
13374
  },
13244
13375
  // The spans endpoint is sorted by span ingestion time, which might differ from
13245
13376
  // the span timestamp. In order to accomodate for this, we will sort the spans
@@ -13248,20 +13379,20 @@ var useSpans = () => {
13248
13379
  return a2.start_time_unix_nano < b2.start_time_unix_nano ? -1 : 1;
13249
13380
  }
13250
13381
  }));
13251
- const [hasMoreBackward, setHasMoreBackward] = (0, import_react46.useState)();
13252
- const [hasMoreForward, setHasMoreForward] = (0, import_react46.useState)();
13253
- const fetchForward = (0, import_react46.useCallback)(() => {
13382
+ const [hasMoreBackward, setHasMoreBackward] = (0, import_react47.useState)();
13383
+ const [hasMoreForward, setHasMoreForward] = (0, import_react47.useState)();
13384
+ const fetchForward = (0, import_react47.useCallback)(() => {
13254
13385
  paginationBuffer.current.fetchForward();
13255
13386
  }, []);
13256
- const fetchBackward = (0, import_react46.useCallback)(() => {
13387
+ const fetchBackward = (0, import_react47.useCallback)(() => {
13257
13388
  paginationBuffer.current.fetchBackward();
13258
13389
  }, []);
13259
- (0, import_react46.useEffect)(() => {
13390
+ (0, import_react47.useEffect)(() => {
13260
13391
  fetchForward();
13261
13392
  }, [fetchForward]);
13262
13393
  const { checkStatus, error: statusError, status } = useStatus();
13263
- const [clearingSpans, setClearingSpans] = (0, import_react46.useState)(false);
13264
- const clearSpans = (0, import_react46.useCallback)(async () => {
13394
+ const [clearingSpans, setClearingSpans] = (0, import_react47.useState)(false);
13395
+ const clearSpans = (0, import_react47.useCallback)(async () => {
13265
13396
  setClearingSpans(true);
13266
13397
  try {
13267
13398
  await api.deleteSpans();
@@ -13273,9 +13404,19 @@ var useSpans = () => {
13273
13404
  setClearingSpans(false);
13274
13405
  }
13275
13406
  }, [paginationBuffer, api]);
13407
+ const [streamPaused, setStreamPaused] = (0, import_react47.useState)(false);
13408
+ const toggleStream = (0, import_react47.useCallback)(() => {
13409
+ setStreamPaused((previous) => !previous);
13410
+ }, []);
13276
13411
  useSpansWebSocket({
13277
13412
  onMessage: () => {
13278
- paginationBuffer.current.fetchForward();
13413
+ if (!hasMoreForward) {
13414
+ if (streamPaused) {
13415
+ paginationBuffer.current.checkIfThereAreMoreItemsForward();
13416
+ } else {
13417
+ paginationBuffer.current.fetchForward();
13418
+ }
13419
+ }
13279
13420
  }
13280
13421
  });
13281
13422
  return {
@@ -13289,10 +13430,11 @@ var useSpans = () => {
13289
13430
  fetchingForward,
13290
13431
  hasMoreBackward,
13291
13432
  hasMoreForward,
13292
- refetching,
13293
13433
  spans,
13294
13434
  status,
13295
- statusError
13435
+ statusError,
13436
+ streamPaused,
13437
+ toggleStream
13296
13438
  };
13297
13439
  };
13298
13440
 
@@ -13300,12 +13442,12 @@ var useSpans = () => {
13300
13442
  var import_icons_material11 = require("@mui/icons-material");
13301
13443
  var import_material19 = require("@mui/material");
13302
13444
  var import_styles = require("@mui/material/styles");
13303
- var import_react59 = require("@xyflow/react");
13304
- var import_react60 = require("react");
13445
+ var import_react60 = require("@xyflow/react");
13446
+ var import_react61 = require("react");
13305
13447
 
13306
13448
  // src/components/event-details/event-details.tsx
13307
13449
  var import_material14 = require("@mui/material");
13308
- var import_react50 = require("react");
13450
+ var import_react51 = require("react");
13309
13451
 
13310
13452
  // src/utils/iam-utils.ts
13311
13453
  function determinePermissionStatus(payload) {
@@ -13539,7 +13681,7 @@ var import_material13 = require("@mui/material");
13539
13681
  // src/components/event-details/event-detail.tsx
13540
13682
  var import_icons_material7 = require("@mui/icons-material");
13541
13683
  var import_material11 = require("@mui/material");
13542
- var import_react48 = require("react");
13684
+ var import_react49 = require("react");
13543
13685
 
13544
13686
  // src/components/status-icon.tsx
13545
13687
  var import_icons_material4 = require("@mui/icons-material");
@@ -13690,7 +13832,7 @@ var IAMEventDetail = ({ event }) => {
13690
13832
  // src/components/event-details/iam-permission-detail.tsx
13691
13833
  var import_icons_material6 = require("@mui/icons-material");
13692
13834
  var import_material10 = require("@mui/material");
13693
- var import_react47 = require("react");
13835
+ var import_react48 = require("react");
13694
13836
  var import_jsx_runtime132 = require("react/jsx-runtime");
13695
13837
  var getChipColors = (status) => {
13696
13838
  const isAllowed = status === "explicitly_allowed" || status === "implicitly_allowed";
@@ -13700,8 +13842,8 @@ var getChipColors = (status) => {
13700
13842
  };
13701
13843
  };
13702
13844
  var IAMPermissionItem = ({ event }) => {
13703
- const [isOpen, setIsOpen] = (0, import_react47.useState)(false);
13704
- const parsedData = (0, import_react47.useMemo)(() => {
13845
+ const [isOpen, setIsOpen] = (0, import_react48.useState)(false);
13846
+ const parsedData = (0, import_react48.useMemo)(() => {
13705
13847
  const payloadString = event.attributes?.payload;
13706
13848
  if (!payloadString) {
13707
13849
  return;
@@ -13771,15 +13913,15 @@ var DetailRow2 = ({ content, label }) => /* @__PURE__ */ (0, import_jsx_runtime1
13771
13913
  ) : content })
13772
13914
  ] });
13773
13915
  var EventMessage = ({ event }) => {
13774
- const [isOpen, setIsOpen] = (0, import_react48.useState)(false);
13775
- const [isOverflowing, setIsOverflowing] = (0, import_react48.useState)(false);
13776
- const textReference = (0, import_react48.useRef)(null);
13777
- const parsedMessage = (0, import_react48.useMemo)(() => parseEventMessage(event), [event]);
13778
- const isIAMPolicyEvent = (0, import_react48.useMemo)(
13916
+ const [isOpen, setIsOpen] = (0, import_react49.useState)(false);
13917
+ const [isOverflowing, setIsOverflowing] = (0, import_react49.useState)(false);
13918
+ const textReference = (0, import_react49.useRef)(null);
13919
+ const parsedMessage = (0, import_react49.useMemo)(() => parseEventMessage(event), [event]);
13920
+ const isIAMPolicyEvent = (0, import_react49.useMemo)(
13779
13921
  () => event.event_type === "iam.policy_evaluation" && event.attributes?.payload && typeof event.attributes.payload === "string",
13780
13922
  [event]
13781
13923
  );
13782
- (0, import_react48.useEffect)(() => {
13924
+ (0, import_react49.useEffect)(() => {
13783
13925
  const checkOverflow = () => {
13784
13926
  const element = textReference.current;
13785
13927
  if (element) {
@@ -13792,11 +13934,11 @@ var EventMessage = ({ event }) => {
13792
13934
  window.removeEventListener("resize", checkOverflow);
13793
13935
  };
13794
13936
  }, [parsedMessage.headline]);
13795
- const hasAdditionalContent = (0, import_react48.useMemo)(
13937
+ const hasAdditionalContent = (0, import_react49.useMemo)(
13796
13938
  () => parsedMessage.message || parsedMessage.details || isIAMPolicyEvent,
13797
13939
  [parsedMessage.message, parsedMessage.details, isIAMPolicyEvent]
13798
13940
  );
13799
- const shouldShowToggle = (0, import_react48.useMemo)(
13941
+ const shouldShowToggle = (0, import_react49.useMemo)(
13800
13942
  () => isOverflowing || hasAdditionalContent,
13801
13943
  [isOverflowing, hasAdditionalContent]
13802
13944
  );
@@ -13938,10 +14080,10 @@ var EventDetail = ({
13938
14080
  // src/components/event-details/toggle-section.tsx
13939
14081
  var import_icons_material8 = require("@mui/icons-material");
13940
14082
  var import_material12 = require("@mui/material");
13941
- var import_react49 = require("react");
14083
+ var import_react50 = require("react");
13942
14084
  var import_jsx_runtime134 = require("react/jsx-runtime");
13943
14085
  var ToggleSection = ({ children, headline, initialOpen = true }) => {
13944
- const [isOpen, setIsOpen] = (0, import_react49.useState)(initialOpen);
14086
+ const [isOpen, setIsOpen] = (0, import_react50.useState)(initialOpen);
13945
14087
  return /* @__PURE__ */ (0, import_jsx_runtime134.jsxs)(import_material12.Box, { sx: { mt: 4 }, children: [
13946
14088
  /* @__PURE__ */ (0, import_jsx_runtime134.jsx)(
13947
14089
  import_material12.Box,
@@ -14031,7 +14173,7 @@ var ATTRIBUTE_NAME_TRANSFORMATIONS = {
14031
14173
  "localstack.aws.service.response": "Response"
14032
14174
  };
14033
14175
  var EventDetails = ({ onClose, selectedEvent }) => {
14034
- const attributes = (0, import_react50.useMemo)(() => {
14176
+ const attributes = (0, import_react51.useMemo)(() => {
14035
14177
  const attributes2 = Object.entries(selectedEvent?.attributes ?? {});
14036
14178
  return attributes2.filter(([key]) => !ATTRIBUTES_TO_EXCLUDE.has(key));
14037
14179
  }, [selectedEvent?.attributes]);
@@ -14140,22 +14282,22 @@ function renderKeyValue(key, value) {
14140
14282
  // src/components/trace-graph/trace-graph.tsx
14141
14283
  var import_base = require("@xyflow/react/dist/base.css");
14142
14284
  var import_material18 = require("@mui/material");
14143
- var import_react57 = require("@xyflow/react");
14144
- var import_react58 = require("react");
14285
+ var import_react58 = require("@xyflow/react");
14286
+ var import_react59 = require("react");
14145
14287
 
14146
14288
  // src/components/trace-graph/service-node.tsx
14147
14289
  var import_material16 = require("@mui/material");
14148
14290
  var import_style = require("@xyflow/react/dist/style.css");
14149
- var import_react52 = require("@xyflow/react");
14150
- var import_react53 = require("react");
14291
+ var import_react53 = require("@xyflow/react");
14292
+ var import_react54 = require("react");
14151
14293
 
14152
14294
  // src/components/trace-graph/problem-indicator.tsx
14153
14295
  var import_icons_material9 = require("@mui/icons-material");
14154
14296
  var import_material15 = require("@mui/material");
14155
- var import_react51 = require("react");
14297
+ var import_react52 = require("react");
14156
14298
  var import_jsx_runtime137 = require("react/jsx-runtime");
14157
14299
  var ProblemIndicator = ({ error }) => {
14158
- const icon = (0, import_react51.useMemo)(() => {
14300
+ const icon = (0, import_react52.useMemo)(() => {
14159
14301
  switch (error.level) {
14160
14302
  case "error": {
14161
14303
  return /* @__PURE__ */ (0, import_jsx_runtime137.jsx)(import_icons_material9.Error, { sx: { color: "#d32f2f", fontSize: "14px" } });
@@ -14168,7 +14310,7 @@ var ProblemIndicator = ({ error }) => {
14168
14310
  }
14169
14311
  }
14170
14312
  }, [error.level]);
14171
- const color2 = (0, import_react51.useMemo)(() => {
14313
+ const color2 = (0, import_react52.useMemo)(() => {
14172
14314
  switch (error.level) {
14173
14315
  case "error": {
14174
14316
  return "#d32f2f";
@@ -14207,7 +14349,7 @@ var handleStyle = {
14207
14349
  borderColor: "lightgray",
14208
14350
  opacity: 0
14209
14351
  };
14210
- var ServiceNode = (0, import_react53.memo)(({ data, selected }) => {
14352
+ var ServiceNode = (0, import_react54.memo)(({ data, selected }) => {
14211
14353
  const hasErrors = (data.event.errors && data.event.errors.length > 0) ?? false;
14212
14354
  return /* @__PURE__ */ (0, import_jsx_runtime138.jsxs)(import_material16.Box, { sx: { maxWidth: 200 }, children: [
14213
14355
  /* @__PURE__ */ (0, import_jsx_runtime138.jsxs)(
@@ -14231,8 +14373,8 @@ var ServiceNode = (0, import_react53.memo)(({ data, selected }) => {
14231
14373
  },
14232
14374
  tabIndex: 0,
14233
14375
  children: [
14234
- /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_react52.Handle, { position: import_react52.Position.Left, style: handleStyle, type: "target" }),
14235
- /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_react52.Handle, { position: import_react52.Position.Right, style: handleStyle, type: "source" }),
14376
+ /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_react53.Handle, { position: import_react53.Position.Left, style: handleStyle, type: "target" }),
14377
+ /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(import_react53.Handle, { position: import_react53.Position.Right, style: handleStyle, type: "source" }),
14236
14378
  /* @__PURE__ */ (0, import_jsx_runtime138.jsx)(
14237
14379
  ServiceCell,
14238
14380
  {
@@ -14292,7 +14434,7 @@ var ServiceNode = (0, import_react53.memo)(({ data, selected }) => {
14292
14434
 
14293
14435
  // src/components/trace-graph/utils.ts
14294
14436
  var import_dagre = __toESM(require("@dagrejs/dagre"), 1);
14295
- var import_react54 = require("@xyflow/react");
14437
+ var import_react55 = require("@xyflow/react");
14296
14438
  var generateNodesAndEdges = (event, parentId) => {
14297
14439
  const nodes = [];
14298
14440
  const edges = [];
@@ -14308,8 +14450,8 @@ var generateNodesAndEdges = (event, parentId) => {
14308
14450
  id: event.span_id,
14309
14451
  position: { x: 0, y: 0 },
14310
14452
  // Will be set by layout
14311
- sourcePosition: import_react54.Position.Right,
14312
- targetPosition: import_react54.Position.Left,
14453
+ sourcePosition: import_react55.Position.Right,
14454
+ targetPosition: import_react55.Position.Left,
14313
14455
  type: "service"
14314
14456
  });
14315
14457
  if (parentId) {
@@ -14319,7 +14461,7 @@ var generateNodesAndEdges = (event, parentId) => {
14319
14461
  markerEnd: {
14320
14462
  color: "lightgray",
14321
14463
  height: 16,
14322
- type: import_react54.MarkerType.Arrow,
14464
+ type: import_react55.MarkerType.Arrow,
14323
14465
  width: 16
14324
14466
  },
14325
14467
  source: parentId,
@@ -14372,8 +14514,8 @@ var getLayoutedNodesAndEdges = (inputNodes, inputEdges) => {
14372
14514
  // src/components/trace-graph/xyflow/controls.tsx
14373
14515
  var import_icons_material10 = require("@mui/icons-material");
14374
14516
  var import_material17 = require("@mui/material");
14375
- var import_react55 = require("@xyflow/react");
14376
- var import_react56 = require("react");
14517
+ var import_react56 = require("@xyflow/react");
14518
+ var import_react57 = require("react");
14377
14519
 
14378
14520
  // node_modules/zustand/esm/shallow.mjs
14379
14521
  function shallow$1(objA, objB) {
@@ -14420,9 +14562,9 @@ var selector = (s) => ({
14420
14562
  maxZoomReached: s.transform[2] >= s.maxZoom,
14421
14563
  minZoomReached: s.transform[2] <= s.minZoom
14422
14564
  });
14423
- var Controls = (0, import_react56.memo)(() => {
14424
- const { maxZoomReached, minZoomReached } = (0, import_react55.useStore)(selector, shallow$1);
14425
- const { fitView, zoomIn, zoomOut } = (0, import_react55.useReactFlow)();
14565
+ var Controls = (0, import_react57.memo)(() => {
14566
+ const { maxZoomReached, minZoomReached } = (0, import_react56.useStore)(selector, shallow$1);
14567
+ const { fitView, zoomIn, zoomOut } = (0, import_react56.useReactFlow)();
14426
14568
  const onZoomInHandler = () => {
14427
14569
  void zoomIn();
14428
14570
  };
@@ -14491,9 +14633,9 @@ var TraceGraph = ({
14491
14633
  onRefresh,
14492
14634
  spans
14493
14635
  }) => {
14494
- const [nodes, setNodes, onNodesChange] = (0, import_react57.useNodesState)([]);
14495
- const [edges, setEdges] = (0, import_react58.useState)([]);
14496
- (0, import_react58.useEffect)(() => {
14636
+ const [nodes, setNodes, onNodesChange] = (0, import_react58.useNodesState)([]);
14637
+ const [edges, setEdges] = (0, import_react59.useState)([]);
14638
+ (0, import_react59.useEffect)(() => {
14497
14639
  const spansMap = /* @__PURE__ */ new Map();
14498
14640
  const rootSpans = [];
14499
14641
  for (const span of spans.data ?? []) {
@@ -14552,7 +14694,7 @@ var TraceGraph = ({
14552
14694
  }
14553
14695
  ),
14554
14696
  /* @__PURE__ */ (0, import_jsx_runtime140.jsxs)(
14555
- import_react57.ReactFlow,
14697
+ import_react58.ReactFlow,
14556
14698
  {
14557
14699
  "data-testid": "trace-graph",
14558
14700
  edges,
@@ -14571,7 +14713,7 @@ var TraceGraph = ({
14571
14713
  children: [
14572
14714
  /* @__PURE__ */ (0, import_jsx_runtime140.jsx)(Controls, {}),
14573
14715
  /* @__PURE__ */ (0, import_jsx_runtime140.jsx)(
14574
- import_react57.Background,
14716
+ import_react58.Background,
14575
14717
  {
14576
14718
  bgColor: theme.palette.background.paper,
14577
14719
  color: theme.palette.text.disabled
@@ -14676,7 +14818,7 @@ var TraceGraphView = ({
14676
14818
  height: "100%",
14677
14819
  overflow: "auto"
14678
14820
  },
14679
- children: traceId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime141.jsx)(import_react59.ReactFlowProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime141.jsx)(
14821
+ children: traceId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime141.jsx)(import_react60.ReactFlowProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime141.jsx)(
14680
14822
  TraceGraph,
14681
14823
  {
14682
14824
  initialFocusEventId: spanId,
@@ -14737,10 +14879,10 @@ async function fetchConnectedTraces(api, traceIds, allSpans = /* @__PURE__ */ ne
14737
14879
  }
14738
14880
  var TraceGraphPage = ({ onClose, spanId, traceId }) => {
14739
14881
  const api = useAppInspectorApi();
14740
- const [spans, setSpans] = (0, import_react60.useState)();
14741
- const [loading, setLoading] = (0, import_react60.useState)(false);
14742
- const [fetchError, setFetchError] = (0, import_react60.useState)();
14743
- const fetchSpans = (0, import_react60.useCallback)(async () => {
14882
+ const [spans, setSpans] = (0, import_react61.useState)();
14883
+ const [loading, setLoading] = (0, import_react61.useState)(false);
14884
+ const [fetchError, setFetchError] = (0, import_react61.useState)();
14885
+ const fetchSpans = (0, import_react61.useCallback)(async () => {
14744
14886
  setLoading(true);
14745
14887
  try {
14746
14888
  const spans2 = await fetchConnectedTraces(api, [traceId]);
@@ -14753,28 +14895,28 @@ var TraceGraphPage = ({ onClose, spanId, traceId }) => {
14753
14895
  setLoading(false);
14754
14896
  }
14755
14897
  }, [api, traceId]);
14756
- (0, import_react60.useEffect)(() => {
14898
+ (0, import_react61.useEffect)(() => {
14757
14899
  void fetchSpans();
14758
14900
  }, [fetchSpans]);
14759
- const [open, setOpen] = (0, import_react60.useState)(true);
14760
- const [selectedEvent, setSelectedEvent] = (0, import_react60.useState)(() => spans?.find((span) => span.span_id === spanId));
14761
- const spansReference = (0, import_react60.useRef)();
14762
- (0, import_react60.useEffect)(() => {
14901
+ const [open, setOpen] = (0, import_react61.useState)(true);
14902
+ const [selectedEvent, setSelectedEvent] = (0, import_react61.useState)(() => spans?.find((span) => span.span_id === spanId));
14903
+ const spansReference = (0, import_react61.useRef)();
14904
+ (0, import_react61.useEffect)(() => {
14763
14905
  if (!spansReference.current && spans) {
14764
14906
  setSelectedEvent(spans.find((span) => span.span_id === spanId));
14765
14907
  spansReference.current = spans;
14766
14908
  }
14767
14909
  }, [spans, setSelectedEvent, spanId]);
14768
14910
  const { checkStatus, error: statusError, status } = useStatus();
14769
- const handleEventSelect = (0, import_react60.useCallback)((spanId2) => {
14911
+ const handleEventSelect = (0, import_react61.useCallback)((spanId2) => {
14770
14912
  const span = spans?.find((s) => s.span_id === spanId2);
14771
14913
  setSelectedEvent(span);
14772
14914
  setOpen(true);
14773
14915
  }, [spans]);
14774
- const handleRetry = (0, import_react60.useCallback)(() => {
14916
+ const handleRetry = (0, import_react61.useCallback)(() => {
14775
14917
  void checkStatus();
14776
14918
  }, [checkStatus]);
14777
- const navigateToSpansList = (0, import_react60.useCallback)(() => {
14919
+ const navigateToSpansList = (0, import_react61.useCallback)(() => {
14778
14920
  onClose?.();
14779
14921
  }, [onClose]);
14780
14922
  return /* @__PURE__ */ (0, import_jsx_runtime141.jsx)(
@@ -14814,21 +14956,23 @@ var SpansListPage = () => {
14814
14956
  fetchingForward,
14815
14957
  hasMoreBackward,
14816
14958
  hasMoreForward,
14817
- refetching,
14818
14959
  spans,
14819
14960
  status,
14820
- statusError
14961
+ statusError,
14962
+ streamPaused,
14963
+ toggleStream
14821
14964
  } = useSpans();
14822
- const clearSpansSync = (0, import_react61.useCallback)(() => {
14965
+ const clearSpansSync = (0, import_react62.useCallback)(() => {
14823
14966
  void clearSpans();
14824
14967
  }, [clearSpans]);
14825
- const [selectedTraceId, setSelectedTraceId] = (0, import_react61.useState)();
14826
- const [selectedSpanId, setSelectedSpanId] = (0, import_react61.useState)();
14827
- const navigateToSpan = (0, import_react61.useCallback)((span) => {
14968
+ const [order2, setOrder] = useLocalStorage("spans-order", "oldest_first");
14969
+ const [selectedTraceId, setSelectedTraceId] = (0, import_react62.useState)();
14970
+ const [selectedSpanId, setSelectedSpanId] = (0, import_react62.useState)();
14971
+ const navigateToSpan = (0, import_react62.useCallback)((span) => {
14828
14972
  setSelectedTraceId(span.trace_id);
14829
14973
  setSelectedSpanId(span.span_id);
14830
14974
  }, []);
14831
- const handleRetry = (0, import_react61.useCallback)(() => {
14975
+ const handleRetry = (0, import_react62.useCallback)(() => {
14832
14976
  void checkStatus();
14833
14977
  }, [checkStatus]);
14834
14978
  const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
@@ -14867,9 +15011,12 @@ var SpansListPage = () => {
14867
15011
  onClearSpans: clearSpansSync,
14868
15012
  onFetchBackward: fetchBackward,
14869
15013
  onFetchForward: fetchForward,
15014
+ onOrderChange: setOrder,
14870
15015
  onSpanClick: navigateToSpan,
14871
- refetching,
14872
- spans
15016
+ onToggleStream: toggleStream,
15017
+ order: order2,
15018
+ spans,
15019
+ streamPaused
14873
15020
  }
14874
15021
  )
14875
15022
  }