@hexclave/dashboard-ui-components 1.0.51 → 1.0.53

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.
@@ -4461,6 +4461,49 @@ This is likely an error in Hexclave. Please make sure you are running the newest
4461
4461
  return Object.assign(Result.error(new RetryError(errors)), { attempts: totalAttempts });
4462
4462
  }
4463
4463
 
4464
+ // ../shared/dist/esm/utils/bytes.js
4465
+ function decodeBase64(input) {
4466
+ return new Uint8Array(atob(input).split("").map((char) => char.charCodeAt(0)));
4467
+ }
4468
+ function isBase64(input) {
4469
+ return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(input);
4470
+ }
4471
+
4472
+ // ../shared/dist/esm/utils/urls.js
4473
+ function createUrlIfValid(...args) {
4474
+ try {
4475
+ return new URL(...args);
4476
+ } catch (e40) {
4477
+ return null;
4478
+ }
4479
+ }
4480
+ function isValidUrl(url) {
4481
+ return !!createUrlIfValid(url);
4482
+ }
4483
+ function isValidHostname(hostname) {
4484
+ if (!hostname || hostname.startsWith(".") || hostname.endsWith(".") || hostname.includes("..")) return false;
4485
+ const url = createUrlIfValid(`https://${hostname}`);
4486
+ if (!url) return false;
4487
+ return url.hostname === hostname;
4488
+ }
4489
+ function isValidHostnameWithWildcards(hostname) {
4490
+ if (!hostname) return false;
4491
+ if (!hostname.includes("*")) return isValidHostname(hostname);
4492
+ if (hostname.startsWith(".") || hostname.endsWith(".")) return false;
4493
+ if (hostname.includes("..")) return false;
4494
+ const testHostname = hostname.replace(/\*+/g, "wildcard");
4495
+ if (!/^[a-zA-Z0-9.-]+$/.test(testHostname)) return false;
4496
+ const segments = hostname.split(/\*+/);
4497
+ for (let i = 0; i < segments.length; i++) {
4498
+ const segment = segments[i];
4499
+ if (segment === "") continue;
4500
+ if (i === 0 && segment.startsWith(".")) return false;
4501
+ if (i === segments.length - 1 && segment.endsWith(".")) return false;
4502
+ if (segment.includes("..")) return false;
4503
+ }
4504
+ return true;
4505
+ }
4506
+
4464
4507
  // ../shared/dist/esm/known-errors.js
4465
4508
  var KnownError = class extends StatusError {
4466
4509
  constructor(statusCode, humanReadableMessage, details) {
@@ -5217,49 +5260,6 @@ This is likely an error in Hexclave. Please make sure you are running the newest
5217
5260
  knownErrorCodes.add(KnownError2.errorCode);
5218
5261
  }
5219
5262
 
5220
- // ../shared/dist/esm/utils/bytes.js
5221
- function decodeBase64(input) {
5222
- return new Uint8Array(atob(input).split("").map((char) => char.charCodeAt(0)));
5223
- }
5224
- function isBase64(input) {
5225
- return /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(input);
5226
- }
5227
-
5228
- // ../shared/dist/esm/utils/urls.js
5229
- function createUrlIfValid(...args) {
5230
- try {
5231
- return new URL(...args);
5232
- } catch (e40) {
5233
- return null;
5234
- }
5235
- }
5236
- function isValidUrl(url) {
5237
- return !!createUrlIfValid(url);
5238
- }
5239
- function isValidHostname(hostname) {
5240
- if (!hostname || hostname.startsWith(".") || hostname.endsWith(".") || hostname.includes("..")) return false;
5241
- const url = createUrlIfValid(`https://${hostname}`);
5242
- if (!url) return false;
5243
- return url.hostname === hostname;
5244
- }
5245
- function isValidHostnameWithWildcards(hostname) {
5246
- if (!hostname) return false;
5247
- if (!hostname.includes("*")) return isValidHostname(hostname);
5248
- if (hostname.startsWith(".") || hostname.endsWith(".")) return false;
5249
- if (hostname.includes("..")) return false;
5250
- const testHostname = hostname.replace(/\*+/g, "wildcard");
5251
- if (!/^[a-zA-Z0-9.-]+$/.test(testHostname)) return false;
5252
- const segments = hostname.split(/\*+/);
5253
- for (let i = 0; i < segments.length; i++) {
5254
- const segment = segments[i];
5255
- if (segment === "") continue;
5256
- if (i === 0 && segment.startsWith(".")) return false;
5257
- if (i === segments.length - 1 && segment.endsWith(".")) return false;
5258
- if (segment.includes("..")) return false;
5259
- }
5260
- return true;
5261
- }
5262
-
5263
5263
  // ../../node_modules/.pnpm/yup@1.7.1/node_modules/yup/index.esm.js
5264
5264
  var import_property_expr = __toESM(require_property_expr());
5265
5265
  var import_tiny_case = __toESM(require_tiny_case());
@@ -9780,14 +9780,17 @@ attempted value: ${formattedValue}
9780
9780
  if (error instanceof Error) concatStacktraces(error, currentError);
9781
9781
  });
