@prorobotech/openapi-k8s-toolkit 0.0.1-alpha.160 → 0.0.1-alpha.161

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.
@@ -1,9 +1,9 @@
1
1
  import styled, { createGlobalStyle } from 'styled-components';
2
- import K, { useState, useRef, useLayoutEffect, useEffect, Fragment, createContext, useContext, useMemo, createElement, isValidElement, cloneElement, useCallback, useInsertionEffect, useSyncExternalStore, memo, Suspense, useReducer } from 'react';
2
+ import K, { useState, useRef, useReducer, useEffect, useCallback, useLayoutEffect, Fragment, createContext, useContext, useMemo, createElement, isValidElement, cloneElement, useInsertionEffect, useSyncExternalStore, memo, Suspense } from 'react';
3
3
  import { Input, Tree, Modal, Alert, theme, Select, Tag, Breadcrumb, Spin, Menu, Tooltip, Space, Button, Flex, Typography, Card as Card$1, Row, Col, Tabs, Form, Popover, notification, Dropdown, Table, Slider, InputNumber, Switch, Result, Progress, Checkbox, Empty } from 'antd';
4
4
  import { LoadingOutlined, ExclamationCircleFilled, CloseCircleFilled, CheckCircleFilled, PlusOutlined, ClearOutlined, MinusOutlined, CaretDownOutlined, CaretRightOutlined, InfoCircleOutlined, EyeOutlined, EyeInvisibleOutlined, SearchOutlined, MoreOutlined, CheckOutlined, CloseOutlined, BugOutlined, EllipsisOutlined } from '@ant-design/icons';
5
- import { useQuery, useQueries, useQueryClient } from '@tanstack/react-query';
6
5
  import { Link, useNavigate, useLocation, useParams, useSearchParams } from 'react-router-dom';
6
+ import { useQueries, useQuery, useQueryClient } from '@tanstack/react-query';
7
7
 
8
8
  const Spacer$1 = styled.div`
9
9
  height: ${({ $space, $spaceMob, $samespace }) => {
@@ -8316,31 +8316,512 @@ const PaddingContainer = styled.div`
8316
8316
  padding: ${({ $padding }) => $padding};
