@localstack/appinspector-ui 1.0.134 → 1.0.135

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
@@ -15930,11 +15930,10 @@ var import_material9 = require("@mui/material");
15930
15930
  var import_react39 = require("react");
15931
15931
  var import_jsx_runtime129 = require("react/jsx-runtime");
15932
15932
  var StatusMessage = ({
15933
- error,
15934
15933
  localstackVersion,
15935
15934
  onEnable,
15936
15935
  onRetry,
15937
- status
15936
+ phase
15938
15937
  }) => {
15939
15938
  const [enabling, setEnabling] = (0, import_react39.useState)(false);
15940
15939
  const [enableError, setEnableError] = (0, import_react39.useState)();
@@ -15950,8 +15949,23 @@ var StatusMessage = ({
15950
15949
  setEnabling(false);
15951
15950
  }
15952
15951
  };
15953
- const isBelowMinimum = localstackVersion !== void 0 && checkEmulatorVersion(localstackVersion) === "below-minimum";
15954
- if (isBelowMinimum || error instanceof AppInspectorNotFoundError) {
15952
+ if (phase === "CHECKING_STATUS" || phase === "CONNECTING_WS") {
15953
+ return /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
15954
+ import_material9.Box,
15955
+ {
15956
+ sx: {
15957
+ alignItems: "center",
15958
+ display: "flex",
15959
+ flexDirection: "column",
15960
+ gap: 2,
15961
+ justifyContent: "center",
15962
+ p: 4
15963
+ },
15964
+ children: /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.CircularProgress, { size: 32 })
15965
+ }
15966
+ );
15967
+ }
15968
+ if (phase === "INCOMPATIBLE") {
15955
15969
  return /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
15956
15970
  import_material9.Box,
15957
15971
  {
@@ -15971,7 +15985,7 @@ var StatusMessage = ({
15971
15985
  sx: { maxWidth: 600, width: "100%" },
15972
15986
  children: [
15973
15987
  /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.AlertTitle, { sx: { fontWeight: "bold" }, children: "App Inspector Not Available" }),
15974
- /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.Typography, { sx: { mb: 2 }, variant: "body2", children: isBelowMinimum ? `App Inspector requires LocalStack ${MINIMUM_EMULATOR_VERSION} or later. You are running version ${localstackVersion}. Please update LocalStack.` : `App Inspector requires LocalStack ${MINIMUM_EMULATOR_VERSION} or later. Please update LocalStack.` }),
15988
+ /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.Typography, { sx: { mb: 2 }, variant: "body2", children: localstackVersion === void 0 ? `App Inspector requires LocalStack ${MINIMUM_EMULATOR_VERSION} or later. Please update LocalStack.` : `App Inspector requires LocalStack ${MINIMUM_EMULATOR_VERSION} or later. You are running version ${localstackVersion}. Please update LocalStack.` }),
15975
15989
  /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.Typography, { sx: { mb: 1 }, variant: "body2", children: /* @__PURE__ */ (0, import_jsx_runtime129.jsx)("strong", { children: "Update LocalStack:" }) }),
15976
15990
  /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
15977
15991
  import_material9.Box,
@@ -15986,11 +16000,10 @@ var StatusMessage = ({
15986
16000
  children: "localstack update docker-images"
15987
16001
  }
15988
16002
  ),
15989
- /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.Box, { sx: { display: "flex", gap: 1, mt: 2 }, children: onRetry && /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
16003
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.Box, { sx: { display: "flex", gap: 1, mt: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
15990
16004
  import_material9.Button,
15991
16005
  {
15992
16006
  "aria-label": "Check App Inspector status again",
15993
- disabled: enabling,
15994
16007
  onClick: onRetry,
15995
16008
  variant: "outlined",
15996
16009
  children: "Check Again"
@@ -16002,7 +16015,7 @@ var StatusMessage = ({
16002
16015
  }
16003
16016
  );
16004
16017
  }
16005
- if (error instanceof ConnectionError) {
16018
+ if (phase === "UNREACHABLE") {
16006
16019
  return /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
16007
16020
  import_material9.Box,
16008
16021
  {
@@ -16064,7 +16077,7 @@ var StatusMessage = ({
16064
16077
  }
16065
16078
  );
16066
16079
  }
16067
- if (error instanceof AppInspectorDisabledError || status?.status === "DISABLED") {
16080
+ if (phase === "DISABLED") {
16068
16081
  return /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
16069
16082
  import_material9.Box,
16070
16083
  {
@@ -16119,102 +16132,99 @@ var StatusMessage = ({
16119
16132
  }
16120
16133
  );
16121
16134
  }
16122
- if (error) {
16123
- return /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
16124
- import_material9.Box,
16125
- {
16126
- sx: {
16127
- alignItems: "center",
16128
- display: "flex",
16129
- flexDirection: "column",
16130
- gap: 2,
16131
- justifyContent: "center",
16132
- p: 4
16133
- },
16134
- children: /* @__PURE__ */ (0, import_jsx_runtime129.jsxs)(
16135
- import_material9.Alert,
16136
- {
16137
- icon: /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_icons_material4.ErrorOutline, { fontSize: "large" }),
16138
- severity: "error",
16139
- sx: { maxWidth: 600, width: "100%" },
16140
- children: [
16141
- /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.AlertTitle, { sx: { fontWeight: "bold" }, children: "Error" }),
16142
- /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.Typography, { sx: { mb: 2 }, variant: "body2", children: error.message }),
16143
- onRetry && /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_material9.Box, { sx: { display: "flex", justifyContent: "flex-start", mt: 2 }, children: /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(
16144
- import_material9.Button,
16145
- {
16146
- "aria-label": "Retry operation",
16147
- onClick: onRetry,
16148
- variant: "outlined",
16149
- children: "Retry"
16150
- }
16151
- ) })
16152
- ]
16153
- }
16154
- )
16155
- }
16156
- );
16157
- }
16158
16135
  return /* @__PURE__ */ (0, import_jsx_runtime129.jsx)(import_jsx_runtime129.Fragment, {});
16159
16136
  };
16160
16137
 
16161
16138
  // src/hooks/status-provider.tsx
16162
16139
  var import_react41 = require("react");
16163
16140
 
16164
- // src/hooks/use-status.tsx
16141
+ // src/hooks/use-connection-state-machine.ts
16165
16142
  var import_react40 = require("react");
16166
- var useStatus = () => {
16143
+ var POLL_INTERVAL_MS = 5e3;
16144
+ function useConnectionStateMachine() {
16167
16145
  const api = useAppInspectorApi();
16146
+ const [phase, setPhase] = (0, import_react40.useState)("CHECKING_STATUS");
16168
16147
  const [checking, setChecking] = (0, import_react40.useState)(true);
16169
16148
  const [status, setStatus] = (0, import_react40.useState)();
16170
- const [error, setError] = (0, import_react40.useState)();
16171
- const hasFetchedReference = (0, import_react40.useRef)(false);
16172
- const abortControllerReference = (0, import_react40.useRef)(null);
16173
- const checkStatus = (0, import_react40.useCallback)(async () => {
16174
- if (abortControllerReference.current !== null) {
16175
- abortControllerReference.current.abort();
16149
+ const [statusError, setStatusError] = (0, import_react40.useState)();
16150
+ const abortControllerRef = (0, import_react40.useRef)(null);
16151
+ const dispatchStatus = (0, import_react40.useCallback)((result, error) => {
16152
+ if (result === void 0) {
16153
+ setStatus(void 0);
16154
+ setStatusError(error);
16155
+ setPhase(error instanceof AppInspectorNotFoundError ? "INCOMPATIBLE" : "UNREACHABLE");
16156
+ return;
16157
+ }
16158
+ setStatus(result);
16159
+ setStatusError(void 0);
16160
+ if (checkEmulatorVersion(result.localstackVersion) === "below-minimum") {
16161
+ setPhase("INCOMPATIBLE");
16162
+ return;
16163
+ }
16164
+ setPhase(result.status === "ENABLED" ? "CONNECTING_WS" : "DISABLED");
16165
+ }, []);
16166
+ const runCheck = (0, import_react40.useCallback)(async () => {
16167
+ if (abortControllerRef.current !== null) {
16168
+ abortControllerRef.current.abort();
16176
16169
  }
16177
16170
  const abortController = new AbortController();
16178
- abortControllerReference.current = abortController;
16171
+ abortControllerRef.current = abortController;
16179
16172
  setChecking(true);
16180
16173
  try {
16181
- const response = await api.getStatus();
16174
+ const result = await api.getStatus();
16182
16175
  if (!abortController.signal.aborted) {
16183
- setStatus(response);
16184
- setError(void 0);
16176
+ dispatchStatus(result);
16185
16177
  }
16186
- } catch (error_) {
16178
+ } catch (error) {
16187
16179
  if (!abortController.signal.aborted) {
16188
- setError(error_ instanceof Error ? error_ : new Error("Unknown error"));
16189
- setStatus(void 0);
16180
+ dispatchStatus(void 0, error instanceof Error ? error : new Error("Unknown error"));
16190
16181
  }
16191
16182
  } finally {
16192
16183
  if (!abortController.signal.aborted) {
16193
16184
  setChecking(false);
16194
16185
  }
16195
16186
  }
16196
- }, [api]);
16187
+ }, [api, dispatchStatus]);
16197
16188
  (0, import_react40.useEffect)(() => {
16198
- if (!hasFetchedReference.current) {
16199
- hasFetchedReference.current = true;
16200
- void checkStatus();
16201
- }
16202
- }, [checkStatus]);
16203
- return { checking, checkStatus, error, status };
16204
- };
16189
+ void runCheck();
16190
+ }, [runCheck]);
16191
+ (0, import_react40.useEffect)(() => {
16192
+ if (phase !== "UNREACHABLE" && phase !== "DISABLED") return;
16193
+ const intervalId = globalThis.setInterval(() => {
16194
+ void runCheck();
16195
+ }, POLL_INTERVAL_MS);
16196
+ return () => {
16197
+ globalThis.clearInterval(intervalId);
16198
+ };
16199
+ }, [phase, runCheck]);
16200
+ const checkStatus = (0, import_react40.useCallback)(() => {
16201
+ void runCheck();
16202
+ }, [runCheck]);
16203
+ const onWsOpen = (0, import_react40.useCallback)(() => {
16204
+ setPhase("LIVE");
16205
+ }, []);
16206
+ const onWsClose = (0, import_react40.useCallback)(() => {
16207
+ setPhase("CHECKING_STATUS");
16208
+ void runCheck();
16209
+ }, [runCheck]);
16210
+ const wsEnabled = phase === "CONNECTING_WS" || phase === "LIVE";
16211
+ return {
16212
+ checking,
16213
+ checkStatus,
16214
+ onWsClose,
16215
+ onWsOpen,
16216
+ phase,
16217
+ status,
16218
+ statusError,
16219
+ wsEnabled
16220
+ };
16221
+ }
16205
16222
 
16206
16223
  // src/hooks/status-provider.tsx
16207
16224
  var import_jsx_runtime130 = require("react/jsx-runtime");
16208
16225
  var AppInspectorStatusContext = (0, import_react41.createContext)(void 0);
16209
16226
  var StatusProvider = ({ children }) => {
16210
- const { checking, checkStatus, error, status } = useStatus();
16211
- const reportDisabled = (0, import_react41.useCallback)(() => {
16212
- void checkStatus();
16213
- }, [checkStatus]);
16214
- const value = (0, import_react41.useMemo)(
16215
- () => ({ checking, checkStatus, reportDisabled, status, statusError: error }),
16216
- [checking, checkStatus, reportDisabled, status, error]
16217
- );
16227
+ const value = useConnectionStateMachine();
16218
16228
  return /* @__PURE__ */ (0, import_jsx_runtime130.jsx)(AppInspectorStatusContext.Provider, { value, children });
16219
16229
  };
16220
16230
  var useAppInspectorStatus = () => {
@@ -18682,14 +18692,21 @@ var AppInspectorContextProvider = (props) => {
18682
18692
 
18683
18693
  // src/hooks/use-spans-ws.tsx
18684
18694
  function useSpansWebSocket(options) {
18685
- const { onMessage } = options;
18695
+ const { enabled, onClose, onMessage, onOpen } = options;
18686
18696
  const onMessageRef = (0, import_react46.useRef)(onMessage);
18697
+ const onOpenRef = (0, import_react46.useRef)(onOpen);
18698
+ const onCloseRef = (0, import_react46.useRef)(onClose);
18687
18699
  (0, import_react46.useEffect)(() => {
18688
18700
  onMessageRef.current = onMessage;
18689
18701
  }, [onMessage]);
18702
+ (0, import_react46.useEffect)(() => {
18703
+ onOpenRef.current = onOpen;
18704
+ }, [onOpen]);
18705
+ (0, import_react46.useEffect)(() => {
18706
+ onCloseRef.current = onClose;
18707
+ }, [onClose]);
18690
18708
  const [connected, setConnected] = (0, import_react46.useState)(false);
18691
18709
  const wsRef = (0, import_react46.useRef)(void 0);
18692
- const reconnectRef = (0, import_react46.useRef)(void 0);
18693
18710
  const { localstackEndpoint } = useAppInspector();
18694
18711
  const connect = (0, import_react46.useCallback)(() => {
18695
18712
  if (wsRef.current !== void 0) return;
@@ -18698,19 +18715,22 @@ function useSpansWebSocket(options) {
18698
18715
  const ws = new WebSocket(url);
18699
18716
  wsRef.current = ws;
18700
18717
  ws.addEventListener("open", () => {
18718
+ if (wsRef.current !== ws) return;
18701
18719
  setConnected(true);
18720
+ onOpenRef.current();
18702
18721
  });
18703
18722
  ws.addEventListener("message", () => {
18723
+ if (wsRef.current !== ws) return;
18704
18724
  onMessageRef.current();
18705
18725
  });
18706
18726
  ws.addEventListener("close", () => {
18727
+ if (wsRef.current !== ws) return;
18707
18728
  setConnected(false);
18708
18729
  wsRef.current = void 0;
18709
- reconnectRef.current = globalThis.setTimeout(() => {
18710
- connect();
18711
- }, 2e3);
18730
+ onCloseRef.current();
18712
18731
  });
18713
18732
  ws.addEventListener("error", () => {
18733
+ if (wsRef.current !== ws) return;
18714
18734
  try {
18715
18735
  ws.close();
18716
18736
  } catch {
@@ -18718,18 +18738,26 @@ function useSpansWebSocket(options) {
18718
18738
  });
18719
18739
  }, [localstackEndpoint]);
18720
18740
  (0, import_react46.useEffect)(() => {
18741
+ if (!enabled) {
18742
+ if (wsRef.current !== void 0) {
18743
+ wsRef.current.close();
18744
+ wsRef.current = void 0;
18745
+ setConnected(false);
18746
+ }
18747
+ return;
18748
+ }
18721
18749
  connect();
18722
18750
  return () => {
18723
- if (reconnectRef.current !== void 0) clearTimeout(reconnectRef.current);
18724
18751
  if (wsRef.current !== void 0) {
18725
18752
  try {
18726
18753
  wsRef.current.close();
18727
18754
  } catch {
18728
18755
  }
18729
18756
  wsRef.current = void 0;
18757
+ setConnected(false);
18730
18758
  }
18731
18759
  };
18732
- }, [connect]);
18760
+ }, [enabled, connect]);
18733
18761
  return { connected };
18734
18762
  }
18735
18763
 
@@ -18737,7 +18765,7 @@ function useSpansWebSocket(options) {
18737
18765
  var PAGE_SIZE = 100;
18738
18766
  var useSpans = () => {
18739
18767
  const api = useAppInspectorApi();
18740
- const { reportDisabled } = useAppInspectorStatus();
18768
+ const { onWsClose, onWsOpen, wsEnabled } = useAppInspectorStatus();
18741
18769
  const [spans, setSpans] = (0, import_react47.useState)();
18742
18770
  const [fetchError, setFetchError] = (0, import_react47.useState)();
18743
18771
  const [fetchingForward, setFetchingForward] = (0, import_react47.useState)(false);
@@ -18826,6 +18854,8 @@ var useSpans = () => {
18826
18854
  }
18827
18855
  }, [hasMoreBackward, fetchingBackward, fetchingForward]);
18828
18856
  useSpansWebSocket({
18857
+ enabled: wsEnabled,
18858
+ onClose: onWsClose,
18829
18859
  onMessage: () => {
18830
18860
  if (clearingSpans) {
18831
18861
  return;
@@ -18833,16 +18863,15 @@ var useSpans = () => {
18833
18863
  if (!hasMoreForward) {
18834
18864
  void paginationBufferRef.current.fetchForward();
18835
18865
  }
18866
+ },
18867
+ onOpen: () => {
18868
+ onWsOpen();
18869
+ fetchForward();
18836
18870
  }
18837
18871
  });
18838
18872
  const clearFetchError = (0, import_react47.useCallback)(() => {
18839
18873
  setFetchError(void 0);
18840
18874
  }, []);
18841
- (0, import_react47.useEffect)(() => {
18842
- if (fetchError instanceof AppInspectorDisabledError || fetchError instanceof ConnectionError) {
18843
- reportDisabled();
18844
- }
18845
- }, [fetchError, reportDisabled]);
18846
18875
  return {
18847
18876
  clearFetchError,
18848
18877
  clearingSpans,
@@ -31084,7 +31113,7 @@ var QueryStatus = {
31084
31113
  var import_material17 = require("@mui/material");
31085
31114
  var import_react53 = require("react");
31086
31115
  var import_jsx_runtime139 = require("react/jsx-runtime");
31087
- var POLL_INTERVAL_MS = 1e3;
31116
+ var POLL_INTERVAL_MS2 = 1e3;
31088
31117
  async function pollQueryResults(client, queryId) {
31089
31118
  return client.send(new GetQueryResultsCommand({ queryId }));
31090
31119
  }
@@ -31145,7 +31174,7 @@ function useLambdaInvokeLogs(functionName2, requestId, region, startTimeNano, en
31145
31174
  setError(new Error(`Query ended with status: ${status}`));
31146
31175
  setLoading(false);
31147
31176
  } else {
31148
- pollTimerRef.current = setTimeout(() => void poll(), POLL_INTERVAL_MS);
31177
+ pollTimerRef.current = setTimeout(() => void poll(), POLL_INTERVAL_MS2);
31149
31178
  }
31150
31179
  } catch (error_) {
31151
31180
  if (!cancelled) {
@@ -31953,90 +31982,75 @@ var TraceGraphView = ({
31953
31982
  fetchError,
31954
31983
  fetchSpans,
31955
31984
  handleClose,
31956
- handleEnable,
31957
31985
  handleEventSelect,
31958
- handleRetry,
31959
31986
  loading,
31960
31987
  navigateToSpansList,
31961
31988
  open,
31962
31989
  selectedEvent,
31963
31990
  spanId,
31964
31991
  spans,
31965
- status,
31966
- statusError,
31967
31992
  traceId
31968
- }) => {
31969
- const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
31970
- return /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(
31971
- import_material23.Box,
31972
- {
31973
- "data-testid": TRACE_GRAPH_PAGE_TEST_ID,
31974
- sx: {
31975
- alignItems: "center",
31976
- display: "flex",
31977
- flexDirection: "column",
31978
- flexGrow: 1,
31979
- gap: 2,
31980
- overflow: "hidden"
31981
- },
31982
- children: [
31983
- /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(import_material23.Box, { sx: { display: "flex", width: "100%" }, children: [
31984
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_material23.Button, { onClick: () => {
31985
- navigateToSpansList();
31986
- }, startIcon: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_icons_material13.ArrowBack, {}), children: "Go back" }),
31987
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_material23.Box, { sx: { flexGrow: 1 } })
31988
- ] }),
31989
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
31990
- import_material23.Paper,
31991
- {
31992
- sx: {
31993
- display: "flex",
31994
- flexGrow: 1,
31995
- overflow: "hidden",
31996
- position: "relative",
31997
- width: "100%"
31998
- },
31999
- children: shouldShowStatusMessage ? /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
32000
- StatusMessage,
31993
+ }) => /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(
31994
+ import_material23.Box,
31995
+ {
31996
+ "data-testid": TRACE_GRAPH_PAGE_TEST_ID,
31997
+ sx: {
31998
+ alignItems: "center",
31999
+ display: "flex",
32000
+ flexDirection: "column",
32001
+ flexGrow: 1,
32002
+ gap: 2,
32003
+ overflow: "hidden"
32004
+ },
32005
+ children: [
32006
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(import_material23.Box, { sx: { display: "flex", width: "100%" }, children: [
32007
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_material23.Button, { onClick: () => {
32008
+ navigateToSpansList();
32009
+ }, startIcon: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_icons_material13.ArrowBack, {}), children: "Go back" }),
32010
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_material23.Box, { sx: { flexGrow: 1 } })
32011
+ ] }),
32012
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(
32013
+ import_material23.Paper,
32014
+ {
32015
+ sx: {
32016
+ display: "flex",
32017
+ flexGrow: 1,
32018
+ overflow: "hidden",
32019
+ position: "relative",
32020
+ width: "100%"
32021
+ },
32022
+ children: [
32023
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(Main, { open, children: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
32024
+ import_material23.Box,
32001
32025
  {
32002
- error: statusError,
32003
- onEnable: handleEnable,
32004
- onRetry: handleRetry,
32005
- status
32006
- }
32007
- ) : /* @__PURE__ */ (0, import_jsx_runtime145.jsxs)(import_jsx_runtime145.Fragment, { children: [
32008
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(Main, { open, children: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
32009
- import_material23.Box,
32010
- {
32011
- sx: {
32012
- height: "100%",
32013
- overflow: "auto"
32014
- },
32015
- children: traceId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_react62.ReactFlowProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
32016
- TraceGraph,
32017
- {
32018
- initialFocusEventId: spanId,
32019
- onEventSelect: handleEventSelect,
32020
- onRefresh: () => {
32021
- fetchSpans();
32022
- },
32023
- spans: {
32024
- data: spans,
32025
- error: fetchError,
32026
- loading
32027
- }
32026
+ sx: {
32027
+ height: "100%",
32028
+ overflow: "auto"
32029
+ },
32030
+ children: traceId !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(import_react62.ReactFlowProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(
32031
+ TraceGraph,
32032
+ {
32033
+ initialFocusEventId: spanId,
32034
+ onEventSelect: handleEventSelect,
32035
+ onRefresh: () => {
32036
+ fetchSpans();
32037
+ },
32038
+ spans: {
32039
+ data: spans,
32040
+ error: fetchError,
32041
+ loading
32028
32042
  }
32029
- ) })
32030
- }
32031
- ) }),
32032
- /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(StyledDrawer, { anchor: "right", open, variant: "persistent", children: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(EventDetails, { onClose: handleClose, selectedEvent }) })
32033
- ] })
32034
- }
32035
- )
32036
- ]
32037
- }
32038
- );
32039
- };
32043
+ }
32044
+ ) })
32045
+ }
32046
+ ) }),
32047
+ /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(StyledDrawer, { anchor: "right", open, variant: "persistent", children: /* @__PURE__ */ (0, import_jsx_runtime145.jsx)(EventDetails, { onClose: handleClose, selectedEvent }) })
32048
+ ]
32049
+ }
32050
+ )
32051
+ ]
32052
+ }
32053
+ );
32040
32054
  async function fetchConnectedTraces(api, traceIds, allSpans = /* @__PURE__ */ new Map(), processedTraceIds = /* @__PURE__ */ new Set()) {
32041
32055
  const newTraceIds = traceIds.filter((id2) => !processedTraceIds.has(id2));
32042
32056
  if (newTraceIds.length === 0) {
@@ -32101,24 +32115,11 @@ var TraceGraphPage = ({ onClose, spanId, traceId }) => {
32101
32115
  spansReference.current = spans;
32102
32116
  }
32103
32117
  }, [spans, setSelectedEvent, spanId]);