9782
9782
  }
9783
- async function wait(ms) {
9783
+ async function wait(ms, options) {
9784
9784
  if (!Number.isFinite(ms) || ms < 0) throw new HexclaveAssertionError(`wait() requires a non-negative integer number of milliseconds to wait. (found: ${ms}ms)`);
9785
9785
  if (ms >= 2 ** 31) throw new HexclaveAssertionError("The maximum timeout for wait() is 2147483647ms (2**31 - 1). (found: ${ms}ms)");
9786
9786
  return await traceSpan({
9787
9787
  description: "wait(...)",
9788
9788
  attributes: { "stack.wait.ms": ms }
9789
9789
  }, async (span) => {
9790
- return await new Promise((resolve) => setTimeout(resolve, ms));
9790
+ return await new Promise((resolve) => {
9791
+ const timeout = setTimeout(resolve, ms);
9792
+ if (options?.unref === true && typeof timeout === "object") timeout.unref();
9793
+ });
9791
9794
  });
9792
9795
  }
9793
9796
  function runAsynchronouslyWithAlert(...args) {
@@ -23991,10 +23994,15 @@ ${colorConfig.map(([key, itemConfig]) => {
23991
23994
  const [hasMore, setHasMore] = (0, import_react36.useState)(true);
23992
23995
  const [error, setError] = (0, import_react36.useState)(null);
23993
23996
  const cursorRef = (0, import_react36.useRef)(void 0);
23994
- const abortRef = (0, import_react36.useRef)(null);
23997
+ const inFlightFetchRef = (0, import_react36.useRef)(null);
23998
+ const pendingLoadMoreRef = (0, import_react36.useRef)(false);
23999
+ const hasMoreRef = (0, import_react36.useRef)(true);
24000
+ const paginationModeRef = (0, import_react36.useRef)(paginationMode);
24001
+ paginationModeRef.current = paginationMode;
23995
24002
  const pageIndexRef = (0, import_react36.useRef)(0);
23996
24003
  const hasDataRef = (0, import_react36.useRef)(false);
23997
24004
  const hasMountedServerPaginationRef = (0, import_react36.useRef)(false);
24005
+ const lastCompletedNonAppendFetchKeyRef = (0, import_react36.useRef)(null);
23998
24006
  const latestArgsRef = (0, import_react36.useRef)({
23999
24007
  dataSource,
24000
24008
  getRowId,
@@ -24007,6 +24015,9 @@ ${colorConfig.map(([key, itemConfig]) => {
24007
24015
  const quickSearchKey = quickSearch;
24008
24016
  const fetchPage = (0, import_react36.useCallback)(
24009
24017
  async (append) => {
24018
+ if (append && inFlightFetchRef.current != null) {
24019
+ return;
24020
+ }
24010
24021
  const {
24011
24022
  dataSource: currentDataSource,
24012
24023
  getRowId: currentGetRowId,
@@ -24014,9 +24025,15 @@ ${colorConfig.map(([key, itemConfig]) => {
24014
24025
  quickSearch: currentQuickSearch,
24015
24026
  pagination: currentPagination
24016
24027
  } = latestArgsRef.current;
24017
- abortRef.current?.abort();
24028
+ inFlightFetchRef.current?.abort();
24018
24029
  const controller = new AbortController();
24019
- abortRef.current = controller;
24030
+ inFlightFetchRef.current = controller;
24031
+ const fetchKey = {
24032
+ dataSource: currentDataSource,
24033
+ sortingKey: JSON.stringify(currentSorting),
24034
+ quickSearchKey: currentQuickSearch,
24035
+ pageSize: currentPagination.pageSize
24036
+ };
24020
24037
  if (append) {
24021
24038
  setIsLoadingMore(true);
24022
24039
  } else {
@@ -24025,16 +24042,18 @@ ${colorConfig.map(([key, itemConfig]) => {
24025
24042
  } else {
24026
24043
  setIsLoading(true);
24027
24044
  }
24028
- cursorRef.current = void 0;
24029
- pageIndexRef.current = 0;
24030
24045
  }
24031
24046
  setError(null);
24047
+ let cursor = append ? cursorRef.current : void 0;
24048
+ let pageIndex = append ? pageIndexRef.current : 0;
24049
+ let failed = false;
24050
+ let committedResult = false;
24032
24051
  try {
24033
24052
  const params = {
24034
24053
  sorting: currentSorting,
24035
24054
  quickSearch: currentQuickSearch,
24036
- pagination: append ? { pageIndex: pageIndexRef.current, pageSize: currentPagination.pageSize } : currentPagination,
24037
- cursor: cursorRef.current
24055
+ pagination: append ? { pageIndex, pageSize: currentPagination.pageSize } : currentPagination,
24056
+ cursor
24038
24057
  };
24039
24058
  const gen = currentDataSource(params);
24040
24059
  for await (const result of gen) {
@@ -24043,9 +24062,11 @@ ${colorConfig.map(([key, itemConfig]) => {
24043
24062
  setTotalRowCount(result.totalRowCount);
24044
24063
  }
24045
24064
  if (result.nextCursor !== void 0) {
24046
- cursorRef.current = result.nextCursor;
24065
+ cursor = result.nextCursor;
24047
24066
  }
24048
- setHasMore(result.hasMore !== false);
24067
+ cursorRef.current = cursor;
24068
+ hasMoreRef.current = result.hasMore !== false;
24069
+ setHasMore(hasMoreRef.current);
24049
24070
  if (append) {
24050
24071
  setRows((prev) => {
24051
24072
  const existingIds = new Set(prev.map(currentGetRowId));
@@ -24055,29 +24076,50 @@ ${colorConfig.map(([key, itemConfig]) => {
24055
24076
  return [...prev, ...newRows];
24056
24077
  });
24057
24078
  } else {
24079
+ lastCompletedNonAppendFetchKeyRef.current = null;
24058
24080
  setRows(result.rows);
24059
24081
  }
24060
24082
  hasDataRef.current = true;
24061
- pageIndexRef.current++;
24083
+ committedResult = true;
24084
+ pageIndex++;
24085
+ pageIndexRef.current = pageIndex;
24086
+ }
24087
+ if (!append && committedResult && !controller.signal.aborted) {
24088
+ lastCompletedNonAppendFetchKeyRef.current = fetchKey;
24062
24089
  }
24063
24090
  } catch (err) {
24064
24091
  if (controller.signal.aborted) return;
24065
24092
  console.error("[DataGrid] Data source error:", err);
24093
+ failed = true;
24066
24094
  setError(err instanceof Error ? err : new Error(String(err)));
24067
24095
  } finally {
24068
- if (!controller.signal.aborted) {
24096
+ if (inFlightFetchRef.current === controller) {
24097
+ inFlightFetchRef.current = null;
24069
24098
  setIsLoading(false);
24070
24099
  setIsRefetching(false);
24071
24100
  setIsLoadingMore(false);
24101
+ const shouldChainLoadMore = pendingLoadMoreRef.current && !failed && !controller.signal.aborted && hasMoreRef.current && paginationModeRef.current === "infinite";
24102
+ pendingLoadMoreRef.current = false;
24103
+ if (shouldChainLoadMore) {
24104
+ runAsynchronously(fetchPage(true));
24105
+ }
24072
24106
  }
24073
24107
  }
24074
24108
  },
24075
24109
  []
24076
24110
  );
24077
24111
  (0, import_react36.useEffect)(() => {
24078
- fetchPage(false).catch(() => {
24079
- });
24080
- return () => abortRef.current?.abort();
24112
+ if (paginationMode !== "infinite") {
24113
+ pendingLoadMoreRef.current = false;
24114
+ }
24115
+ }, [paginationMode]);
24116
+ (0, import_react36.useEffect)(() => {
24117
+ const lastCompletedKey = lastCompletedNonAppendFetchKeyRef.current;
24118
+ const isSameCompletedFetch = hasDataRef.current && lastCompletedKey?.dataSource === dataSource && lastCompletedKey.sortingKey === sortingKey && lastCompletedKey.quickSearchKey === quickSearchKey && lastCompletedKey.pageSize === pagination.pageSize;
24119
+ if (!isSameCompletedFetch) {
24120
+ runAsynchronously(fetchPage(false));
24121
+ }
24122
+ return () => inFlightFetchRef.current?.abort();
24081
24123
  }, [fetchPage, dataSource, sortingKey, quickSearchKey, pagination.pageSize]);
24082
24124
  (0, import_react36.useEffect)(() => {
24083
24125
  if (paginationMode !== "server") {
@@ -24088,18 +24130,20 @@ ${colorConfig.map(([key, itemConfig]) => {
24088
24130
  hasMountedServerPaginationRef.current = true;
24089
24131
  return;
24090
24132
  }
24091
- fetchPage(false).catch(() => {
24092
- });
24133
+ runAsynchronously(fetchPage(false));
24093
24134
  }, [fetchPage, paginationMode, pagination.pageIndex]);
24094
24135
  const loadMore = (0, import_react36.useCallback)(() => {
24095
- if (!isLoadingMore && hasMore && paginationMode === "infinite") {
24096
- fetchPage(true).catch(() => {
24097
- });
24136
+ if (paginationMode !== "infinite" || !hasMore) {
24137
+ return;
24098
24138
  }
24099
- }, [isLoadingMore, hasMore, paginationMode, fetchPage]);
24139
+ if (inFlightFetchRef.current != null) {
24140
+ pendingLoadMoreRef.current = true;
24141
+ return;
24142
+ }
24143
+ runAsynchronously(fetchPage(true));
24144
+ }, [hasMore, paginationMode, fetchPage]);
24100
24145
  const reload = (0, import_react36.useCallback)(() => {
24101
- fetchPage(false).catch(() => {
24102
- });
24146
+ runAsynchronously(fetchPage(false));
24103
24147
  }, [fetchPage]);
24104
24148
  return {
24105
24149
  rows,