8317
8317
  `;
8318
8318
 
8319
- const getDirectUnknownResource = async ({ uri }) => {
8320
- return axios.get(uri);
8319
+ const eventKey$1 = (e) => {
8320
+ const n = e.metadata?.name ?? "";
8321
+ const ns = e.metadata?.namespace ?? "";
8322
+ return `${ns}/${n}`;
8323
+ };
8324
+ const compareRV$1 = (a, b) => {
8325
+ if (a.length !== b.length) return a.length > b.length ? 1 : -1;
8326
+ return a > b ? 1 : a < b ? -1 : 0;
8321
8327
  };
8328
+ const getRV$1 = (item) => item?.metadata?.resourceVersion;
8322
8329
 
8323
- const useDirectUnknownResource = ({
8324
- uri,
8325
- queryKey,
8326
- refetchInterval,
8327
- isEnabled
8330
+ const reducer$1 = (state, action) => {
8331
+ switch (action.type) {
8332
+ case "RESET": {
8333
+ const order = action.items.map(eventKey$1);
8334
+ const byKey = {};
8335
+ action.items.forEach((it) => byKey[eventKey$1(it)] = it);
8336
+ return { order, byKey };
8337
+ }
8338
+ case "APPEND_PAGE": {
8339
+ const next = { ...state.byKey };
8340
+ const addKeys = [];
8341
+ action.items.forEach((it) => {
8342
+ const k = eventKey$1(it);
8343
+ if (!next[k]) addKeys.push(k);
8344
+ next[k] = it;
8345
+ });
8346
+ return { order: [...state.order, ...addKeys], byKey: next };
8347
+ }
8348
+ case "UPSERT": {
8349
+ const k = eventKey$1(action.item);
8350
+ const exists = Boolean(state.byKey[k]);
8351
+ const byKey = { ...state.byKey, [k]: action.item };
8352
+ const order = exists ? state.order : [k, ...state.order];
8353
+ return { order, byKey };
8354
+ }
8355
+ case "REMOVE": {
8356
+ if (!state.byKey[action.key]) return state;
8357
+ const byKey = { ...state.byKey };
8358
+ delete byKey[action.key];
8359
+ return { order: state.order.filter((k) => k !== action.key), byKey };
8360
+ }
8361
+ default:
8362
+ return state;
8363
+ }
8364
+ };
8365
+
8366
+ const isRecord = (v) => typeof v === "object" && v !== null;
8367
+ const readString = (obj, key) => {
8368
+ const val = obj[key];
8369
+ return typeof val === "string" ? val : void 0;
8370
+ };
8371
+ const itemRV = (it) => {
8372
+ const fromUtil = getRV$1(it);
8373
+ if (fromUtil) return fromUtil;
8374
+ if (!isRecord(it)) return void 0;
8375
+ const rvTop = readString(it, "resourceVersion");
8376
+ const mdRaw = isRecord(it["metadata"]) ? it["metadata"] : void 0;
8377
+ const rvMeta = mdRaw ? readString(mdRaw, "resourceVersion") : void 0;
8378
+ return rvTop ?? rvMeta;
8379
+ };
8380
+ const getMaxRV$1 = (items) => (items ?? []).reduce((max, it) => {
8381
+ const rv = itemRV(it);
8382
+ return rv && (!max || compareRV$1(rv, max) > 0) ? rv : max;
8383
+ }, void 0);
8384
+ const makeResId = (q) => `${q.apiGroup ?? ""}|${q.apiVersion}|${q.plural}|${q.namespace ?? ""}|${q.fieldSelector ?? ""}|${q.labelSelector ?? ""}`;
8385
+ const useListWatch = ({
8386
+ wsUrl,
8387
+ pageSize,
8388
+ paused = false,
8389
+ ignoreRemove = false,
8390
+ onStatus,
8391
+ onError,
8392
+ autoDrain = false,
8393
+ preserveStateOnUrlChange = true,
8394
+ isEnabled = true,
8395
+ // NEW default: socket gated by this flag
8396
+ query
8328
8397
  }) => {
8329
- return useQuery({
8330
- queryKey,
8331
- queryFn: async () => {
8332
- const response = await getDirectUnknownResource({
8333
- uri
8398
+ const resId = `${query.apiGroup ?? ""}|${query.apiVersion}|${query.plural}|${query.namespace ?? ""}|${query.fieldSelector ?? ""}|${query.labelSelector ?? ""}`;
8399
+ const resIdRef = useRef(resId);
8400
+ const [state, dispatch] = useReducer(reducer$1, { order: [], byKey: {} });
8401
+ const [contToken, setContToken] = useState();
8402
+ const [hasMore, setHasMore] = useState(false);
8403
+ const [status, setStatus] = useState(isEnabled ? "connecting" : "closed");
8404
+ const [lastError, setLastError] = useState(void 0);
8405
+ const [isPaused, setIsPaused] = useState(paused);
8406
+ const [isRemoveIgnored, setIsRemoveIgnored] = useState(ignoreRemove);
8407
+ const queryRef = useRef(query);
8408
+ const wsRef = useRef(null);
8409
+ const connectingRef = useRef(false);
8410
+ const mountedRef = useRef(true);
8411
+ const startedRef = useRef(false);
8412
+ const reconnectTimerRef = useRef(null);
8413
+ const backoffRef = useRef(750);
8414
+ const urlRef = useRef(wsUrl);
8415
+ const onMessageRef = useRef(() => {
8416
+ });
8417
+ const connectRef = useRef(() => {
8418
+ });
8419
+ const fetchingRef = useRef(false);
8420
+ const anchorRVRef = useRef(void 0);
8421
+ const haveAnchorRef = useRef(false);
8422
+ const enabledRef = useRef(isEnabled);
8423
+ const intentionalCloseRef = useRef(false);
8424
+ const suppressErrorsRef = useRef(false);
8425
+ const pausedRef = useRef(isPaused);
8426
+ const ignoreRemoveRef = useRef(isRemoveIgnored);
8427
+ useEffect(() => {
8428
+ pausedRef.current = isPaused;
8429
+ }, [isPaused]);
8430
+ useEffect(() => {
8431
+ ignoreRemoveRef.current = isRemoveIgnored;
8432
+ }, [isRemoveIgnored]);
8433
+ useEffect(() => {
8434
+ enabledRef.current = isEnabled;
8435
+ }, [isEnabled]);
8436
+ const clearErrorSafe = useCallback(() => {
8437
+ setLastError(void 0);
8438
+ }, []);
8439
+ const setStatusSafe = useCallback(
8440
+ (s) => {
8441
+ setStatus(s);
8442
+ onStatus?.(s);
8443
+ },
8444
+ [onStatus]
8445
+ );
8446
+ const setErrorSafe = useCallback(
8447
+ (msg) => {
8448
+ setLastError(msg);
8449
+ if (msg) onError?.(msg);
8450
+ },
8451
+ [onError]
8452
+ );
8453
+ const applyParam = (sp, key, v) => {
8454
+ if (v === void 0 || v === null || v === "") {
8455
+ sp.delete(key);
8456
+ return;
8457
+ }
8458
+ sp.set(key, String(v));
8459
+ };
8460
+ const buildWsUrl = useCallback((raw) => {
8461
+ let u;
8462
+ const base = window.location.origin;
8463
+ try {
8464
+ const hasScheme = /^[a-z]+:/i.test(raw);
8465
+ u = hasScheme ? new URL(raw) : new URL(raw.startsWith("/") ? raw : `/${raw}`, base);
8466
+ if (u.protocol === "http:") u.protocol = "ws:";
8467
+ if (u.protocol === "https:") u.protocol = "wss:";
8468
+ if (u.protocol !== "ws:" && u.protocol !== "wss:") {
8469
+ u = new URL(u.pathname + u.search + u.hash, base);
8470
+ u.protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
8471
+ }
8472
+ } catch {
8473
+ const origin = window.location.origin.replace(/^http/, "ws");
8474
+ u = new URL(raw.startsWith("/") ? raw : `/${raw}`, origin);
8475
+ }
8476
+ const q = queryRef.current;
8477
+ applyParam(u.searchParams, "namespace", q.namespace);
8478
+ applyParam(u.searchParams, "limit", q.initialLimit);
8479
+ applyParam(u.searchParams, "_continue", q.initialContinue);
8480
+ applyParam(u.searchParams, "apiGroup", q.apiGroup);
8481
+ applyParam(u.searchParams, "apiVersion", q.apiVersion);
8482
+ applyParam(u.searchParams, "plural", q.plural);
8483
+ applyParam(u.searchParams, "fieldSelector", q.fieldSelector);
8484
+ applyParam(u.searchParams, "labelSelector", q.labelSelector);
8485
+ if (haveAnchorRef.current && anchorRVRef.current) {
8486
+ u.searchParams.set("sinceRV", anchorRVRef.current);
8487
+ } else {
8488
+ u.searchParams.delete("sinceRV");
8489
+ }
8490
+ return u.toString();
8491
+ }, []);
8492
+ const closeWS = useCallback(() => {
8493
+ try {
8494
+ wsRef.current?.close();
8495
+ } catch {
8496
+ }
8497
+ wsRef.current = null;
8498
+ }, []);
8499
+ const scheduleReconnect = useCallback(() => {
8500
+ if (intentionalCloseRef.current) {
8501
+ intentionalCloseRef.current = false;
8502
+ return;
8503
+ }
8504
+ if (!enabledRef.current) {
8505
+ setStatusSafe("closed");
8506
+ connectingRef.current = false;
8507
+ return;
8508
+ }
8509
+ setStatusSafe("closed");
8510
+ connectingRef.current = false;
8511
+ const baseDelay = Math.min(backoffRef.current, 8e3);
8512
+ const jitter = Math.random() * 0.4 + 0.8;
8513
+ const wait = Math.floor(baseDelay * jitter);
8514
+ const next = Math.min(baseDelay * 2, 12e3);
8515
+ backoffRef.current = next;
8516
+ if (reconnectTimerRef.current) {
8517
+ window.clearTimeout(reconnectTimerRef.current);
8518
+ reconnectTimerRef.current = null;
8519
+ }
8520
+ reconnectTimerRef.current = window.setTimeout(() => {
8521
+ if (!mountedRef.current || !enabledRef.current) return;
8522
+ connectRef.current();
8523
+ }, wait);
8524
+ }, [setStatusSafe]);
8525
+ const connect = useCallback(() => {
8526
+ if (!mountedRef.current) return;
8527
+ if (!enabledRef.current) {
8528
+ setStatusSafe("closed");
8529
+ return;
8530
+ }
8531
+ if (connectingRef.current) return;
8532
+ if (wsRef.current && (wsRef.current.readyState === WebSocket.OPEN || wsRef.current.readyState === WebSocket.CONNECTING)) {
8533
+ return;
8534
+ }
8535
+ connectingRef.current = true;
8536
+ setStatusSafe("connecting");
8537
+ setErrorSafe(void 0);
8538
+ const url = buildWsUrl(urlRef.current);
8539
+ console.debug("[useListWatch] connecting to", url);
8540
+ const ws = new WebSocket(url);
8541
+ wsRef.current = ws;
8542
+ ws.addEventListener("open", () => {
8543
+ if (!mountedRef.current || !enabledRef.current) return;
8544
+ backoffRef.current = 750;
8545
+ fetchingRef.current = false;
8546
+ setStatusSafe("open");
8547
+ connectingRef.current = false;
8548
+ suppressErrorsRef.current = false;
8549
+ });
8550
+ ws.addEventListener("message", (ev) => onMessageRef.current(ev));
8551
+ ws.addEventListener("close", scheduleReconnect);
8552
+ ws.addEventListener("error", () => {
8553
+ if (intentionalCloseRef.current || suppressErrorsRef.current) return;
8554
+ setErrorSafe("WebSocket error");
8555
+ });
8556
+ }, [buildWsUrl, scheduleReconnect, setErrorSafe, setStatusSafe]);
8557
+ useEffect(() => {
8558
+ connectRef.current = connect;
8559
+ }, [connect]);
8560
+ const reconnect = useCallback(() => {
8561
+ if (!enabledRef.current) {
8562
+ closeWS();
8563
+ setStatusSafe("closed");
8564
+ return;
8565
+ }
8566
+ if (reconnectTimerRef.current) {
8567
+ window.clearTimeout(reconnectTimerRef.current);
8568
+ reconnectTimerRef.current = null;
8569
+ }
8570
+ intentionalCloseRef.current = true;
8571
+ try {
8572
+ wsRef.current?.close();
8573
+ } catch {
8574
+ }
8575
+ wsRef.current = null;
8576
+ connect();
8577
+ }, [closeWS, connect, setStatusSafe]);
8578
+ useEffect(() => {
8579
+ if (!mountedRef.current) return;
8580
+ if (isEnabled) {
8581
+ connect();
8582
+ } else {
8583
+ if (reconnectTimerRef.current) {
8584
+ window.clearTimeout(reconnectTimerRef.current);
8585
+ reconnectTimerRef.current = null;
8586
+ }
8587
+ closeWS();
8588
+ setStatusSafe("closed");
8589
+ }
8590
+ }, [isEnabled, closeWS, connect, setStatusSafe]);
8591
+ const setUrl = useCallback(
8592
+ (next) => {
8593
+ const changed = next !== urlRef.current;
8594
+ urlRef.current = next;
8595
+ if (changed) {
8596
+ clearErrorSafe();
8597
+ suppressErrorsRef.current = true;
8598
+ if (!preserveStateOnUrlChange) {
8599
+ dispatch({ type: "RESET", items: [] });
8600
+ setContToken(void 0);
8601
+ setHasMore(false);
8602
+ anchorRVRef.current = void 0;
8603
+ haveAnchorRef.current = false;
8604
+ }
8605
+ if (enabledRef.current) reconnect();
8606
+ }
8607
+ },
8608
+ [preserveStateOnUrlChange, reconnect, clearErrorSafe]
8609
+ );
8610
+ const setQuery = useCallback(
8611
+ (q) => {
8612
+ clearErrorSafe();
8613
+ suppressErrorsRef.current = true;
8614
+ const prev = queryRef.current;
8615
+ const prevId = makeResId(prev);
8616
+ const nextId = makeResId(q);
8617
+ queryRef.current = q;
8618
+ if (!preserveStateOnUrlChange) {
8619
+ dispatch({ type: "RESET", items: [] });
8620
+ setContToken(void 0);
8621
+ setHasMore(false);
8622
+ }
8623
+ if (prevId !== nextId) {
8624
+ anchorRVRef.current = void 0;
8625
+ haveAnchorRef.current = false;
8626
+ }
8627
+ if (enabledRef.current && prevId !== nextId) {
8628
+ reconnect();
8629
+ }
8630
+ },
8631
+ [clearErrorSafe, preserveStateOnUrlChange, reconnect]
8632
+ );
8633
+ const total = state.order.length;
8634
+ const continueToken = contToken;
8635
+ useEffect(() => {
8636
+ onMessageRef.current = (ev) => {
8637
+ let frame;
8638
+ try {
8639
+ frame = JSON.parse(String(ev.data));
8640
+ } catch {
8641
+ return;
8642
+ }
8643
+ if (!frame) return;
8644
+ if (frame.type === "INITIAL") {
8645
+ dispatch({ type: "RESET", items: frame.items });
8646
+ setContToken(frame.continue);
8647
+ setHasMore(Boolean(frame.continue));
8648
+ setErrorSafe(void 0);
8649
+ fetchingRef.current = false;
8650
+ suppressErrorsRef.current = false;
8651
+ const snapshotRV = frame.resourceVersion || getMaxRV$1(frame.items);
8652
+ if (snapshotRV) {
8653
+ anchorRVRef.current = snapshotRV;
8654
+ haveAnchorRef.current = true;
8655
+ }
8656
+ return;
8657
+ }
8658
+ if (frame.type === "PAGE") {
8659
+ dispatch({ type: "APPEND_PAGE", items: frame.items });
8660
+ setContToken(frame.continue);
8661
+ setHasMore(Boolean(frame.continue));
8662
+ fetchingRef.current = false;
8663
+ const batchRV = getMaxRV$1(frame.items);
8664
+ if (batchRV && (!anchorRVRef.current || compareRV$1(batchRV, anchorRVRef.current) > 0)) {
8665
+ anchorRVRef.current = batchRV;
8666
+ }
8667
+ return;
8668
+ }
8669
+ if (frame.type === "PAGE_ERROR") {
8670
+ setErrorSafe(frame.error || "Failed to load next page");
8671
+ fetchingRef.current = false;
8672
+ return;
8673
+ }
8674
+ if (frame.type === "ADDED" || frame.type === "MODIFIED" || frame.type === "DELETED") {
8675
+ const rv = itemRV(frame.item);
8676
+ if (rv && (!anchorRVRef.current || compareRV$1(rv, anchorRVRef.current) > 0)) {
8677
+ anchorRVRef.current = rv;
8678
+ }
8679
+ }
8680
+ if (!pausedRef.current) {
8681
+ if (frame.type === "ADDED" || frame.type === "MODIFIED") {
8682
+ dispatch({ type: "UPSERT", item: frame.item });
8683
+ }
8684
+ if (!ignoreRemoveRef.current && frame.type === "DELETED") {
8685
+ dispatch({ type: "REMOVE", key: eventKey$1(frame.item) });
8686
+ }
8687
+ }
8688
+ };
8689
+ }, [setErrorSafe]);
8690
+ useEffect(() => {
8691
+ if (startedRef.current) return void 0;
8692
+ startedRef.current = true;
8693
+ mountedRef.current = true;
8694
+ if (isEnabled) {
8695
+ connect();
8696
+ } else {
8697
+ setStatusSafe("closed");
8698
+ }
8699
+ return () => {
8700
+ mountedRef.current = false;
8701
+ startedRef.current = false;
8702
+ if (reconnectTimerRef.current) {
8703
+ window.clearTimeout(reconnectTimerRef.current);
8704
+ reconnectTimerRef.current = null;
8705
+ }
8706
+ closeWS();
8707
+ wsRef.current = null;
8708
+ connectingRef.current = false;
8709
+ };
8710
+ }, []);
8711
+ useEffect(() => {
8712
+ if (wsUrl !== urlRef.current) setUrl(wsUrl);
8713
+ }, [wsUrl, setUrl]);
8714
+ useEffect(() => {
8715
+ if (resIdRef.current !== resId) {
8716
+ clearErrorSafe();
8717
+ suppressErrorsRef.current = true;
8718
+ anchorRVRef.current = void 0;
8719
+ haveAnchorRef.current = false;
8720
+ resIdRef.current = resId;
8721
+ queryRef.current = query;
8722
+ if (enabledRef.current) reconnect();
8723
+ }
8724
+ }, [resId, query, reconnect, clearErrorSafe]);
8725
+ const pageSizeRef = useRef(pageSize);
8726
+ useEffect(() => {
8727
+ pageSizeRef.current = pageSize;
8728
+ }, [pageSize]);
8729
+ const sendScroll = useCallback(() => {
8730
+ if (!enabledRef.current) return;
8731
+ const token = contToken;
8732
+ if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) return;
8733
+ if (!token || fetchingRef.current) return;
8734
+ fetchingRef.current = true;
8735
+ const msg = { type: "SCROLL", continue: token, limit: pageSizeRef.current };
8736
+ wsRef.current.send(JSON.stringify(msg));
8737
+ }, [contToken]);
8738
+ const drainAll = useCallback(
8739
+ async (opts) => {
8740
+ if (!enabledRef.current) return 0;
8741
+ const maxPages = opts?.maxPages ?? 999;
8742
+ const maxItems = opts?.maxItems ?? Number.POSITIVE_INFINITY;
8743
+ let pages = 0;
8744
+ let added = 0;
8745
+ const awaitOnce = () => new Promise((resolve) => {
8746
+ const handler = (ev) => {
8747
+ try {
8748
+ const f = JSON.parse(String(ev.data));
8749
+ if (f.type === "PAGE") {
8750
+ const newCount = (f.items || []).reduce((acc, it) => {
8751
+ const k = eventKey$1(it);
8752
+ return state.byKey[k] ? acc : acc + 1;
8753
+ }, 0);
8754
+ added += newCount;
8755
+ const ws2 = wsRef.current;
8756
+ if (!ws2) {
8757
+ resolve("STOP");
8758
+ return;
8759
+ }
8760
+ resolve("PAGE");
8761
+ }
8762
+ } catch {
8763
+ }
8764
+ };
8765
+ const ws = wsRef.current;
8766
+ if (!ws) {
8767
+ resolve("STOP");
8768
+ return;
8769
+ }
8770
+ const stopCheck = () => {
8771
+ if (!hasMore || !contToken) {
8772
+ resolve("STOP");
8773
+ }
8774
+ };
8775
+ ws.addEventListener("message", handler, { once: true });
8776
+ setTimeout(stopCheck, 0);
8334
8777
  });
8335
- const data = JSON.parse(JSON.stringify(response.data));
8336
- if (data.metadata?.resourceVersion) {
8337
- delete data.metadata.resourceVersion;
8778
+ while (pages < maxPages && hasMore && contToken && wsRef.current?.readyState === WebSocket.OPEN) {
8779
+ if (added >= maxItems) break;
8780
+ if (!fetchingRef.current) sendScroll();
8781
+ const r = await awaitOnce();
8782
+ if (r === "STOP") break;
8783
+ pages += 1;
8338
8784
  }
8339
- return data;
8785
+ return added;
8340
8786
  },
8341
- refetchInterval: refetchInterval !== void 0 ? refetchInterval : 5e3,
8342
- enabled: isEnabled
8343
- });
8787
+ [contToken, hasMore, sendScroll, state.byKey]
8788
+ );
8789
+ useEffect(() => {
8790
+ if (!autoDrain) return;
8791
+ if (!enabledRef.current) return;
8792
+ if (status === "open" && haveAnchorRef.current) {
8793
+ drainAll().catch(() => {
8794
+ });
8795
+ }
8796
+ }, [autoDrain, drainAll, status]);
8797
+ return {
8798
+ state,
8799
+ total,
8800
+ hasMore,
8801
+ continueToken,
8802
+ status,
8803
+ lastError,
8804
+ setPaused: setIsPaused,
8805
+ setIgnoreRemove: setIsRemoveIgnored,
8806
+ sendScroll,
8807
+ drainAll,
8808
+ reconnect,
8809
+ setUrl,
8810
+ setQuery
8811
+ };
8812
+ };
8813
+
8814
+ const useInfiniteSentinel = (sentinelRef, hasMore, onNeedMore) => {
8815
+ useEffect(() => {
8816
+ const el = sentinelRef.current;
8817
+ if (!el) return void 0;
8818
+ const io = new IntersectionObserver((entries) => {
8819
+ const visible = entries.some((e) => e.isIntersecting);
8820
+ if (visible && hasMore) onNeedMore();
8821
+ });
8822
+ io.observe(el);
8823
+ return () => io.disconnect();
8824
+ }, [sentinelRef, hasMore, onNeedMore]);
8344
8825
  };
8345
8826
 
8346
8827
  const prepareTemplate = ({
@@ -8381,7 +8862,7 @@ const prepareDataForManageableBreadcrumbs = ({
8381
8862
  replaceValues,
8382
8863
  idToCompare
8383
8864
  }) => {
8384
- const foundData = data.find((el) => el.id === idToCompare);
8865
+ const foundData = data.find((el) => el?.id === idToCompare);
8385
8866
  if (!foundData) {
8386
8867
  return void 0;
8387
8868
  }
@@ -8480,23 +8961,37 @@ const ManageableBreadcrumbs = ({ data }) => {
8480
8961
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$v.HeightDiv, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleBreadcrumb, { items: data.breadcrumbItems }) });
8481
8962
  };
8482
8963
  const ManageableBreadcrumbsWithDataProvider = ({
8483
- uri,
8484
- refetchInterval,
8964
+ wsUrl,
8965
+ apiGroup,
8966
+ apiVersion,
8967
+ plural,
8485
8968
  isEnabled,
8486
8969
  replaceValues,
8487
8970
  pathname,
8488
8971
  idToCompare
8489
8972
  }) => {
8490
- const {
8491
- data: rawData,
8492
- isError: rawDataError,
8493
- isLoading: rawDataLoading
8494
- } = useDirectUnknownResource({
8495
- uri,
8496
- refetchInterval,
8497
- queryKey: ["breadcrumb", uri],
8973
+ const { state, status, lastError } = useListWatch({
8974
+ wsUrl,
8975
+ paused: false,
8976
+ ignoreRemove: false,
8977
+ autoDrain: true,
8978
+ preserveStateOnUrlChange: true,
8979
+ query: {
8980
+ apiVersion,
8981
+ apiGroup,
8982
+ plural
8983
+ },
8498
8984
  isEnabled
8499
8985
  });
8986
+ const rawDataLoading = status === "connecting";
8987
+ const rawDataError = status === "closed" && lastError ? lastError : void 0;
8988
+ const rawData = {
8989
+ items: state.order.map((key) => {
8990
+ const res = state.byKey[key];
8991
+ return res;
8992
+ })
8993
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8994
+ };
8500
8995
  if (rawDataError) {
8501
8996
  return null;
8502
8997
  }
@@ -8682,8 +9177,10 @@ const ManageableSidebar = ({ data, noMarginTop }) => {
8682
9177
  );
8683
9178
  };
8684
9179
  const ManageableSidebarWithDataProvider = ({
8685
- uri,
8686
- refetchInterval,
9180
+ wsUrl,
9181
+ apiGroup,
9182
+ apiVersion,
9183
+ plural,
8687
9184
  isEnabled,
8688
9185
  replaceValues,
8689
9186
  pathname,
@@ -8692,16 +9189,28 @@ const ManageableSidebarWithDataProvider = ({
8692
9189
  hidden,
8693
9190
  noMarginTop
8694
9191
  }) => {
8695
- const {
8696
- data: rawData,
8697
- isError: rawDataError,
8698
- isLoading: rawDataLoading
8699
- } = useDirectUnknownResource({
8700
- uri,
8701
- refetchInterval,
8702
- queryKey: ["sidebar", uri],
9192
+ const { state, status, lastError } = useListWatch({
9193
+ wsUrl,
9194
+ paused: false,
9195
+ ignoreRemove: false,
9196
+ autoDrain: true,
9197
+ preserveStateOnUrlChange: true,
9198
+ query: {
9199
+ apiVersion,
9200
+ apiGroup,
9201
+ plural
9202
+ },
8703
9203
  isEnabled
8704
9204
  });
9205
+ const rawDataLoading = status === "connecting";
9206
+ const rawDataError = status === "closed" && lastError ? lastError : void 0;
9207
+ const rawData = {
9208
+ items: state.order.map((key) => {
9209
+ const res = state.byKey[key];
9210
+ return res;
9211
+ })
9212
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9213
+ };
8705
9214
  if (rawDataError) {
8706
9215
  return null;
8707
9216
  }
@@ -33500,6 +34009,33 @@ const usePermissions = ({
33500
34009
  });
33501
34010
  };
33502
34011
 
34012
+ const getDirectUnknownResource = async ({ uri }) => {
34013
+ return axios.get(uri);
34014
+ };
34015
+
34016
+ const useDirectUnknownResource = ({
34017
+ uri,
34018
+ queryKey,
34019
+ refetchInterval,
34020
+ isEnabled
34021
+ }) => {
34022
+ return useQuery({
34023
+ queryKey,
34024
+ queryFn: async () => {
34025
+ const response = await getDirectUnknownResource({
34026
+ uri
34027
+ });
34028
+ const data = JSON.parse(JSON.stringify(response.data));
34029
+ if (data.metadata?.resourceVersion) {
34030
+ delete data.metadata.resourceVersion;
34031
+ }
34032
+ return data;
34033
+ },
34034
+ refetchInterval: refetchInterval !== void 0 ? refetchInterval : 5e3,
34035
+ enabled: isEnabled
34036
+ });
34037
+ };
34038
+
33503
34039
  const getBackLinkToTable = ({ fullPath }) => {
33504
34040
  return encodeURIComponent(fullPath);
33505
34041
  };
@@ -49677,22 +50213,6 @@ const getCreatePathToNav = ({
49677
50213
  }
49678
50214
  return `/${baseprefix}/${clusterName}/${namespace}/forms/builtin/${apiVersion}/${typeName}?backlink=${window.location.pathname}`;
49679
50215
  };
49680
- const getListPath = ({
49681
- clusterName,
49682
- namespace,
49683
- type,
49684
- typeName,
49685
- apiGroup,
49686
- apiVersion
49687
- }) => {
49688
- if (type === "crd") {
49689
- return `/api/clusters/${clusterName}/k8s/apis/${apiGroup}/${apiVersion}${namespace ? `/namespaces/${namespace}` : ""}/${typeName}`;
49690
- }
49691
- if (type === "nonCrd") {
49692
- return `/api/clusters/${clusterName}/k8s/apis/${apiGroup}/${apiVersion}${namespace ? `/namespaces/${namespace}` : ""}/${typeName}`;
49693
- }
49694
- return `/api/clusters/${clusterName}/k8s/api/v1${namespace ? `/namespaces/${namespace}` : ""}/${typeName}`;
49695
- };
49696
50216
 
49697
50217
  const CustomCard$4 = styled(Card$1)`
49698
50218
  position: relative;
@@ -49825,20 +50345,28 @@ const MarketplaceCard = ({
49825
50345
  apiVersion,
49826
50346
  baseprefix
49827
50347
  });
49828
- const listUrl = addedMode && type !== "direct" ? getListPath({
49829
- clusterName,
49830
- namespace,
49831
- type,
49832
- typeName,
49833
- apiGroup,
49834
- apiVersion
49835
- }) : void 0;
49836
- const { data: k8sList, error: k8sListError } = useDirectUnknownResource({
49837
- uri: listUrl || "",
49838
- queryKey: [listUrl || ""],
49839
- refetchInterval: false,
49840
- isEnabled: addedMode && listUrl !== void 0
50348
+ const { state, status, lastError } = useListWatch({
50349
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50350
+ paused: false,
50351
+ ignoreRemove: false,
50352
+ autoDrain: true,
50353
+ preserveStateOnUrlChange: true,
50354
+ query: {
50355
+ namespace,
50356
+ apiVersion: apiVersion || "",
50357
+ apiGroup,
50358
+ plural: type
50359
+ },
50360
+ isEnabled: Boolean(apiVersion && addedMode && type !== "direct")
49841
50361
  });
50362
+ const k8sListError = status === "closed" && lastError ? lastError : void 0;
50363
+ const k8sList = {
50364
+ items: state.order.map((key) => {
50365
+ const res = state.byKey[key];
50366
+ return res;
50367
+ })
50368
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50369
+ };
49842
50370
  if (addedMode && (k8sListError || type === "direct") && !showZeroResources) {
49843
50371
  return null;
49844
50372
  }
@@ -49967,16 +50495,30 @@ const MarketPlace = ({
49967
50495
  const [filteredAndSortedData, setFilterAndSortedData] = useState([]);
49968
50496
  const [uniqueTags, setUniqueTags] = useState([]);
49969
50497
  const [selectedTags, setSelectedTags] = useState([]);
49970
- const {
49971
- data: marketplacePanels,
49972
- isLoading,
49973
- error
49974
- } = useDirectUnknownResource({
49975
- uri: `/api/clusters/${clusterName}/k8s/apis/${baseApiGroup}/${baseApiVersion}/${mpResourceName}/`,
49976
- refetchInterval: 5e3,
49977
- queryKey: ["marketplacePanels", clusterName || "no-cluster"],
50498
+ const { state, status, lastError } = useListWatch({
50499
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50500
+ paused: false,
50501
+ ignoreRemove: false,
50502
+ autoDrain: true,
50503
+ preserveStateOnUrlChange: true,
50504
+ query: {
50505
+ apiVersion: baseApiVersion,
50506
+ apiGroup: baseApiGroup,
50507
+ plural: mpResourceName
50508
+ },
49978
50509
  isEnabled: clusterName !== void 0
49979
50510
  });
50511
+ const isLoading = status === "connecting";
50512
+ const error = status === "closed" && lastError ? lastError : void 0;
50513
+ const marketplacePanels = useMemo(() => {
50514
+ return {
50515
+ items: state.order.map((key) => {
50516
+ const res = state.byKey[key];
50517
+ return res;
50518
+ })
50519
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50520
+ };
50521
+ }, [state]);
49980
50522
  const createPermission = usePermissions({
49981
50523
  group: baseApiGroup,
49982
50524
  resource: mpResourceName,
@@ -50275,26 +50817,52 @@ const ProjectInfoCard = ({
50275
50817
  children
50276
50818
  }) => {
50277
50819
  const navigate = useNavigate();
50278
- const {
50279
- data: marketplacePanels,
50280
- isLoading: marketplaceIsLoading
50281
- // error: marketplaceError,
50282
- } = useDirectUnknownResource({
50283
- uri: `/api/clusters/${clusterName}/k8s/apis/${baseApiGroup}/${baseApiVersion}/${mpResourceName}/`,
50284
- refetchInterval: 5e3,
50285
- queryKey: ["marketplacePanels", clusterName || "no-cluster"],
50820
+ const { state, status } = useListWatch({
50821
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50822
+ paused: false,
50823
+ ignoreRemove: false,
50824
+ autoDrain: true,
50825
+ preserveStateOnUrlChange: true,
50826
+ query: {
50827
+ apiVersion: baseApiVersion,
50828
+ apiGroup: baseApiGroup,
50829
+ plural: mpResourceName
50830
+ },
50286
50831
  isEnabled: clusterName !== void 0
50287
50832
  });
50833
+ const marketplaceIsLoading = status === "connecting";
50834
+ const marketplacePanels = {
50835
+ items: state.order.map((key) => {
50836
+ const res = state.byKey[key];
50837
+ return res;
50838
+ })
50839
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50840
+ };
50288
50841
  const {
50289
- data: project,
50290
- isLoading,
50291
- error
50292
- } = useDirectUnknownResource({
50293
- uri: `/api/clusters/${clusterName}/k8s/apis/${baseProjectApiGroup}/${baseProjectVersion}/${projectResourceName}/${namespace}`,
50294
- refetchInterval: 5e3,
50295
- queryKey: ["projects", clusterName || "no-cluster"],
50842
+ state: stateProject,
50843
+ status: statusProject,
50844
+ lastError: lastErrorProject
50845
+ } = useListWatch({
50846
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50847
+ paused: false,
50848
+ ignoreRemove: false,
50849
+ autoDrain: true,
50850
+ preserveStateOnUrlChange: true,
50851
+ query: {
50852
+ apiVersion: baseProjectVersion,
50853
+ apiGroup: baseProjectApiGroup,
50854
+ plural: projectResourceName,
50855
+ fieldSelector: `metadata.name=${namespace}`
50856
+ },
50296
50857
  isEnabled: clusterName !== void 0
50297
50858
  });
50859
+ const isLoading = statusProject === "connecting";
50860
+ const error = statusProject === "closed" && lastErrorProject ? lastErrorProject : void 0;
50861
+ const projectArr = stateProject.order.map((key) => {
50862
+ const res = stateProject.byKey[key];
50863
+ return res;
50864
+ });
50865
+ const project = projectArr.length > 0 ? projectArr[0] : void 0;
50298
50866
  const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
50299
50867
  const updatePermission = usePermissions({
50300
50868
  group: baseProjectApiGroup,
@@ -52901,5 +53469,5 @@ const useCrdData = ({
52901
53469
  });
52902
53470
  };
52903
53471
 
52904
- export { BackToDefaultIcon, BlackholeForm, BlackholeFormDataProvider, ContentCard$1 as ContentCard, CursorDefaultDiv, CursorPointerTag, CursorPointerTagMinContent, CustomSelect$4 as CustomSelect, DeleteIcon, DeleteModal, DeleteModalMany, DownIcon, DynamicComponents, DynamicRenderer, DynamicRendererWithProviders, EarthIcon, EditIcon, EnrichedTable, EnrichedTableProvider, Events, FlexGrow, LockedIcon, LookingGlassIcon, ManageableBreadcrumbs, ManageableBreadcrumbsWithDataProvider, ManageableSidebar, ManageableSidebarWithDataProvider, MarketPlace, MarketplaceCard, MinusIcon, NodeTerminal, PaddingContainer, PauseCircleIcon, PlusIcon, PodLogs, PodLogsMonaco, PodTerminal, ProjectInfoCard, ResumeCircleIcon, Search, Spacer$1 as Spacer, SuccessIcon, TreeWithSearch, UncontrolledSelect, UnlockedIcon, UpIcon, YamlEditorSingleton, checkIfApiInstanceNamespaceScoped, checkIfBuiltInInstanceNamespaceScoped, checkPermission, createContextFactory, createNewEntry, deepMerge, deleteEntry, feedbackIcons, filterIfApiInstanceNamespaceScoped, filterIfBuiltInInstanceNamespaceScoped, filterSelectOptions, floorToDecimal, getAllPathsFromObj, getApiResourceSingle, getApiResourceTypes, getApiResourceTypesByApiGroup, getApiResources, getBackLinkToTable, getBuiltinResourceSingle, getBuiltinResourceTypes, getBuiltinResources, getBuiltinTreeData, getClusterList, getCrdData, getCrdResourceSingle, getCrdResources, getDirectUnknownResource, getEnrichedColumns, getEnrichedColumnsWithControls, getGroupsByCategory, getKinds, getLinkToApiForm, getLinkToBuiltinForm, getLinkToForm, getObjectFormItemsDraft, getPrefixSubarrays, getSortedKinds, getSortedKindsAll, getStringByName, getSwagger, getUppercase, groupsToTreeData, hslFromString, isFlatObject, isMultilineFromYaml, isMultilineString, kindByGvr, namespacedByGvr, normalizeValuesForQuotasToNumber, parseQuotaValue, parseQuotaValueCpu, parseQuotaValueMemoryAndStorage, pluralByKind, prepareDataForManageableBreadcrumbs, prepareDataForManageableSidebar, prepareTemplate, prepareUrlsToFetchForDynamicRenderer, updateEntry, useApiResourceSingle, useApiResourceTypesByGroup, useApiResources, useApisResourceTypes, useBuiltinResourceSingle, useBuiltinResourceTypes, useBuiltinResources, useClusterList, useCrdData, useCrdResourceSingle, useCrdResources, useDirectUnknownResource, usePermissions };
53472
+ export { BackToDefaultIcon, BlackholeForm, BlackholeFormDataProvider, ContentCard$1 as ContentCard, CursorDefaultDiv, CursorPointerTag, CursorPointerTagMinContent, CustomSelect$4 as CustomSelect, DeleteIcon, DeleteModal, DeleteModalMany, DownIcon, DynamicComponents, DynamicRenderer, DynamicRendererWithProviders, EarthIcon, EditIcon, EnrichedTable, EnrichedTableProvider, Events, FlexGrow, LockedIcon, LookingGlassIcon, ManageableBreadcrumbs, ManageableBreadcrumbsWithDataProvider, ManageableSidebar, ManageableSidebarWithDataProvider, MarketPlace, MarketplaceCard, MinusIcon, NodeTerminal, PaddingContainer, PauseCircleIcon, PlusIcon, PodLogs, PodLogsMonaco, PodTerminal, ProjectInfoCard, ResumeCircleIcon, Search, Spacer$1 as Spacer, SuccessIcon, TreeWithSearch, UncontrolledSelect, UnlockedIcon, UpIcon, YamlEditorSingleton, checkIfApiInstanceNamespaceScoped, checkIfBuiltInInstanceNamespaceScoped, checkPermission, createContextFactory, createNewEntry, deepMerge, deleteEntry, feedbackIcons, filterIfApiInstanceNamespaceScoped, filterIfBuiltInInstanceNamespaceScoped, filterSelectOptions, floorToDecimal, getAllPathsFromObj, getApiResourceSingle, getApiResourceTypes, getApiResourceTypesByApiGroup, getApiResources, getBackLinkToTable, getBuiltinResourceSingle, getBuiltinResourceTypes, getBuiltinResources, getBuiltinTreeData, getClusterList, getCrdData, getCrdResourceSingle, getCrdResources, getDirectUnknownResource, getEnrichedColumns, getEnrichedColumnsWithControls, getGroupsByCategory, getKinds, getLinkToApiForm, getLinkToBuiltinForm, getLinkToForm, getObjectFormItemsDraft, getPrefixSubarrays, getSortedKinds, getSortedKindsAll, getStringByName, getSwagger, getUppercase, groupsToTreeData, hslFromString, isFlatObject, isMultilineFromYaml, isMultilineString, kindByGvr, namespacedByGvr, normalizeValuesForQuotasToNumber, parseQuotaValue, parseQuotaValueCpu, parseQuotaValueMemoryAndStorage, pluralByKind, prepareDataForManageableBreadcrumbs, prepareDataForManageableSidebar, prepareTemplate, prepareUrlsToFetchForDynamicRenderer, updateEntry, useApiResourceSingle, useApiResourceTypesByGroup, useApiResources, useApisResourceTypes, useBuiltinResourceSingle, useBuiltinResourceTypes, useBuiltinResources, useClusterList, useCrdData, useCrdResourceSingle, useCrdResources, useDirectUnknownResource, useInfiniteSentinel, useListWatch, usePermissions };
52905
53473
  //# sourceMappingURL=openapi-k8s-toolkit.es.js.map