32104
- const { checkStatus, reportDisabled, status, statusError } = useAppInspectorStatus();
32105
- (0, import_react63.useEffect)(() => {
32106
- if (fetchError instanceof AppInspectorDisabledError || fetchError instanceof ConnectionError) {
32107
- reportDisabled();
32108
- }
32109
- }, [fetchError, reportDisabled]);
32110
- const handleEnable = (0, import_react63.useCallback)(async () => {
32111
- await api.setStatus({ status: "ENABLED" });
32112
- void checkStatus();
32113
- }, [api, checkStatus]);
32114
32118
  const handleEventSelect = (0, import_react63.useCallback)((spanId2) => {
32115
32119
  const span = spans?.find((s) => s.span_id === spanId2);
32116
32120
  setSelectedEvent(span);
32117
32121
  setOpen(true);
32118
32122
  }, [spans]);
32119
- const handleRetry = (0, import_react63.useCallback)(() => {
32120
- void checkStatus();
32121
- }, [checkStatus]);
32122
32123
  const navigateToSpansList = (0, import_react63.useCallback)(() => {
32123
32124
  onClose?.();
32124
32125
  }, [onClose]);
@@ -32130,17 +32131,13 @@ var TraceGraphPage = ({ onClose, spanId, traceId }) => {
32130
32131
  handleClose: () => {
32131
32132
  setOpen(false);
32132
32133
  },
32133
- handleEnable,
32134
32134
  handleEventSelect,
32135
- handleRetry,
32136
32135
  loading,
32137
32136
  navigateToSpansList,
32138
32137
  open,
32139
32138
  selectedEvent,
32140
32139
  spanId: spanId ?? void 0,
32141
32140
  spans,
32142
- status,
32143
- statusError,
32144
32141
  traceId
32145
32142
  }
