@prorobotech/openapi-k8s-toolkit 1.0.3 → 1.1.0-alpha.1

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,8 +1,8 @@
1
1
  (function (global, factory) {
2
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('styled-components'), require('react'), require('antd'), require('@ant-design/icons'), require('@tanstack/react-query'), require('react-router-dom')) :
3
- typeof define === 'function' && define.amd ? define(['exports', 'styled-components', 'react', 'antd', '@ant-design/icons', '@tanstack/react-query', 'react-router-dom'], factory) :
4
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@prorobotech/openapi-k8s-toolkit"] = {}, global.styled, global.React, global.antd, global.antdIcons, global.reactQuery, global.ReactRouterDOM));
5
- })(this, (function (exports, styled, K, antd, icons, reactQuery, reactRouterDom) { 'use strict';
2
+ typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('styled-components'), require('react'), require('antd'), require('@ant-design/icons'), require('react-router-dom'), require('@tanstack/react-query')) :
3
+ typeof define === 'function' && define.amd ? define(['exports', 'styled-components', 'react', 'antd', '@ant-design/icons', 'react-router-dom', '@tanstack/react-query'], factory) :
4
+ (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global["@prorobotech/openapi-k8s-toolkit"] = {}, global.styled, global.React, global.antd, global.antdIcons, global.ReactRouterDOM, global.reactQuery));
5
+ })(this, (function (exports, styled, K, antd, icons, reactRouterDom, reactQuery) { 'use strict';
6
6
 
7
7
  const Spacer$1 = styled.div`
8
8
  height: ${({ $space, $spaceMob, $samespace }) => {
@@ -8315,31 +8315,512 @@
8315
8315
  padding: ${({ $padding }) => $padding};
8316
8316
  `;
8317
8317
 
8318
- const getDirectUnknownResource = async ({ uri }) => {
8319
- return axios.get(uri);
8318
+ const eventKey$1 = (e) => {
8319
+ const n = e.metadata?.name ?? "";
8320
+ const ns = e.metadata?.namespace ?? "";
8321
+ return `${ns}/${n}`;
8322
+ };
8323
+ const compareRV$1 = (a, b) => {
8324
+ if (a.length !== b.length) return a.length > b.length ? 1 : -1;
8325
+ return a > b ? 1 : a < b ? -1 : 0;
8320
8326
  };
8327
+ const getRV$1 = (item) => item?.metadata?.resourceVersion;
8321
8328
 
8322
- const useDirectUnknownResource = ({
8323
- uri,
8324
- queryKey,
8325
- refetchInterval,
8326
- isEnabled
8329
+ const reducer$1 = (state, action) => {
8330
+ switch (action.type) {
8331
+ case "RESET": {
8332
+ const order = action.items.map(eventKey$1);
8333
+ const byKey = {};
8334
+ action.items.forEach((it) => byKey[eventKey$1(it)] = it);
8335
+ return { order, byKey };
8336
+ }
8337
+ case "APPEND_PAGE": {
8338
+ const next = { ...state.byKey };
8339
+ const addKeys = [];
8340
+ action.items.forEach((it) => {
8341
+ const k = eventKey$1(it);
8342
+ if (!next[k]) addKeys.push(k);
8343
+ next[k] = it;
8344
+ });
8345
+ return { order: [...state.order, ...addKeys], byKey: next };
8346
+ }
8347
+ case "UPSERT": {
8348
+ const k = eventKey$1(action.item);
8349
+ const exists = Boolean(state.byKey[k]);
8350
+ const byKey = { ...state.byKey, [k]: action.item };
8351
+ const order = exists ? state.order : [k, ...state.order];
8352
+ return { order, byKey };
8353
+ }
8354
+ case "REMOVE": {
8355
+ if (!state.byKey[action.key]) return state;
8356
+ const byKey = { ...state.byKey };
8357
+ delete byKey[action.key];
8358
+ return { order: state.order.filter((k) => k !== action.key), byKey };
8359
+ }
8360
+ default:
8361
+ return state;
8362
+ }
8363
+ };
8364
+
8365
+ const isRecord = (v) => typeof v === "object" && v !== null;
8366
+ const readString = (obj, key) => {
8367
+ const val = obj[key];
8368
+ return typeof val === "string" ? val : void 0;
8369
+ };
8370
+ const itemRV = (it) => {
8371
+ const fromUtil = getRV$1(it);
8372
+ if (fromUtil) return fromUtil;
8373
+ if (!isRecord(it)) return void 0;
8374
+ const rvTop = readString(it, "resourceVersion");
8375
+ const mdRaw = isRecord(it["metadata"]) ? it["metadata"] : void 0;
8376
+ const rvMeta = mdRaw ? readString(mdRaw, "resourceVersion") : void 0;
8377
+ return rvTop ?? rvMeta;
8378
+ };
8379
+ const getMaxRV$1 = (items) => (items ?? []).reduce((max, it) => {
8380
+ const rv = itemRV(it);
8381
+ return rv && (!max || compareRV$1(rv, max) > 0) ? rv : max;
8382
+ }, void 0);
8383
+ const makeResId = (q) => `${q.apiGroup ?? ""}|${q.apiVersion}|${q.plural}|${q.namespace ?? ""}|${q.fieldSelector ?? ""}|${q.labelSelector ?? ""}`;
8384
+ const useListWatch = ({
8385
+ wsUrl,
8386
+ pageSize,
8387
+ paused = false,
8388
+ ignoreRemove = false,
8389
+ onStatus,
8390
+ onError,
8391
+ autoDrain = false,
8392
+ preserveStateOnUrlChange = true,
8393
+ isEnabled = true,
8394
+ // NEW default: socket gated by this flag
8395
+ query
8327
8396
  }) => {
8328
- return reactQuery.useQuery({
8329
- queryKey,
8330
- queryFn: async () => {
8331
- const response = await getDirectUnknownResource({
8332
- uri
8397
+ const resId = `${query.apiGroup ?? ""}|${query.apiVersion}|${query.plural}|${query.namespace ?? ""}|${query.fieldSelector ?? ""}|${query.labelSelector ?? ""}`;
8398
+ const resIdRef = K.useRef(resId);
8399
+ const [state, dispatch] = K.useReducer(reducer$1, { order: [], byKey: {} });
8400
+ const [contToken, setContToken] = K.useState();
8401
+ const [hasMore, setHasMore] = K.useState(false);
8402
+ const [status, setStatus] = K.useState(isEnabled ? "connecting" : "closed");
8403
+ const [lastError, setLastError] = K.useState(void 0);
8404
+ const [isPaused, setIsPaused] = K.useState(paused);
8405
+ const [isRemoveIgnored, setIsRemoveIgnored] = K.useState(ignoreRemove);
8406
+ const queryRef = K.useRef(query);
8407
+ const wsRef = K.useRef(null);
8408
+ const connectingRef = K.useRef(false);
8409
+ const mountedRef = K.useRef(true);
8410
+ const startedRef = K.useRef(false);
8411
+ const reconnectTimerRef = K.useRef(null);
8412
+ const backoffRef = K.useRef(750);
8413
+ const urlRef = K.useRef(wsUrl);
8414
+ const onMessageRef = K.useRef(() => {
8415
+ });
8416
+ const connectRef = K.useRef(() => {
8417
+ });
8418
+ const fetchingRef = K.useRef(false);
8419
+ const anchorRVRef = K.useRef(void 0);
8420
+ const haveAnchorRef = K.useRef(false);
8421
+ const enabledRef = K.useRef(isEnabled);
8422
+ const intentionalCloseRef = K.useRef(false);
8423
+ const suppressErrorsRef = K.useRef(false);
8424
+ const pausedRef = K.useRef(isPaused);
8425
+ const ignoreRemoveRef = K.useRef(isRemoveIgnored);
8426
+ K.useEffect(() => {
8427
+ pausedRef.current = isPaused;
8428
+ }, [isPaused]);
8429
+ K.useEffect(() => {
8430
+ ignoreRemoveRef.current = isRemoveIgnored;
8431
+ }, [isRemoveIgnored]);
8432
+ K.useEffect(() => {
8433
+ enabledRef.current = isEnabled;
8434
+ }, [isEnabled]);
8435
+ const clearErrorSafe = K.useCallback(() => {
8436
+ setLastError(void 0);
8437
+ }, []);
8438
+ const setStatusSafe = K.useCallback(
8439
+ (s) => {
8440
+ setStatus(s);
8441
+ onStatus?.(s);
8442
+ },
8443
+ [onStatus]
8444
+ );
8445
+ const setErrorSafe = K.useCallback(
8446
+ (msg) => {
8447
+ setLastError(msg);
8448
+ if (msg) onError?.(msg);
8449
+ },
8450
+ [onError]
8451
+ );
8452
+ const applyParam = (sp, key, v) => {
8453
+ if (v === void 0 || v === null || v === "") {
8454
+ sp.delete(key);
8455
+ return;
8456
+ }
8457
+ sp.set(key, String(v));
8458
+ };
8459
+ const buildWsUrl = K.useCallback((raw) => {
8460
+ let u;
8461
+ const base = window.location.origin;
8462
+ try {
8463
+ const hasScheme = /^[a-z]+:/i.test(raw);
8464
+ u = hasScheme ? new URL(raw) : new URL(raw.startsWith("/") ? raw : `/${raw}`, base);
8465
+ if (u.protocol === "http:") u.protocol = "ws:";
8466
+ if (u.protocol === "https:") u.protocol = "wss:";
8467
+ if (u.protocol !== "ws:" && u.protocol !== "wss:") {
8468
+ u = new URL(u.pathname + u.search + u.hash, base);
8469
+ u.protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
8470
+ }
8471
+ } catch {
8472
+ const origin = window.location.origin.replace(/^http/, "ws");
8473
+ u = new URL(raw.startsWith("/") ? raw : `/${raw}`, origin);
8474
+ }
8475
+ const q = queryRef.current;
8476
+ applyParam(u.searchParams, "namespace", q.namespace);
8477
+ applyParam(u.searchParams, "limit", q.initialLimit);
8478
+ applyParam(u.searchParams, "_continue", q.initialContinue);
8479
+ applyParam(u.searchParams, "apiGroup", q.apiGroup);
8480
+ applyParam(u.searchParams, "apiVersion", q.apiVersion);
8481
+ applyParam(u.searchParams, "plural", q.plural);
8482
+ applyParam(u.searchParams, "fieldSelector", q.fieldSelector);
8483
+ applyParam(u.searchParams, "labelSelector", q.labelSelector);
8484
+ if (haveAnchorRef.current && anchorRVRef.current) {
8485
+ u.searchParams.set("sinceRV", anchorRVRef.current);
8486
+ } else {
8487
+ u.searchParams.delete("sinceRV");
8488
+ }
8489
+ return u.toString();
8490
+ }, []);
8491
+ const closeWS = K.useCallback(() => {
8492
+ try {
8493
+ wsRef.current?.close();
8494
+ } catch {
8495
+ }
8496
+ wsRef.current = null;
8497
+ }, []);
8498
+ const scheduleReconnect = K.useCallback(() => {
8499
+ if (intentionalCloseRef.current) {
8500
+ intentionalCloseRef.current = false;
8501
+ return;
8502
+ }
8503
+ if (!enabledRef.current) {
8504
+ setStatusSafe("closed");
8505
+ connectingRef.current = false;
8506
+ return;
8507
+ }
8508
+ setStatusSafe("closed");
8509
+ connectingRef.current = false;
8510
+ const baseDelay = Math.min(backoffRef.current, 8e3);
8511
+ const jitter = Math.random() * 0.4 + 0.8;
8512
+ const wait = Math.floor(baseDelay * jitter);
8513
+ const next = Math.min(baseDelay * 2, 12e3);
8514
+ backoffRef.current = next;
8515
+ if (reconnectTimerRef.current) {
8516
+ window.clearTimeout(reconnectTimerRef.current);
8517
+ reconnectTimerRef.current = null;
8518
+ }
8519
+ reconnectTimerRef.current = window.setTimeout(() => {
8520
+ if (!mountedRef.current || !enabledRef.current) return;
8521
+ connectRef.current();
8522
+ }, wait);
8523
+ }, [setStatusSafe]);
8524
+ const connect = K.useCallback(() => {
8525
+ if (!mountedRef.current) return;
8526
+ if (!enabledRef.current) {
8527
+ setStatusSafe("closed");
8528
+ return;
8529
+ }
8530
+ if (connectingRef.current) return;
8531
+ if (wsRef.current && (wsRef.current.readyState === WebSocket.OPEN || wsRef.current.readyState === WebSocket.CONNECTING)) {
8532
+ return;
8533
+ }
8534
+ connectingRef.current = true;
8535
+ setStatusSafe("connecting");
8536
+ setErrorSafe(void 0);
8537
+ const url = buildWsUrl(urlRef.current);
8538
+ console.debug("[useListWatch] connecting to", url);
8539
+ const ws = new WebSocket(url);
8540
+ wsRef.current = ws;
8541
+ ws.addEventListener("open", () => {
8542
+ if (!mountedRef.current || !enabledRef.current) return;
8543
+ backoffRef.current = 750;
8544
+ fetchingRef.current = false;
8545
+ setStatusSafe("open");
8546
+ connectingRef.current = false;
8547
+ suppressErrorsRef.current = false;
8548
+ });
8549
+ ws.addEventListener("message", (ev) => onMessageRef.current(ev));
8550
+ ws.addEventListener("close", scheduleReconnect);
8551
+ ws.addEventListener("error", () => {
8552
+ if (intentionalCloseRef.current || suppressErrorsRef.current) return;
8553
+ setErrorSafe("WebSocket error");
8554
+ });
8555
+ }, [buildWsUrl, scheduleReconnect, setErrorSafe, setStatusSafe]);
8556
+ K.useEffect(() => {
8557
+ connectRef.current = connect;
8558
+ }, [connect]);
8559
+ const reconnect = K.useCallback(() => {
8560
+ if (!enabledRef.current) {
8561
+ closeWS();
8562
+ setStatusSafe("closed");
8563
+ return;
8564
+ }
8565
+ if (reconnectTimerRef.current) {
8566
+ window.clearTimeout(reconnectTimerRef.current);
8567
+ reconnectTimerRef.current = null;
8568
+ }
8569
+ intentionalCloseRef.current = true;
8570
+ try {
8571
+ wsRef.current?.close();
8572
+ } catch {
8573
+ }
8574
+ wsRef.current = null;
8575
+ connect();
8576
+ }, [closeWS, connect, setStatusSafe]);
8577
+ K.useEffect(() => {
8578
+ if (!mountedRef.current) return;
8579
+ if (isEnabled) {
8580
+ connect();
8581
+ } else {
8582
+ if (reconnectTimerRef.current) {
8583
+ window.clearTimeout(reconnectTimerRef.current);
8584
+ reconnectTimerRef.current = null;
8585
+ }
8586
+ closeWS();
8587
+ setStatusSafe("closed");
8588
+ }
8589
+ }, [isEnabled, closeWS, connect, setStatusSafe]);
8590
+ const setUrl = K.useCallback(
8591
+ (next) => {
8592
+ const changed = next !== urlRef.current;
8593
+ urlRef.current = next;
8594
+ if (changed) {
8595
+ clearErrorSafe();
8596
+ suppressErrorsRef.current = true;
8597
+ if (!preserveStateOnUrlChange) {
8598
+ dispatch({ type: "RESET", items: [] });
8599
+ setContToken(void 0);
8600
+ setHasMore(false);
8601
+ anchorRVRef.current = void 0;
8602
+ haveAnchorRef.current = false;
8603
+ }
8604
+ if (enabledRef.current) reconnect();
8605
+ }
8606
+ },
8607
+ [preserveStateOnUrlChange, reconnect, clearErrorSafe]
8608
+ );
8609
+ const setQuery = K.useCallback(
8610
+ (q) => {
8611
+ clearErrorSafe();
8612
+ suppressErrorsRef.current = true;
8613
+ const prev = queryRef.current;
8614
+ const prevId = makeResId(prev);
8615
+ const nextId = makeResId(q);
8616
+ queryRef.current = q;
8617
+ if (!preserveStateOnUrlChange) {
8618
+ dispatch({ type: "RESET", items: [] });
8619
+ setContToken(void 0);
8620
+ setHasMore(false);
8621
+ }
8622
+ if (prevId !== nextId) {
8623
+ anchorRVRef.current = void 0;
8624
+ haveAnchorRef.current = false;
8625
+ }
8626
+ if (enabledRef.current && prevId !== nextId) {
8627
+ reconnect();
8628
+ }
8629
+ },
8630
+ [clearErrorSafe, preserveStateOnUrlChange, reconnect]
8631
+ );
8632
+ const total = state.order.length;
8633
+ const continueToken = contToken;
8634
+ K.useEffect(() => {
8635
+ onMessageRef.current = (ev) => {
8636
+ let frame;
8637
+ try {
8638
+ frame = JSON.parse(String(ev.data));
8639
+ } catch {
8640
+ return;
8641
+ }
8642
+ if (!frame) return;
8643
+ if (frame.type === "INITIAL") {
8644
+ dispatch({ type: "RESET", items: frame.items });
8645
+ setContToken(frame.continue);
8646
+ setHasMore(Boolean(frame.continue));
8647
+ setErrorSafe(void 0);
8648
+ fetchingRef.current = false;
8649
+ suppressErrorsRef.current = false;
8650
+ const snapshotRV = frame.resourceVersion || getMaxRV$1(frame.items);
8651
+ if (snapshotRV) {
8652
+ anchorRVRef.current = snapshotRV;
8653
+ haveAnchorRef.current = true;
8654
+ }
8655
+ return;
8656
+ }
8657
+ if (frame.type === "PAGE") {
8658
+ dispatch({ type: "APPEND_PAGE", items: frame.items });
8659
+ setContToken(frame.continue);
8660
+ setHasMore(Boolean(frame.continue));
8661
+ fetchingRef.current = false;
8662
+ const batchRV = getMaxRV$1(frame.items);
8663
+ if (batchRV && (!anchorRVRef.current || compareRV$1(batchRV, anchorRVRef.current) > 0)) {
8664
+ anchorRVRef.current = batchRV;
8665
+ }
8666
+ return;
8667
+ }
8668
+ if (frame.type === "PAGE_ERROR") {
8669
+ setErrorSafe(frame.error || "Failed to load next page");
8670
+ fetchingRef.current = false;
8671
+ return;
8672
+ }
8673
+ if (frame.type === "ADDED" || frame.type === "MODIFIED" || frame.type === "DELETED") {
8674
+ const rv = itemRV(frame.item);
8675
+ if (rv && (!anchorRVRef.current || compareRV$1(rv, anchorRVRef.current) > 0)) {
8676
+ anchorRVRef.current = rv;
8677
+ }
8678
+ }
8679
+ if (!pausedRef.current) {
8680
+ if (frame.type === "ADDED" || frame.type === "MODIFIED") {
8681
+ dispatch({ type: "UPSERT", item: frame.item });
8682
+ }
8683
+ if (!ignoreRemoveRef.current && frame.type === "DELETED") {
8684
+ dispatch({ type: "REMOVE", key: eventKey$1(frame.item) });
8685
+ }
8686
+ }
8687
+ };
8688
+ }, [setErrorSafe]);
8689
+ K.useEffect(() => {
8690
+ if (startedRef.current) return void 0;
8691
+ startedRef.current = true;
8692
+ mountedRef.current = true;
8693
+ if (isEnabled) {
8694
+ connect();
8695
+ } else {
8696
+ setStatusSafe("closed");
8697
+ }
8698
+ return () => {
8699
+ mountedRef.current = false;
8700
+ startedRef.current = false;
8701
+ if (reconnectTimerRef.current) {
8702
+ window.clearTimeout(reconnectTimerRef.current);
8703
+ reconnectTimerRef.current = null;
8704
+ }
8705
+ closeWS();
8706
+ wsRef.current = null;
8707
+ connectingRef.current = false;
8708
+ };
8709
+ }, []);
8710
+ K.useEffect(() => {
8711
+ if (wsUrl !== urlRef.current) setUrl(wsUrl);
8712
+ }, [wsUrl, setUrl]);
8713
+ K.useEffect(() => {
8714
+ if (resIdRef.current !== resId) {
8715
+ clearErrorSafe();
8716
+ suppressErrorsRef.current = true;
8717
+ anchorRVRef.current = void 0;
8718
+ haveAnchorRef.current = false;
8719
+ resIdRef.current = resId;
8720
+ queryRef.current = query;
8721
+ if (enabledRef.current) reconnect();
8722
+ }
8723
+ }, [resId, query, reconnect, clearErrorSafe]);
8724
+ const pageSizeRef = K.useRef(pageSize);
8725
+ K.useEffect(() => {
8726
+ pageSizeRef.current = pageSize;
8727
+ }, [pageSize]);
8728
+ const sendScroll = K.useCallback(() => {
8729
+ if (!enabledRef.current) return;
8730
+ const token = contToken;
8731
+ if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) return;
8732
+ if (!token || fetchingRef.current) return;
8733
+ fetchingRef.current = true;
8734
+ const msg = { type: "SCROLL", continue: token, limit: pageSizeRef.current };
8735
+ wsRef.current.send(JSON.stringify(msg));
8736
+ }, [contToken]);
8737
+ const drainAll = K.useCallback(
8738
+ async (opts) => {
8739
+ if (!enabledRef.current) return 0;
8740
+ const maxPages = opts?.maxPages ?? 999;
8741
+ const maxItems = opts?.maxItems ?? Number.POSITIVE_INFINITY;
8742
+ let pages = 0;
8743
+ let added = 0;
8744
+ const awaitOnce = () => new Promise((resolve) => {
8745
+ const handler = (ev) => {
8746
+ try {
8747
+ const f = JSON.parse(String(ev.data));
8748
+ if (f.type === "PAGE") {
8749
+ const newCount = (f.items || []).reduce((acc, it) => {
8750
+ const k = eventKey$1(it);
8751
+ return state.byKey[k] ? acc : acc + 1;
8752
+ }, 0);
8753
+ added += newCount;
8754
+ const ws2 = wsRef.current;
8755
+ if (!ws2) {
8756
+ resolve("STOP");
8757
+ return;
8758
+ }
8759
+ resolve("PAGE");
8760
+ }
8761
+ } catch {
8762
+ }
8763
+ };
8764
+ const ws = wsRef.current;
8765
+ if (!ws) {
8766
+ resolve("STOP");
8767
+ return;
8768
+ }
8769
+ const stopCheck = () => {
8770
+ if (!hasMore || !contToken) {
8771
+ resolve("STOP");
8772
+ }
8773
+ };
8774
+ ws.addEventListener("message", handler, { once: true });
8775
+ setTimeout(stopCheck, 0);
8333
8776
  });
8334
- const data = JSON.parse(JSON.stringify(response.data));
8335
- if (data.metadata?.resourceVersion) {
8336
- delete data.metadata.resourceVersion;
8777
+ while (pages < maxPages && hasMore && contToken && wsRef.current?.readyState === WebSocket.OPEN) {
8778
+ if (added >= maxItems) break;
8779
+ if (!fetchingRef.current) sendScroll();
8780
+ const r = await awaitOnce();
8781
+ if (r === "STOP") break;
8782
+ pages += 1;
8337
8783
  }
8338
- return data;
8784
+ return added;
8339
8785
  },
8340
- refetchInterval: refetchInterval !== void 0 ? refetchInterval : 5e3,
8341
- enabled: isEnabled
8342
- });
8786
+ [contToken, hasMore, sendScroll, state.byKey]
8787
+ );
8788
+ K.useEffect(() => {
8789
+ if (!autoDrain) return;
8790
+ if (!enabledRef.current) return;
8791
+ if (status === "open" && haveAnchorRef.current) {
8792
+ drainAll().catch(() => {
8793
+ });
8794
+ }
8795
+ }, [autoDrain, drainAll, status]);
8796
+ return {
8797
+ state,
8798
+ total,
8799
+ hasMore,
8800
+ continueToken,
8801
+ status,
8802
+ lastError,
8803
+ setPaused: setIsPaused,
8804
+ setIgnoreRemove: setIsRemoveIgnored,
8805
+ sendScroll,
8806
+ drainAll,
8807
+ reconnect,
8808
+ setUrl,
8809
+ setQuery
8810
+ };
8811
+ };
8812
+
8813
+ const useInfiniteSentinel = (sentinelRef, hasMore, onNeedMore) => {
8814
+ K.useEffect(() => {
8815
+ const el = sentinelRef.current;
8816
+ if (!el) return void 0;
8817
+ const io = new IntersectionObserver((entries) => {
8818
+ const visible = entries.some((e) => e.isIntersecting);
8819
+ if (visible && hasMore) onNeedMore();
8820
+ });
8821
+ io.observe(el);
8822
+ return () => io.disconnect();
8823
+ }, [sentinelRef, hasMore, onNeedMore]);
8343
8824
  };
8344
8825
 
8345
8826
  const prepareTemplate = ({
@@ -8380,7 +8861,7 @@
8380
8861
  replaceValues,
8381
8862
  idToCompare
8382
8863
  }) => {
8383
- const foundData = data.find((el) => el.id === idToCompare);
8864
+ const foundData = data.find((el) => el?.id === idToCompare);
8384
8865
  if (!foundData) {
8385
8866
  return void 0;
8386
8867
  }
@@ -8479,23 +8960,37 @@
8479
8960
  return /* @__PURE__ */ jsxRuntimeExports.jsx(Styled$v.HeightDiv, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CollapsibleBreadcrumb, { items: data.breadcrumbItems }) });
8480
8961
  };
8481
8962
  const ManageableBreadcrumbsWithDataProvider = ({
8482
- uri,
8483
- refetchInterval,
8963
+ wsUrl,
8964
+ apiGroup,
8965
+ apiVersion,
8966
+ plural,
8484
8967
  isEnabled,
8485
8968
  replaceValues,
8486
8969
  pathname,
8487
8970
  idToCompare
8488
8971
  }) => {
8489
- const {
8490
- data: rawData,
8491
- isError: rawDataError,
8492
- isLoading: rawDataLoading
8493
- } = useDirectUnknownResource({
8494
- uri,
8495
- refetchInterval,
8496
- queryKey: ["breadcrumb", uri],
8972
+ const { state, status, lastError } = useListWatch({
8973
+ wsUrl,
8974
+ paused: false,
8975
+ ignoreRemove: false,
8976
+ autoDrain: true,
8977
+ preserveStateOnUrlChange: true,
8978
+ query: {
8979
+ apiVersion,
8980
+ apiGroup,
8981
+ plural
8982
+ },
8497
8983
  isEnabled
8498
8984
  });
8985
+ const rawDataLoading = status === "connecting";
8986
+ const rawDataError = status === "closed" && lastError ? lastError : void 0;
8987
+ const rawData = {
8988
+ items: state.order.map((key) => {
8989
+ const res = state.byKey[key];
8990
+ return res;
8991
+ })
8992
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
8993
+ };
8499
8994
  if (rawDataError) {
8500
8995
  return null;
8501
8996
  }
@@ -8681,8 +9176,10 @@
8681
9176
  );
8682
9177
  };
8683
9178
  const ManageableSidebarWithDataProvider = ({
8684
- uri,
8685
- refetchInterval,
9179
+ wsUrl,
9180
+ apiGroup,
9181
+ apiVersion,
9182
+ plural,
8686
9183
  isEnabled,
8687
9184
  replaceValues,
8688
9185
  pathname,
@@ -8691,16 +9188,28 @@
8691
9188
  hidden,
8692
9189
  noMarginTop
8693
9190
  }) => {
8694
- const {
8695
- data: rawData,
8696
- isError: rawDataError,
8697
- isLoading: rawDataLoading
8698
- } = useDirectUnknownResource({
8699
- uri,
8700
- refetchInterval,
8701
- queryKey: ["sidebar", uri],
9191
+ const { state, status, lastError } = useListWatch({
9192
+ wsUrl,
9193
+ paused: false,
9194
+ ignoreRemove: false,
9195
+ autoDrain: true,
9196
+ preserveStateOnUrlChange: true,
9197
+ query: {
9198
+ apiVersion,
9199
+ apiGroup,
9200
+ plural
9201
+ },
8702
9202
  isEnabled
8703
9203
  });
9204
+ const rawDataLoading = status === "connecting";
9205
+ const rawDataError = status === "closed" && lastError ? lastError : void 0;
9206
+ const rawData = {
9207
+ items: state.order.map((key) => {
9208
+ const res = state.byKey[key];
9209
+ return res;
9210
+ })
9211
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
9212
+ };
8704
9213
  if (rawDataError) {
8705
9214
  return null;
8706
9215
  }
@@ -33499,6 +34008,33 @@
33499
34008
  });
33500
34009
  };
33501
34010
 
34011
+ const getDirectUnknownResource = async ({ uri }) => {
34012
+ return axios.get(uri);
34013
+ };
34014
+
34015
+ const useDirectUnknownResource = ({
34016
+ uri,
34017
+ queryKey,
34018
+ refetchInterval,
34019
+ isEnabled
34020
+ }) => {
34021
+ return reactQuery.useQuery({
34022
+ queryKey,
34023
+ queryFn: async () => {
34024
+ const response = await getDirectUnknownResource({
34025
+ uri
34026
+ });
34027
+ const data = JSON.parse(JSON.stringify(response.data));
34028
+ if (data.metadata?.resourceVersion) {
34029
+ delete data.metadata.resourceVersion;
34030
+ }
34031
+ return data;
34032
+ },
34033
+ refetchInterval: refetchInterval !== void 0 ? refetchInterval : 5e3,
34034
+ enabled: isEnabled
34035
+ });
34036
+ };
34037
+
33502
34038
  const getBackLinkToTable = ({ fullPath }) => {
33503
34039
  return encodeURIComponent(fullPath);
33504
34040
  };
@@ -49640,22 +50176,6 @@ if (_IS_WORKLET) registerPaint("spoiler", SpoilerPainterWorklet);
49640
50176
  }
49641
50177
  return `/${baseprefix}/${clusterName}/${namespace}/forms/builtin/${apiVersion}/${typeName}?backlink=${window.location.pathname}`;
49642
50178
  };
49643
- const getListPath = ({
49644
- clusterName,
49645
- namespace,
49646
- type,
49647
- typeName,
49648
- apiGroup,
49649
- apiVersion
49650
- }) => {
49651
- if (type === "crd") {
49652
- return `/api/clusters/${clusterName}/k8s/apis/${apiGroup}/${apiVersion}${namespace ? `/namespaces/${namespace}` : ""}/${typeName}`;
49653
- }
49654
- if (type === "nonCrd") {
49655
- return `/api/clusters/${clusterName}/k8s/apis/${apiGroup}/${apiVersion}${namespace ? `/namespaces/${namespace}` : ""}/${typeName}`;
49656
- }
49657
- return `/api/clusters/${clusterName}/k8s/api/v1${namespace ? `/namespaces/${namespace}` : ""}/${typeName}`;
49658
- };
49659
50179
 
49660
50180
  const CustomCard$4 = styled(antd.Card)`
49661
50181
  position: relative;
@@ -49788,20 +50308,28 @@ if (_IS_WORKLET) registerPaint("spoiler", SpoilerPainterWorklet);
49788
50308
  apiVersion,
49789
50309
  baseprefix
49790
50310
  });
49791
- const listUrl = addedMode && type !== "direct" ? getListPath({
49792
- clusterName,
49793
- namespace,
49794
- type,
49795
- typeName,
49796
- apiGroup,
49797
- apiVersion
49798
- }) : void 0;
49799
- const { data: k8sList, error: k8sListError } = useDirectUnknownResource({
49800
- uri: listUrl || "",
49801
- queryKey: [listUrl || ""],
49802
- refetchInterval: false,
49803
- isEnabled: addedMode && listUrl !== void 0
50311
+ const { state, status, lastError } = useListWatch({
50312
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50313
+ paused: false,
50314
+ ignoreRemove: false,
50315
+ autoDrain: true,
50316
+ preserveStateOnUrlChange: true,
50317
+ query: {
50318
+ namespace,
50319
+ apiVersion: apiVersion || "",
50320
+ apiGroup,
50321
+ plural: type
50322
+ },
50323
+ isEnabled: Boolean(apiVersion && addedMode && type !== "direct")
49804
50324
  });
50325
+ const k8sListError = status === "closed" && lastError ? lastError : void 0;
50326
+ const k8sList = {
50327
+ items: state.order.map((key) => {
50328
+ const res = state.byKey[key];
50329
+ return res;
50330
+ })
50331
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50332
+ };
49805
50333
  if (addedMode && (k8sListError || type === "direct") && !showZeroResources) {
49806
50334
  return null;
49807
50335
  }
@@ -49930,16 +50458,30 @@ if (_IS_WORKLET) registerPaint("spoiler", SpoilerPainterWorklet);
49930
50458
  const [filteredAndSortedData, setFilterAndSortedData] = K.useState([]);
49931
50459
  const [uniqueTags, setUniqueTags] = K.useState([]);
49932
50460
  const [selectedTags, setSelectedTags] = K.useState([]);
49933
- const {
49934
- data: marketplacePanels,
49935
- isLoading,
49936
- error
49937
- } = useDirectUnknownResource({
49938
- uri: `/api/clusters/${clusterName}/k8s/apis/${baseApiGroup}/${baseApiVersion}/${mpResourceName}/`,
49939
- refetchInterval: 5e3,
49940
- queryKey: ["marketplacePanels", clusterName || "no-cluster"],
50461
+ const { state, status, lastError } = useListWatch({
50462
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50463
+ paused: false,
50464
+ ignoreRemove: false,
50465
+ autoDrain: true,
50466
+ preserveStateOnUrlChange: true,
50467
+ query: {
50468
+ apiVersion: baseApiVersion,
50469
+ apiGroup: baseApiGroup,
50470
+ plural: mpResourceName
50471
+ },
49941
50472
  isEnabled: clusterName !== void 0
49942
50473
  });
50474
+ const isLoading = status === "connecting";
50475
+ const error = status === "closed" && lastError ? lastError : void 0;
50476
+ const marketplacePanels = K.useMemo(() => {
50477
+ return {
50478
+ items: state.order.map((key) => {
50479
+ const res = state.byKey[key];
50480
+ return res;
50481
+ })
50482
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50483
+ };
50484
+ }, [state]);
49943
50485
  const createPermission = usePermissions({
49944
50486
  group: baseApiGroup,
49945
50487
  resource: mpResourceName,
@@ -50238,26 +50780,52 @@ if (_IS_WORKLET) registerPaint("spoiler", SpoilerPainterWorklet);
50238
50780
  children
50239
50781
  }) => {
50240
50782
  const navigate = reactRouterDom.useNavigate();
50241
- const {
50242
- data: marketplacePanels,
50243
- isLoading: marketplaceIsLoading
50244
- // error: marketplaceError,
50245
- } = useDirectUnknownResource({
50246
- uri: `/api/clusters/${clusterName}/k8s/apis/${baseApiGroup}/${baseApiVersion}/${mpResourceName}/`,
50247
- refetchInterval: 5e3,
50248
- queryKey: ["marketplacePanels", clusterName || "no-cluster"],
50783
+ const { state, status } = useListWatch({
50784
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50785
+ paused: false,
50786
+ ignoreRemove: false,
50787
+ autoDrain: true,
50788
+ preserveStateOnUrlChange: true,
50789
+ query: {
50790
+ apiVersion: baseApiVersion,
50791
+ apiGroup: baseApiGroup,
50792
+ plural: mpResourceName
50793
+ },
50249
50794
  isEnabled: clusterName !== void 0
50250
50795
  });
50796
+ const marketplaceIsLoading = status === "connecting";
50797
+ const marketplacePanels = {
50798
+ items: state.order.map((key) => {
50799
+ const res = state.byKey[key];
50800
+ return res;
50801
+ })
50802
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50803
+ };
50251
50804
  const {
50252
- data: project,
50253
- isLoading,
50254
- error
50255
- } = useDirectUnknownResource({
50256
- uri: `/api/clusters/${clusterName}/k8s/apis/${baseProjectApiGroup}/${baseProjectVersion}/${projectResourceName}/${namespace}`,
50257
- refetchInterval: 5e3,
50258
- queryKey: ["projects", clusterName || "no-cluster"],
50805
+ state: stateProject,
50806
+ status: statusProject,
50807
+ lastError: lastErrorProject
50808
+ } = useListWatch({
50809
+ wsUrl: `/api/clusters/${clusterName}/openapi-bff-ws/listThenWatch/listWatchWs`,
50810
+ paused: false,
50811
+ ignoreRemove: false,
50812
+ autoDrain: true,
50813
+ preserveStateOnUrlChange: true,
50814
+ query: {
50815
+ apiVersion: baseProjectVersion,
50816
+ apiGroup: baseProjectApiGroup,
50817
+ plural: projectResourceName,
50818
+ fieldSelector: `metadata.name=${namespace}`
50819
+ },
50259
50820
  isEnabled: clusterName !== void 0
50260
50821
  });
50822
+ const isLoading = statusProject === "connecting";
50823
+ const error = statusProject === "closed" && lastErrorProject ? lastErrorProject : void 0;
50824
+ const projectArr = stateProject.order.map((key) => {
50825
+ const res = stateProject.byKey[key];
50826
+ return res;
50827
+ });
50828
+ const project = projectArr.length > 0 ? projectArr[0] : void 0;
50261
50829
  const [isDeleteModalOpen, setIsDeleteModalOpen] = K.useState(false);
50262
50830
  const updatePermission = usePermissions({
50263
50831
  group: baseProjectApiGroup,
@@ -53016,6 +53584,8 @@ if (_IS_WORKLET) registerPaint("spoiler", SpoilerPainterWorklet);
53016
53584
  exports.useCrdResourceSingle = useCrdResourceSingle;
53017
53585
  exports.useCrdResources = useCrdResources;
53018
53586
  exports.useDirectUnknownResource = useDirectUnknownResource;
53587
+ exports.useInfiniteSentinel = useInfiniteSentinel;
53588
+ exports.useListWatch = useListWatch;
53019
53589
  exports.usePermissions = usePermissions;
53020
53590
 
53021
53591
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });