@localstack/appinspector-ui 1.0.112 → 1.0.113

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -2414,9 +2414,16 @@ var init_event_streams = __esm({
2414
2414
 
2415
2415
  // src/pages/spans-list-page.tsx
2416
2416
  import { Box as Box20 } from "@mui/material";
2417
- import { useCallback as useCallback11, useState as useState18 } from "react";
2417
+ import { useCallback as useCallback12, useState as useState18 } from "react";
2418
2418
 
2419
2419
  // src/api/errors.ts
2420
+ var AppInspectorDisabledError = class extends Error {
2421
+ constructor(message, cause) {
2422
+ super(message);
2423
+ this.name = "AppInspectorDisabledError";
2424
+ this.cause = cause;
2425
+ }
2426
+ };
2420
2427
  var AppInspectorNotFoundError = class extends Error {
2421
2428
  localstackVersion;
2422
2429
  constructor(message, cause, localstackVersion) {
@@ -15523,7 +15530,7 @@ var StatusMessage = ({
15523
15530
  }
15524
15531
  );
15525
15532
  }
15526
- if (status?.status === "DISABLED") {
15533
+ if (error instanceof AppInspectorDisabledError || status?.status === "DISABLED") {
15527
15534
  return /* @__PURE__ */ jsx129(
15528
15535
  Box6,
15529
15536
  {
@@ -15630,7 +15637,7 @@ var StatusMessage = ({
15630
15637
  };
15631
15638
 
15632
15639
  // src/hooks/status-provider.tsx
15633
- import { createContext as createContext8, useContext as useContext15, useMemo as useMemo6 } from "react";
15640
+ import { createContext as createContext8, useCallback as useCallback5, useContext as useContext15, useMemo as useMemo6 } from "react";
15634
15641
 
15635
15642
  // src/hooks/use-status.tsx
15636
15643
  import { useCallback as useCallback4, useEffect as useEffect11, useRef as useRef9, useState as useState6 } from "react";
@@ -15679,9 +15686,12 @@ import { jsx as jsx130 } from "react/jsx-runtime";
15679
15686
  var AppInspectorStatusContext = createContext8(void 0);
15680
15687
  var StatusProvider = ({ children }) => {
15681
15688
  const { checking, checkStatus, error, status } = useStatus();
15689
+ const reportDisabled = useCallback5(() => {
15690
+ void checkStatus();
15691
+ }, [checkStatus]);
15682
15692
  const value = useMemo6(
15683
- () => ({ checking, checkStatus, status, statusError: error }),
15684
- [checking, checkStatus, status, error]
15693
+ () => ({ checking, checkStatus, reportDisabled, status, statusError: error }),
15694
+ [checking, checkStatus, reportDisabled, status, error]
15685
15695
  );
15686
15696
  return /* @__PURE__ */ jsx130(AppInspectorStatusContext.Provider, { value, children });
15687
15697
  };
@@ -15694,7 +15704,7 @@ var useAppInspectorStatus = () => {
15694
15704
  };
15695
15705
 
15696
15706
  // src/hooks/use-local-storage.tsx
15697
- import { useCallback as useCallback5, useEffect as useEffect12, useState as useState7 } from "react";
15707
+ import { useCallback as useCallback6, useEffect as useEffect12, useState as useState7 } from "react";
15698
15708
  function useLocalStorage(key, initialValue) {
15699
15709
  const [storedValue, setStoredValue] = useState7(() => {
15700
15710
  try {
@@ -15705,7 +15715,7 @@ function useLocalStorage(key, initialValue) {
15705
15715
  return initialValue;
15706
15716
  }
15707
15717
  });
15708
- const setValue = useCallback5((value) => {
15718
+ const setValue = useCallback6((value) => {
15709
15719
  try {
15710
15720
  setStoredValue((previousState) => {
15711
15721
  const next = typeof value === "function" ? value(previousState) : value;
@@ -15739,7 +15749,7 @@ function useLocalStorage(key, initialValue) {
15739
15749
  }
15740
15750
 
15741
15751
  // src/hooks/use-spans.ts
15742
- import { useCallback as useCallback8, useEffect as useEffect16, useRef as useRef13, useState as useState10 } from "react";
15752
+ import { useCallback as useCallback9, useEffect as useEffect16, useRef as useRef13, useState as useState10 } from "react";
15743
15753
 
15744
15754
  // src/utils/pagination-buffer.ts
15745
15755
  var insertSorted = (array, item, compareFunction, hint = "back") => {
@@ -15920,7 +15930,7 @@ var createPaginationBuffer = (options) => {
15920
15930
  };
15921
15931
 
15922
15932
  // src/hooks/use-spans-ws.tsx
15923
- import { useCallback as useCallback7, useEffect as useEffect14, useRef as useRef11, useState as useState8 } from "react";
15933
+ import { useCallback as useCallback8, useEffect as useEffect14, useRef as useRef11, useState as useState8 } from "react";
15924
15934
 
15925
15935
  // src/config.ts
15926
15936
  var APPINSPECTOR_API_PREFIX = "/_localstack/appinspector";
@@ -15950,7 +15960,7 @@ var LOCALSTACK_INFO_PATH = "/_localstack/info";
15950
15960
 
15951
15961
  // src/context.tsx
15952
15962
  import { createContext as createContext9, useContext as useContext16 } from "react";
15953
- import { useCallback as useCallback6, useMemo as useMemo7 } from "react";
15963
+ import { useCallback as useCallback7, useMemo as useMemo7 } from "react";
15954
15964
 
15955
15965
  // src/api/client.ts
15956
15966
  var import_semver2 = __toESM(require_semver2(), 1);
@@ -16039,17 +16049,19 @@ var makeRequest = async (options) => {
16039
16049
  new Error(`404 from ${url}: ${response.statusText}`)
16040
16050
  );
16041
16051
  }
16052
+ if (response.status === 503) {
16053
+ throw new AppInspectorDisabledError(
16054
+ ERROR_MESSAGES.APP_INSPECTOR_DISABLED,
16055
+ new Error(`503 from ${url}: ${response.statusText}`)
16056
+ );
16057
+ }
16042
16058
  throw new Error(`API request failed: ${response.status.toString()} ${response.statusText}`);
16043
16059
  }
16044
16060
  options.captureHeaders?.(response.headers);
16045
16061
  return await response.json();
16046
16062
  } catch (error) {
16047
16063
  if (error instanceof TypeError) {
16048
- const message = error.message.toLowerCase();
16049
- const isNetworkError = message.includes("fetch") || message.includes("network") || message.includes("failed to fetch");
16050
- if (isNetworkError) {
16051
- throw new ConnectionError(ERROR_MESSAGES.CONNECTION_FAILED, error);
16052
- }
16064
+ throw new ConnectionError(ERROR_MESSAGES.CONNECTION_FAILED, error);
16053
16065
  }
16054
16066
  if (error instanceof Error) {
16055
16067
  throw error;
@@ -18118,7 +18130,7 @@ var AppInspectorContextProvider = (props) => {
18118
18130
  () => createApiClient({ localstackEndpoint: props.localstackEndpoint }),
18119
18131
  [props.localstackEndpoint]
18120
18132
  );
18121
- const resolveLink = useCallback6(
18133
+ const resolveLink = useCallback7(
18122
18134
  (options) => {
18123
18135
  if (options.to === "settings") {
18124
18136
  return `${props.routePrefix}/settings`;
@@ -18157,7 +18169,7 @@ function useSpansWebSocket(options) {
18157
18169
  const wsRef = useRef11(void 0);
18158
18170
  const reconnectRef = useRef11(void 0);
18159
18171
  const { localstackEndpoint } = useAppInspector();
18160
- const connect = useCallback7(() => {
18172
+ const connect = useCallback8(() => {
18161
18173
  if (wsRef.current !== void 0) return;
18162
18174
  const url = new URL(getAppInspectorApiUrl(localstackEndpoint, API_ENDPOINTS.WEBSOCKET_SPANS));
18163
18175
  url.protocol = globalThis.location.protocol === "https:" ? "wss" : "ws";
@@ -18296,6 +18308,7 @@ function useThrottledItems(items, getId, catchUpIncrement = 10) {
18296
18308
  var PAGE_SIZE = 30;
18297
18309
  var useSpans = () => {
18298
18310
  const api = useAppInspectorApi();
18311
+ const { reportDisabled } = useAppInspectorStatus();
18299
18312
  const [spans, setSpans] = useState10();
18300
18313
  const throttledSpans = useThrottledItems(spans, (span) => span.span_id);
18301
18314
  const [fetchError, setFetchError] = useState10();
@@ -18347,17 +18360,17 @@ var useSpans = () => {
18347
18360
  const [warningCount, setWarningCount] = useState10();
18348
18361
  const [hasMoreBackward, setHasMoreBackward] = useState10();
18349
18362
  const [hasMoreForward, setHasMoreForward] = useState10();
18350
- const fetchForward = useCallback8(() => {
18363
+ const fetchForward = useCallback9(() => {
18351
18364
  void paginationBufferRef.current.fetchForward();
18352
18365
  }, []);
18353
- const fetchBackward = useCallback8(() => {
18366
+ const fetchBackward = useCallback9(() => {
18354
18367
  void paginationBufferRef.current.fetchBackward();
18355
18368
  }, []);
18356
18369
  useEffect16(() => {
18357
18370
  fetchForward();
18358
18371
  }, [fetchForward]);
18359
18372
  const [clearingSpans, setClearingSpans] = useState10(false);
18360
- const clearSpans = useCallback8(async () => {
18373
+ const clearSpans = useCallback9(async () => {
18361
18374
  if (clearingSpans) {
18362
18375
  return;
18363
18376
  }
@@ -18375,7 +18388,7 @@ var useSpans = () => {
18375
18388
  }
18376
18389
  }, [clearingSpans, api]);
18377
18390
  const [streamPaused, setStreamPaused] = useState10(false);
18378
- const toggleStream = useCallback8(() => {
18391
+ const toggleStream = useCallback9(() => {
18379
18392
  setStreamPaused((previous) => !previous);
18380
18393
  }, []);
18381
18394
  useEffect16(() => {
@@ -18397,9 +18410,14 @@ var useSpans = () => {
18397
18410
  }
18398
18411
  }
18399
18412
  });
18400
- const clearFetchError = useCallback8(() => {
18413
+ const clearFetchError = useCallback9(() => {
18401
18414
  setFetchError(void 0);
18402
18415
  }, []);
18416
+ useEffect16(() => {
18417
+ if (fetchError instanceof AppInspectorDisabledError || fetchError instanceof ConnectionError) {
18418
+ reportDisabled();
18419
+ }
18420
+ }, [fetchError, reportDisabled]);
18403
18421
  return {
18404
18422
  clearFetchError,
18405
18423
  clearingSpans,
@@ -18427,7 +18445,7 @@ import { ArrowBack } from "@mui/icons-material";
18427
18445
  import { Box as Box19, Button as Button6, Drawer, Paper as Paper3 } from "@mui/material";
18428
18446
  import { styled } from "@mui/material/styles";
18429
18447
  import { ReactFlowProvider } from "@xyflow/react";
18430
- import { useCallback as useCallback10, useEffect as useEffect21, useRef as useRef17, useState as useState17 } from "react";
18448
+ import { useCallback as useCallback11, useEffect as useEffect21, useRef as useRef17, useState as useState17 } from "react";
18431
18449
 
18432
18450
  // src/components/event-details/event-details.tsx
18433
18451
  import { Close as Close2 } from "@mui/icons-material";
@@ -18798,7 +18816,7 @@ import { Box as Box11, useTheme as useTheme3 } from "@mui/material";
18798
18816
  var import_copy_to_clipboard = __toESM(require_copy_to_clipboard(), 1);
18799
18817
  import { jsx as jsx135, jsxs as jsxs126, Fragment as Fragment8 } from "react/jsx-runtime";
18800
18818
  import { Box as Box10, InputBase, NoSsr, SvgIcon, createTheme, ThemeProvider, Paper as Paper2 } from "@mui/material";
18801
- import { createContext as createContext10, useContext as useContext17, useState as useState12, useRef as useRef14, useCallback as useCallback9, useMemo as useMemo9, useEffect as useEffect17, memo as memo9 } from "react";
18819
+ import { createContext as createContext10, useContext as useContext17, useState as useState12, useRef as useRef14, useCallback as useCallback10, useMemo as useMemo9, useEffect as useEffect17, memo as memo9 } from "react";
18802
18820
  import { create, useStore, createStore } from "zustand";
18803
18821
  function r(e2) {
18804
18822
  var t2, f2, n2 = "";
@@ -19044,7 +19062,7 @@ function useClipboard() {
19044
19062
  let { timeout = 2e3 } = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
19045
19063
  const [copied, setCopied] = useState12(false);
19046
19064
  const copyTimeout = useRef14(null);
19047
- const handleCopyResult = useCallback9((value) => {
19065
+ const handleCopyResult = useCallback10((value) => {
19048
19066
  const current = copyTimeout.current;
19049
19067
  if (current) {
19050
19068
  window.clearTimeout(current);
@@ -19055,7 +19073,7 @@ function useClipboard() {
19055
19073
  timeout
19056
19074
  ]);
19057
19075
  const onCopy = useJsonViewerStore((store) => store.onCopy);
19058
- const copy = useCallback9(async (path, value) => {
19076
+ const copy = useCallback10(async (path, value) => {
19059
19077
  if (typeof onCopy === "function") {
19060
19078
  try {
19061
19079
  await onCopy(path, value, copyString);
@@ -19076,7 +19094,7 @@ function useClipboard() {
19076
19094
  handleCopyResult,
19077
19095
  onCopy
19078
19096
  ]);
19079
- const reset = useCallback9(() => {
19097
+ const reset = useCallback10(() => {
19080
19098
  setCopied(false);
19081
19099
  if (copyTimeout.current) {
19082
19100
  clearTimeout(copyTimeout.current);
@@ -19135,7 +19153,7 @@ function useInspect(path, value, nestedIndex) {
19135
19153
  }
19136
19154
  return isTrap ? false : typeof defaultInspectControl === "function" ? defaultInspectControl(path, value) : depth < defaultInspectDepth;
19137
19155
  });
19138
- const setInspect = useCallback9((apply) => {
19156
+ const setInspect = useCallback10((apply) => {
19139
19157
  set((oldState) => {
19140
19158
  const newState = typeof apply === "boolean" ? apply : apply(oldState);
19141
19159
  setInspectCache(path, newState, nestedIndex);
@@ -19212,7 +19230,7 @@ function defineEasyType(param) {
19212
19230
  const EasyTypeEditor = (param2) => {
19213
19231
  let { value, setValue, abortEditing, commitEditing } = param2;
19214
19232
  const color2 = useJsonViewerStore((store) => store.colorspace[colorKey]);
19215
- const handleKeyDown = useCallback9((event) => {
19233
+ const handleKeyDown = useCallback10((event) => {
19216
19234
  if (event.key === "Enter") {
19217
19235
  event.preventDefault();
19218
19236
  commitEditing(value);
@@ -19226,7 +19244,7 @@ function defineEasyType(param) {
19226
19244
  commitEditing,
19227
19245
  value
19228
19246
  ]);
19229
- const handleChange = useCallback9((event) => {
19247
+ const handleChange = useCallback10((event) => {
19230
19248
  setValue(event.target.value);
19231
19249
  }, [
19232
19250
  setValue
@@ -20139,7 +20157,7 @@ var DataKeyPair = (props) => {
20139
20157
  prevValue,
20140
20158
  value
20141
20159
  ]);
20142
- const startEditing = useCallback9((event) => {
20160
+ const startEditing = useCallback10((event) => {
20143
20161
  event.preventDefault();
20144
20162
  if (serialize) setTempValue(serialize(value));
20145
20163
  setEditing(true);
@@ -20147,14 +20165,14 @@ var DataKeyPair = (props) => {
20147
20165
  serialize,
20148
20166
  value
20149
20167
  ]);
20150
- const abortEditing = useCallback9(() => {
20168
+ const abortEditing = useCallback10(() => {
20151
20169
  setEditing(false);
20152
20170
  setTempValue("");
20153
20171
  }, [
20154
20172
  setEditing,
20155
20173
  setTempValue
20156
20174
  ]);
20157
- const commitEditing = useCallback9((newValue) => {
20175
+ const commitEditing = useCallback10((newValue) => {
20158
20176
  setEditing(false);
20159
20177
  if (!deserialize) return;
20160
20178
  try {
@@ -20290,7 +20308,7 @@ var DataKeyPair = (props) => {
20290
20308
  sx: {
20291
20309
  userSelect: "text"
20292
20310
  },
20293
- onMouseEnter: useCallback9(() => setHover(path, nestedIndex), [
20311
+ onMouseEnter: useCallback10(() => setHover(path, nestedIndex), [
20294
20312
  setHover,
20295
20313
  path,
20296
20314
  nestedIndex
@@ -20305,7 +20323,7 @@ var DataKeyPair = (props) => {
20305
20323
  letterSpacing: 0.5,
20306
20324
  opacity: 0.8
20307
20325
  },
20308
- onClick: useCallback9((event) => {
20326
+ onClick: useCallback10((event) => {
20309
20327
  if (event.isDefaultPrevented()) {
20310
20328
  return;
20311
20329
  }
@@ -20521,7 +20539,7 @@ var JsonViewerInner = (props) => {
20521
20539
  const prevValue = useJsonViewerStore((store) => store.prevValue);
20522
20540
  const emptyPath = useMemo9(() => [], []);
20523
20541
  const setHover = useJsonViewerStore((store) => store.setHover);
20524
- const onMouseLeave = useCallback9(() => setHover(null), [
20542
+ const onMouseLeave = useCallback10(() => setHover(null), [
20525
20543
  setHover
20526
20544
  ]);
20527
20545
  return /* @__PURE__ */ jsx135(Paper2, {
@@ -31350,7 +31368,7 @@ var TraceGraphPage = ({ onClose, spanId, traceId }) => {
31350
31368
  const [spans, setSpans] = useState17();
31351
31369
  const [loading, setLoading] = useState17(false);
31352
31370
  const [fetchError, setFetchError] = useState17();
31353
- const fetchSpans = useCallback10(async () => {
31371
+ const fetchSpans = useCallback11(async () => {
31354
31372
  setLoading(true);
31355
31373
  try {
31356
31374
  const spans2 = await fetchConnectedTraces(api, [traceId]);
@@ -31375,20 +31393,25 @@ var TraceGraphPage = ({ onClose, spanId, traceId }) => {
31375
31393
  spansReference.current = spans;
31376
31394
  }
31377
31395
  }, [spans, setSelectedEvent, spanId]);
31378
- const { checkStatus, status, statusError } = useAppInspectorStatus();
31379
- const handleEnable = useCallback10(async () => {
31396
+ const { checkStatus, reportDisabled, status, statusError } = useAppInspectorStatus();
31397
+ useEffect21(() => {
31398
+ if (fetchError instanceof AppInspectorDisabledError || fetchError instanceof ConnectionError) {
31399
+ reportDisabled();
31400
+ }
31401
+ }, [fetchError, reportDisabled]);
31402
+ const handleEnable = useCallback11(async () => {
31380
31403
  await api.setStatus({ status: "ENABLED" });
31381
31404
  void checkStatus();
31382
31405
  }, [api, checkStatus]);
31383
- const handleEventSelect = useCallback10((spanId2) => {
31406
+ const handleEventSelect = useCallback11((spanId2) => {
31384
31407
  const span = spans?.find((s2) => s2.span_id === spanId2);
31385
31408
  setSelectedEvent(span);
31386
31409
  setOpen(true);
31387
31410
  }, [spans]);
31388
- const handleRetry = useCallback10(() => {
31411
+ const handleRetry = useCallback11(() => {
31389
31412
  void checkStatus();
31390
31413
  }, [checkStatus]);
31391
- const navigateToSpansList = useCallback10(() => {
31414
+ const navigateToSpansList = useCallback11(() => {
31392
31415
  onClose?.();
31393
31416
  }, [onClose]);
31394
31417
  return /* @__PURE__ */ jsx145(
@@ -31440,7 +31463,7 @@ var SpansListPage = () => {
31440
31463
  warningCount
31441
31464
  } = useSpans();
31442
31465
  const { checking, checkStatus, status, statusError } = useAppInspectorStatus();
31443
- const clearSpansSync = useCallback11(() => {
31466
+ const clearSpansSync = useCallback12(() => {
31444
31467
  void clearSpans();
31445
31468
  }, [clearSpans]);
31446
31469
  const localstackVersion = status?.localstackVersion ?? (statusError instanceof AppInspectorNotFoundError ? statusError.localstackVersion : void 0);
@@ -31449,15 +31472,15 @@ var SpansListPage = () => {
31449
31472
  const [order2, setOrder] = useLocalStorage("spans-order", "oldest_first");
31450
31473
  const [selectedTraceId, setSelectedTraceId] = useState18();
31451
31474
  const [selectedSpanId, setSelectedSpanId] = useState18();
31452
- const navigateToSpan = useCallback11((span) => {
31475
+ const navigateToSpan = useCallback12((span) => {
31453
31476
  setSelectedTraceId(span.trace_id);
31454
31477
  setSelectedSpanId(span.span_id);
31455
31478
  }, []);
31456
- const handleRetry = useCallback11(() => {
31479
+ const handleRetry = useCallback12(() => {
31457
31480
  void checkStatus();
31458
31481
  fetchForward();
31459
31482
  }, [checkStatus, fetchForward]);
31460
- const handleEnable = useCallback11(async () => {
31483
+ const handleEnable = useCallback12(async () => {
31461
31484
  await api.setStatus({ status: "ENABLED" });
31462
31485
  clearFetchError();
31463
31486
  void checkStatus();