32146
32143
  );
@@ -32167,7 +32164,7 @@ var SpansListPage = () => {
32167
32164
  totalCount,
32168
32165
  warningCount
32169
32166
  } = useSpans();
32170
- const { checking, checkStatus, status, statusError } = useAppInspectorStatus();
32167
+ const { checkStatus, phase, status, statusError } = useAppInspectorStatus();
32171
32168
  const clearSpansSync = (0, import_react64.useCallback)(() => {
32172
32169
  void clearSpans();
32173
32170
  }, [clearSpans]);
@@ -32182,13 +32179,13 @@ var SpansListPage = () => {
32182
32179
  setSelectedSpanId(span.span_id);
32183
32180
  }, []);
32184
32181
  const handleRetry = (0, import_react64.useCallback)(() => {
32185
- void checkStatus();
32182
+ checkStatus();
32186
32183
  fetchForward();
32187
32184
  }, [checkStatus, fetchForward]);
32188
32185
  const handleEnable = (0, import_react64.useCallback)(async () => {
32189
32186
  await api.setStatus({ status: "ENABLED" });
32190
32187
  clearFetchError();
32191
- void checkStatus();
32188
+ checkStatus();
32192
32189
  }, [api, checkStatus, clearFetchError]);
32193
32190
  const isDelayedRefetchRef = (0, import_react64.useRef)(false);
32194
32191
  const delayedRefetchTimerRef = (0, import_react64.useRef)();
@@ -32211,27 +32208,42 @@ var SpansListPage = () => {
32211
32208
  clearTimeout(delayedRefetchTimerRef.current);
32212
32209
  };
32213
32210
  }, [fetchingForward, fetchForward]);
32214
- const shouldShowStatusMessage = Boolean(statusError) || status?.status === "DISABLED";
32215
- if (versionCompatibility === "below-minimum") {
32216
- return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
32217
- StatusMessage,
32218
- {
32219
- localstackVersion,
32220
- onRetry: handleRetry
32221
- }
32222
- );
32223
- }
32224
- if (shouldShowStatusMessage) {
32225
- return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
32226
- StatusMessage,
32227
- {
32228
- error: statusError,
32229
- localstackVersion,
32230
- onEnable: handleEnable,
32231
- onRetry: handleRetry,
32232
- status
32233
- }
32234
- );
32211
+ switch (phase) {
32212
+ case "CHECKING_STATUS":
32213
+ case "CONNECTING_WS": {
32214
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(StatusMessage, { phase });
32215
+ }
32216
+ case "DISABLED": {
32217
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
32218
+ StatusMessage,
32219
+ {
32220
+ onEnable: handleEnable,
32221
+ phase
32222
+ }
32223
+ );
32224
+ }
32225
+ case "INCOMPATIBLE": {
32226
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
32227
+ StatusMessage,
32228
+ {
32229
+ localstackVersion,
32230
+ onRetry: handleRetry,
32231
+ phase
32232
+ }
32233
+ );
32234
+ }
32235
+ case "LIVE": {
32236
+ break;
32237
+ }
32238
+ case "UNREACHABLE": {
32239
+ return /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
32240
+ StatusMessage,
32241
+ {
32242
+ onRetry: handleRetry,
32243
+ phase
32244
+ }
32245
+ );
32246
+ }
32235
32247
  }
32236
32248
  return /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(import_jsx_runtime146.Fragment, { children: [
32237
32249
  /* @__PURE__ */ (0, import_jsx_runtime146.jsxs)(
@@ -32250,7 +32262,7 @@ var SpansListPage = () => {
32250
32262
  width: "100%"
32251
32263
  },
32252
32264
  children: [
32253
- !checking && /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
32265
+ /* @__PURE__ */ (0, import_jsx_runtime146.jsx)(
32254
32266
  EmulatorVersionBanner,
32255
32267
  {
32256
32268
  compatibility: bannerDismissed && versionCompatibility === "warning" ? "ok" : versionCompatibility,