@64mb/freelens-power 1.6.1 → 2.1.0

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.
Files changed (85) hide show
  1. package/README.md +1 -1
  2. package/out/main/common/power-logs.js.map +1 -1
  3. package/out/main/common/resource-search-kind-priority.js +23 -0
  4. package/out/main/common/resource-search-kind-priority.js.map +1 -0
  5. package/out/main/common/store/logs-preferences-store.js +5 -0
  6. package/out/main/common/store/logs-preferences-store.js.map +1 -1
  7. package/out/main/dashboard-views.js +26 -0
  8. package/out/main/dashboard-views.js.map +1 -1
  9. package/out/main/power-logs-database.js +5 -0
  10. package/out/main/power-logs-database.js.map +1 -1
  11. package/out/main/power-logs-ipc.js +8 -0
  12. package/out/main/power-logs-ipc.js.map +1 -1
  13. package/out/main/power-logs-query.js +1 -0
  14. package/out/main/power-logs-query.js.map +1 -1
  15. package/out/main/resource-search-database.js +7 -2
  16. package/out/main/resource-search-database.js.map +1 -1
  17. package/out/main/resource-search-worker.js +6 -2
  18. package/out/main/resource-search-worker.js.map +1 -1
  19. package/out/renderer/_virtual/_global-external_react.js +2 -1
  20. package/out/renderer/ai-diagnostic-handoff.js +1 -0
  21. package/out/renderer/ai-diagnostic-handoff.js.map +1 -1
  22. package/out/renderer/ai-extras.js +7 -2
  23. package/out/renderer/ai-extras.js.map +1 -1
  24. package/out/renderer/ai.js +1 -1
  25. package/out/renderer/ai.js.map +1 -1
  26. package/out/renderer/appearance.js +2 -0
  27. package/out/renderer/appearance.js.map +1 -1
  28. package/out/renderer/dashboard.js +35 -8
  29. package/out/renderer/dashboard.js.map +1 -1
  30. package/out/renderer/index.js +2 -1
  31. package/out/renderer/index.js.map +1 -1
  32. package/out/renderer/power-log-json-cell.js +82 -0
  33. package/out/renderer/power-log-json-cell.js.map +1 -0
  34. package/out/renderer/power-log-json-fields.js +144 -0
  35. package/out/renderer/power-log-json-fields.js.map +1 -0
  36. package/out/renderer/power-log-json.js +223 -20
  37. package/out/renderer/power-log-json.js.map +1 -1
  38. package/out/renderer/power-log-message-tokens.js +60 -0
  39. package/out/renderer/power-log-message-tokens.js.map +1 -0
  40. package/out/renderer/power-log-message.js +26 -0
  41. package/out/renderer/power-log-message.js.map +1 -0
  42. package/out/renderer/power-log-sql-editor.js +91 -0
  43. package/out/renderer/power-log-sql-editor.js.map +1 -0
  44. package/out/renderer/power-logs-client.js +4 -0
  45. package/out/renderer/power-logs-client.js.map +1 -1
  46. package/out/renderer/power-logs-sql-drafts.js +76 -0
  47. package/out/renderer/power-logs-sql-drafts.js.map +1 -0
  48. package/out/renderer/power-logs-sql-row.js +5 -13
  49. package/out/renderer/power-logs-sql-row.js.map +1 -1
  50. package/out/renderer/power-logs.css.js +39 -6
  51. package/out/renderer/power-logs.css.js.map +1 -1
  52. package/out/renderer/power-logs.js +372 -135
  53. package/out/renderer/power-logs.js.map +1 -1
  54. package/out/renderer/preferences/logs-preferences.js +159 -38
  55. package/out/renderer/preferences/logs-preferences.js.map +1 -1
  56. package/out/renderer/preferences/preferences.js +2 -9
  57. package/out/renderer/preferences/preferences.js.map +1 -1
  58. package/out/renderer/preferences/section-navigation.js +44 -0
  59. package/out/renderer/preferences/section-navigation.js.map +1 -0
  60. package/out/renderer/resource-search-model.js +2 -1
  61. package/out/renderer/resource-search-model.js.map +1 -1
  62. package/out/renderer/resource-search-sync.js +1 -1
  63. package/out/renderer/resource-search-sync.js.map +1 -1
  64. package/out/renderer/resource-search.js +84 -81
  65. package/out/renderer/resource-search.js.map +1 -1
  66. package/out/renderer/src/common/power-log-field-filters.js +92 -0
  67. package/out/renderer/src/common/power-log-field-filters.js.map +1 -0
  68. package/out/renderer/src/common/power-log-json-filter-sql.js +106 -0
  69. package/out/renderer/src/common/power-log-json-filter-sql.js.map +1 -0
  70. package/out/renderer/src/common/power-log-json-preset.js +34 -0
  71. package/out/renderer/src/common/power-log-json-preset.js.map +1 -0
  72. package/out/renderer/src/common/power-log-level.js +171 -0
  73. package/out/renderer/src/common/power-log-level.js.map +1 -0
  74. package/out/renderer/src/common/power-log-parser.js +7 -29
  75. package/out/renderer/src/common/power-log-parser.js.map +1 -1
  76. package/out/renderer/src/common/power-log-sql-level.js +25 -0
  77. package/out/renderer/src/common/power-log-sql-level.js.map +1 -0
  78. package/out/renderer/src/common/power-logs-ai.js +4 -0
  79. package/out/renderer/src/common/power-logs-ai.js.map +1 -1
  80. package/out/renderer/src/common/power-logs.js.map +1 -1
  81. package/out/renderer/src/common/resource-search-kind-priority.js +28 -0
  82. package/out/renderer/src/common/resource-search-kind-priority.js.map +1 -0
  83. package/out/renderer/src/common/store/logs-preferences-store.js +5 -0
  84. package/out/renderer/src/common/store/logs-preferences-store.js.map +1 -1
  85. package/package.json +1 -1
@@ -8,8 +8,10 @@ const require_jsx_runtime = require("./_virtual/_global-external_react/jsx-runti
8
8
  const require_ai_icon = require("./ai-icon.js");
9
9
  const require_ai_diagnostic_handoff = require("./ai-diagnostic-handoff.js");
10
10
  const require_diagnostic_explain_button = require("./diagnostic-explain-button.js");
11
+ const require_react_select_esm = require("./node_modules/.pnpm/react-select@5.10.2_@types_react@17.0.93_react-dom@17.0.2_react@17.0.2__react@17.0.2/node_modules/react-select/dist/react-select.esm.js");
11
12
  const require_resource_search_client = require("./resource-search-client.js");
12
13
  const require_resource_search_routing = require("./resource-search-routing.js");
14
+ const require_resource_search_kind_priority = require("./src/common/resource-search-kind-priority.js");
13
15
  const require_resource_search_fields = require("./resource-search-fields.js");
14
16
  const require_resource_search_model = require("./resource-search-model.js");
15
17
  const require_resource_search_sync = require("./resource-search-sync.js");
@@ -79,6 +81,18 @@ var inventory = () => [
79
81
  ]
80
82
  ];
81
83
  var icons = new Map(inventory().map(([kind, , icon]) => [kind, icon]));
84
+ function SearchFilterSelect({ value, options, ...props }) {
85
+ return /* @__PURE__ */ require_jsx_runtime.jsx(require_react_select_esm.default, {
86
+ ...props,
87
+ className: `Select theme-${require_extensions.Renderer.Theme?.activeTheme?.get()?.type ?? "dark"}`,
88
+ classNamePrefix: "Select",
89
+ value: options.find((option) => option.value === value) ?? null,
90
+ options,
91
+ isClearable: false,
92
+ tabSelectsValue: false,
93
+ menuPlacement: "auto"
94
+ });
95
+ }
82
96
  require__global_external_mobx_react.observer(() => {
83
97
  if (!require_monitoring_preferences_store.MonitoringPreferencesStore.getInstanceOrCreate().resourceSearchEnabled) return null;
84
98
  return /* @__PURE__ */ require_jsx_runtime.jsx("button", {
@@ -109,7 +123,6 @@ function SearchSnippet({ field, query }) {
109
123
  }
110
124
  function SearchDialog({ close, clusterId }) {
111
125
  const [query, setQuery] = require__global_external_react.useState("");
112
- const [knownNamespace, setKnownNamespace] = require__global_external_react.useState("");
113
126
  const [kindFilter, setKindFilter] = require__global_external_react.useState("");
114
127
  const [namespaceFilter, setNamespaceFilter] = require__global_external_react.useState("");
115
128
  const [resources, setResources] = require__global_external_react.useState([]);
@@ -120,6 +133,8 @@ function SearchDialog({ close, clusterId }) {
120
133
  const [error, setError] = require__global_external_react.useState("");
121
134
  const dialog = require__global_external_react.useRef(null);
122
135
  const input = require__global_external_react.useRef(null);
136
+ const openFilterMenus = require__global_external_react.useRef(/* @__PURE__ */ new Set());
137
+ const escapeFromOpenMenu = require__global_external_react.useRef(false);
123
138
  const searchIndex = require__global_external_react.useMemo(() => require_resource_search_model.createResourceSearchIndex(resources), [resources]);
124
139
  const matches = searchIndex.search(query);
125
140
  const selectedResource = matches.find((resource) => resource.path === selectedPath) ?? matches[0];
@@ -207,8 +222,11 @@ function SearchDialog({ close, clusterId }) {
207
222
  "aria-modal": "true",
208
223
  "aria-labelledby": "power-resource-search-title",
209
224
  className: "power-resource-search-dialog",
225
+ onKeyDownCapture: (event) => {
226
+ if (event.key === "Escape") escapeFromOpenMenu.current = openFilterMenus.current.size > 0;
227
+ },
210
228
  onKeyDown: (event) => {
211
- if (event.key === "Escape") {
229
+ if (event.key === "Escape" && !escapeFromOpenMenu.current) {
212
230
  event.stopPropagation();
213
231
  close();
214
232
  }
@@ -281,44 +299,53 @@ function SearchDialog({ close, clusterId }) {
281
299
  }),
282
300
  /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
283
301
  className: "power-resource-search-filters",
284
- style: {
285
- display: "flex",
286
- gap: 8,
287
- flexWrap: "wrap"
288
- },
289
- children: [/* @__PURE__ */ require_jsx_runtime.jsx("input", {
290
- list: "power-search-kinds",
291
- "aria-label": "Filter by exact resource kind",
292
- placeholder: "Kind (all types)",
293
- value: kindFilter,
294
- maxLength: 253,
295
- onChange: (event) => {
296
- setKindFilter(event.target.value);
297
- setSelectedPath(void 0);
298
- }
299
- }), /* @__PURE__ */ require_jsx_runtime.jsx("input", {
300
- list: "power-search-namespaces",
301
- "aria-label": "Filter by exact namespace",
302
- placeholder: "Namespace (all)",
303
- value: namespaceFilter,
304
- maxLength: 253,
305
- onChange: (event) => {
306
- setNamespaceFilter(event.target.value);
307
- setSelectedPath(void 0);
308
- }
302
+ children: [/* @__PURE__ */ require_jsx_runtime.jsxs("label", {
303
+ className: "power-resource-search-filter",
304
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "Kind" }), /* @__PURE__ */ require_jsx_runtime.jsx(SearchFilterSelect, {
305
+ "aria-label": "Kind",
306
+ onMenuOpen: () => openFilterMenus.current.add("kind"),
307
+ onMenuClose: () => openFilterMenus.current.delete("kind"),
308
+ value: kindFilter,
309
+ options: [{
310
+ value: "",
311
+ label: "All types"
312
+ }, ...[...coverage.kinds ?? []].sort((first, second) => require_resource_search_kind_priority.resourceKindPriority(first) - require_resource_search_kind_priority.resourceKindPriority(second) || first.localeCompare(second, "en")).map((kind) => ({
313
+ value: kind,
314
+ label: kind
315
+ }))],
316
+ onChange: (option) => {
317
+ setKindFilter(option?.value ?? "");
318
+ setSelectedPath(void 0);
319
+ }
320
+ })]
321
+ }), /* @__PURE__ */ require_jsx_runtime.jsxs("label", {
322
+ className: "power-resource-search-filter",
323
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("span", { children: "Namespace" }), /* @__PURE__ */ require_jsx_runtime.jsx(SearchFilterSelect, {
324
+ "aria-label": "Namespace",
325
+ onMenuOpen: () => openFilterMenus.current.add("namespace"),
326
+ onMenuClose: () => openFilterMenus.current.delete("namespace"),
327
+ value: namespaceFilter,
328
+ options: [
329
+ {
330
+ value: "",
331
+ label: "All namespaces"
332
+ },
333
+ {
334
+ value: "(cluster)",
335
+ label: "Cluster scoped"
336
+ },
337
+ ...(coverage.namespaces ?? []).map((namespace) => ({
338
+ value: namespace,
339
+ label: namespace
340
+ }))
341
+ ],
342
+ onChange: (option) => {
343
+ setNamespaceFilter(option?.value ?? "");
344
+ setSelectedPath(void 0);
345
+ }
346
+ })]
309
347
  })]
310
348
  }),
311
- /* @__PURE__ */ require_jsx_runtime.jsx("datalist", {
312
- id: "power-search-kinds",
313
- children: (coverage.kinds ?? []).map((kind) => /* @__PURE__ */ require_jsx_runtime.jsx("option", { value: kind }, kind))
314
- }),
315
- /* @__PURE__ */ require_jsx_runtime.jsxs("datalist", {
316
- id: "power-search-namespaces",
317
- children: [/* @__PURE__ */ require_jsx_runtime.jsx("option", {
318
- value: "(cluster)",
319
- children: "Cluster scoped"
320
- }), (coverage.namespaces ?? []).map((namespace) => /* @__PURE__ */ require_jsx_runtime.jsx("option", { value: namespace }, namespace))]
321
- }),
322
349
  /* @__PURE__ */ require_jsx_runtime.jsxs("p", {
323
350
  role: "status",
324
351
  children: [
@@ -333,13 +360,9 @@ function SearchDialog({ close, clusterId }) {
333
360
  ]
334
361
  }),
335
362
  (coverage.message || coverage.denied > 0 || coverage.unavailable + coverage.unsupported > 0) && /* @__PURE__ */ require_jsx_runtime.jsxs("details", { children: [/* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "Inventory coverage" }), /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: coverage.message ?? "Results include the resources your current permissions and available APIs allow." })] }),
336
- coverage.storageFull && /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
363
+ coverage.storageFull && /* @__PURE__ */ require_jsx_runtime.jsx("div", {
337
364
  role: "alert",
338
- children: [/* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Local search storage is full. Cached results are partial; indexing is paused." }), /* @__PURE__ */ require_jsx_runtime.jsx("button", {
339
- type: "button",
340
- onClick: clearCache,
341
- children: "Clear local search cache"
342
- })]
365
+ children: /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Local search storage is full. Cached results are partial; indexing is paused." })
343
366
  }),
344
367
  error && /* @__PURE__ */ require_jsx_runtime.jsx("p", {
345
368
  role: "alert",
@@ -400,40 +423,23 @@ function SearchDialog({ close, clusterId }) {
400
423
  onClick: () => setLimit((value) => Math.min(1e3, value + 100)),
401
424
  children: "Show more matches"
402
425
  }),
403
- /* @__PURE__ */ require_jsx_runtime.jsxs("details", { children: [
404
- /* @__PURE__ */ require_jsx_runtime.jsx("summary", { children: "Search options" }),
405
- /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
406
- style: {
407
- display: "flex",
408
- gap: 8,
409
- flexWrap: "wrap"
410
- },
411
- children: [/* @__PURE__ */ require_jsx_runtime.jsx("input", {
412
- "aria-label": "Known namespace for restricted access",
413
- placeholder: "Known namespace",
414
- value: knownNamespace,
415
- maxLength: 63,
416
- onChange: (event) => setKnownNamespace(event.target.value)
417
- }), /* @__PURE__ */ require_jsx_runtime.jsx("button", {
418
- type: "button",
419
- disabled: !/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(knownNamespace),
420
- onClick: () => {
421
- extraNamespaces.add(knownNamespace);
422
- restartSearchSync();
423
- },
424
- children: "Index namespace"
425
- })]
426
- }),
427
- hasMore && limit >= 1e3 && /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Showing up to 1000 candidates. Refine the name, type or namespace to continue." }),
428
- !coverage.storageFull && /* @__PURE__ */ require_jsx_runtime.jsx("button", {
426
+ hasMore && limit >= 1e3 && /* @__PURE__ */ require_jsx_runtime.jsx("p", { children: "Showing up to 1000 candidates. Refine the name, type or namespace to continue." }),
427
+ /* @__PURE__ */ require_jsx_runtime.jsxs("div", {
428
+ className: "power-resource-search-footer",
429
+ children: [/* @__PURE__ */ require_jsx_runtime.jsx("p", {
430
+ className: "power-resource-search-shortcuts",
431
+ children: "↑↓ Navigate · Enter Open · Esc Close"
432
+ }), /* @__PURE__ */ require_jsx_runtime.jsx("button", {
429
433
  type: "button",
434
+ className: "power-resource-search-clear",
435
+ title: "Clear local search cache",
436
+ "aria-label": "Clear local search cache",
430
437
  onClick: clearCache,
431
- children: "Clear local search cache"
432
- })
433
- ] }),
434
- /* @__PURE__ */ require_jsx_runtime.jsx("p", {
435
- className: "power-resource-search-shortcuts",
436
- children: "↑↓ Navigate · Enter Open · Esc Close"
438
+ children: /* @__PURE__ */ require_jsx_runtime.jsx(require_ai_icon.AiIcon, {
439
+ material: "delete_sweep",
440
+ size: 16
441
+ })
442
+ })]
437
443
  })
438
444
  ]
439
445
  })
@@ -448,7 +454,6 @@ var currentCoverage = {
448
454
  indexing: true
449
455
  };
450
456
  var restartSearchSync = () => {};
451
- var extraNamespaces = /* @__PURE__ */ new Set();
452
457
  function startResourceSearch() {
453
458
  const preferences = require_monitoring_preferences_store.MonitoringPreferencesStore.getInstanceOrCreate();
454
459
  let stop = preferences.resourceSearchEnabled ? startEnabledResourceSearch() : void 0;
@@ -506,7 +511,7 @@ function startEnabledResourceSearch() {
506
511
  transport: require_resource_search_client.createResourceSearchTransport(clusterId, controller.signal),
507
512
  sink,
508
513
  signal: controller.signal,
509
- namespaces: () => [.../* @__PURE__ */ new Set([...require_extensions.Renderer.Catalog.activeCluster.get()?.spec?.accessibleNamespaces ?? [], ...extraNamespaces])],
514
+ namespaces: () => require_extensions.Renderer.Catalog.activeCluster.get()?.spec?.accessibleNamespaces ?? [],
510
515
  onStatus: (status) => {
511
516
  if (!controller.signal.aborted) {
512
517
  if (status.indexing && !wasIndexing) liveObjects.clear();
@@ -530,7 +535,7 @@ function startEnabledResourceSearch() {
530
535
  sync();
531
536
  const container = document.createElement("div");
532
537
  const style = document.createElement("style");
533
- style.textContent = `.power-resource-search-backdrop{position:fixed;inset:0;z-index:10000;background:#0007;display:flex;align-items:flex-start;justify-content:center;padding:8vh 20px}.power-resource-search-dialog{width:680px;max-width:100%;max-height:75vh;display:flex;flex-direction:column;padding:20px;gap:12px;background:var(--mainBackground,#222);color:var(--textColorPrimary,#eee);border:1px solid var(--borderColor,#555);border-radius:8px;box-shadow:0 16px 60px #0008}.power-resource-search-heading{display:flex;align-items:center;justify-content:space-between}.power-resource-search-filters input{flex:1;min-width:180px}.power-resource-search-dialog input{padding:12px;font-size:16px;background:var(--inputControlBackground,#333);color:inherit;border:1px solid var(--borderColor,#666);border-radius:4px}.power-resource-search-dialog p{margin:0;font-size:12px;color:var(--textColorSecondary,#bbb)}.power-resource-search-results{overflow:auto;min-height:180px;flex:1}.power-resource-search-row{display:flex;align-items:center;gap:12px;padding:4px;border-radius:4px}.power-resource-search-row{border-left:3px solid transparent}.power-resource-search-row.selected{background:color-mix(in srgb,var(--primary,#668fff) 16%,var(--mainBackground,#222));color:var(--tableSelectedRowColor,var(--textColorPrimary,#eee));border-left-color:var(--primary,#668fff)}.power-resource-search-row.selected .Icon{color:var(--primary,#8daaff)}.power-resource-search-row:hover{background:var(--tableBgcSelected,var(--contentColor,#292d32))}.power-resource-search-dialog button:hover:not(:disabled){background:#ffffff12;border-radius:4px}.power-resource-search-row>button:last-child{border:1px solid var(--borderColor,#555);border-radius:4px}.power-resource-search-shortcuts{padding-top:8px;border-top:1px solid var(--borderColor,#555)}.power-resource-search-dialog button{min-width:32px;min-height:32px;padding:6px;color:inherit;background:transparent;border:0;cursor:pointer}.power-resource-search-dialog button:disabled{opacity:.45;cursor:default}.power-resource-search-open{display:flex;align-items:center;gap:12px;flex:1;text-align:left;min-width:0}.power-resource-search-open span{min-width:0}.power-resource-search-open strong,.power-resource-search-open small{display:block;overflow-wrap:anywhere}.power-resource-search-open small{opacity:.7}.power-resource-search-row>button.power-resource-search-ai{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;min-width:34px;padding:0;background:var(--contentColor,#292d32);border:1px solid var(--borderColor,#666)}.power-resource-search-row.selected>button.power-resource-search-ai{background:var(--mainBackground,#202326);border-color:color-mix(in srgb,var(--textColorPrimary,#ddd) 55%,var(--borderColor,#666));box-shadow:0 1px 3px #0002}.power-resource-search-row.selected>button.power-resource-search-ai .Icon{color:var(--textColorAccent,#eee)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled){background:var(--contentColor,#30343a);border-color:var(--primary,#8daaff);color:var(--primary,#8daaff)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled) .Icon{color:inherit}.power-resource-search-dialog button:focus-visible{outline:2px solid var(--primary,#668fff)}`;
538
+ style.textContent = `.power-resource-search-backdrop{position:fixed;inset:0;z-index:10000;background:#0007;display:flex;align-items:flex-start;justify-content:center;padding:8vh 20px}.power-resource-search-dialog{width:680px;max-width:100%;max-height:75vh;display:flex;flex-direction:column;padding:20px;gap:12px;background:var(--mainBackground,#222);color:var(--textColorPrimary,#eee);border:1px solid var(--borderColor,#555);border-radius:8px;box-shadow:0 16px 60px #0008}.power-resource-search-heading{display:flex;align-items:center;justify-content:space-between}.power-resource-search-filters{display:flex;align-items:end;gap:8px;flex-wrap:wrap}.power-resource-search-filter{display:flex;flex-direction:column;gap:4px;flex:1;min-width:180px;font-size:12px;color:var(--textColorSecondary)}.power-resource-search-filter .Select{width:100%;min-width:0}.power-resource-search-filter .Select__control{min-height:30px;height:30px;font-size:12px}.power-resource-search-filter .Select__value-container{padding:0 8px;min-width:0}.power-resource-search-filter .Select__input-container{margin:0;padding:0}.power-resource-search-filter .Select__indicator{padding:4px 8px}.power-resource-search-filter .Select__single-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.power-resource-search-dialog > input,.power-resource-search-dialog details input{padding:12px;font-size:16px;background:var(--inputControlBackground,#333);color:inherit;border:1px solid var(--borderColor,#666);border-radius:4px}.power-resource-search-dialog p{margin:0;font-size:12px;color:var(--textColorSecondary,#bbb)}.power-resource-search-results{overflow:auto;min-height:180px;flex:1}.power-resource-search-row{display:flex;align-items:center;gap:12px;padding:4px;border-radius:4px}.power-resource-search-row{border-left:3px solid transparent}.power-resource-search-row.selected{background:color-mix(in srgb,var(--primary,#668fff) 16%,var(--mainBackground,#222));color:var(--tableSelectedRowColor,var(--textColorPrimary,#eee));border-left-color:var(--primary,#668fff)}.power-resource-search-row.selected .Icon{color:var(--primary,#8daaff)}.power-resource-search-row:hover{background:var(--tableBgcSelected,var(--contentColor,#292d32))}.power-resource-search-dialog button:hover:not(:disabled){background:#ffffff12;border-radius:4px}.power-resource-search-row>button:last-child{border:1px solid var(--borderColor,#555);border-radius:4px}.power-resource-search-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding-top:8px;border-top:1px solid var(--borderColor,#555)}.power-resource-search-shortcuts{flex:1}.power-resource-search-footer .power-resource-search-clear{display:inline-flex;align-items:center;justify-content:center;min-width:28px;min-height:28px;width:28px;height:28px;padding:0}.power-resource-search-dialog button{min-width:32px;min-height:32px;padding:6px;color:inherit;background:transparent;border:0;cursor:pointer}.power-resource-search-dialog button:disabled{opacity:.45;cursor:default}.power-resource-search-open{display:flex;align-items:center;gap:12px;flex:1;text-align:left;min-width:0}.power-resource-search-open span{min-width:0}.power-resource-search-open strong,.power-resource-search-open small{display:block;overflow-wrap:anywhere}.power-resource-search-open small{opacity:.7}.power-resource-search-row>button.power-resource-search-ai{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;min-width:34px;padding:0;background:var(--contentColor,#292d32);border:1px solid var(--borderColor,#666)}.power-resource-search-row.selected>button.power-resource-search-ai{background:var(--mainBackground,#202326);border-color:color-mix(in srgb,var(--textColorPrimary,#ddd) 55%,var(--borderColor,#666));box-shadow:0 1px 3px #0002}.power-resource-search-row.selected>button.power-resource-search-ai .Icon{color:var(--textColorAccent,#eee)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled){background:var(--contentColor,#30343a);border-color:var(--primary,#8daaff);color:var(--primary,#8daaff)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled) .Icon{color:inherit}.power-resource-search-dialog button:focus-visible{outline:2px solid var(--primary,#668fff)}`;
534
539
  document.head.append(style);
535
540
  document.body.append(container);
536
541
  let visible = false;
@@ -566,7 +571,6 @@ function startEnabledResourceSearch() {
566
571
  window.addEventListener(OPEN, show);
567
572
  const dispose = require__global_external_mobx.reaction(() => `${require_resource_search_client.searchContextId()}/${require_extensions.Renderer.Catalog.activeCluster.get()?.status?.phase}`, () => {
568
573
  close();
569
- extraNamespaces.clear();
570
574
  sync();
571
575
  });
572
576
  return () => {
@@ -574,7 +578,6 @@ function startEnabledResourceSearch() {
574
578
  syncAbort?.abort();
575
579
  require_resource_search_routing.closeSearchResourceFallback();
576
580
  restartSearchSync = () => {};
577
- extraNamespaces.clear();
578
581
  dispose();
579
582
  window.removeEventListener("blur", resetShift);
580
583
  window.removeEventListener("keydown", key);
@@ -1 +1 @@
1
- {"version":3,"file":"resource-search.js","names":[],"sources":["../../src/renderer/resource-search.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { reaction } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport { MonitoringPreferencesStore } from \"../common/store/monitoring-preferences-store\";\nimport { explainDiagnosticFinding } from \"./ai-diagnostic-handoff\";\nimport { AiIcon } from \"./ai-icon\";\nimport { DiagnosticExplainButton } from \"./diagnostic-explain-button\";\nimport { createResourceSearchClient, createResourceSearchTransport, searchContextId } from \"./resource-search-client\";\nimport { projectSearchFields } from \"./resource-search-fields\";\nimport {\n createDoubleShift,\n createResourceSearchIndex,\n queryTokens,\n type SearchResource,\n} from \"./resource-search-model\";\nimport { closeSearchResourceFallback, openSearchResource } from \"./resource-search-routing\";\nimport { createSearchSynchronizer, type SearchCoverage } from \"./resource-search-sync\";\n\nimport type { SearchDocument } from \"../common/resource-search\";\n\nconst OPEN = \"power-resource-search\";\nconst activeId = () => Renderer.Catalog.activeCluster.get()?.metadata.uid;\nconst inventory = () =>\n [\n [\"Pod\", Renderer.K8sApi.podsStore, \"view_in_ar\"],\n [\"Node\", Renderer.K8sApi.nodesStore, \"dns\"],\n [\"Deployment\", Renderer.K8sApi.deploymentStore, \"layers\"],\n [\"StatefulSet\", Renderer.K8sApi.statefulSetStore, \"layers\"],\n [\"DaemonSet\", Renderer.K8sApi.daemonSetStore, \"layers\"],\n [\"ReplicaSet\", Renderer.K8sApi.replicaSetStore, \"layers\"],\n [\"Job\", Renderer.K8sApi.jobStore, \"work\"],\n [\"CronJob\", Renderer.K8sApi.cronJobStore, \"schedule\"],\n [\"Service\", Renderer.K8sApi.serviceStore, \"settings_ethernet\"],\n [\"Ingress\", Renderer.K8sApi.ingressStore, \"alt_route\"],\n [\"Namespace\", Renderer.K8sApi.namespaceStore, \"folder\"],\n [\"HorizontalPodAutoscaler\", Renderer.K8sApi.hpaStore, \"swap_vert\"],\n ] as const;\nconst icons = new Map(inventory().map(([kind, , icon]) => [kind as string, icon]));\n\nexport const ResourceSearchLauncher = observer(() => {\n if (!MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>().resourceSearchEnabled) return null;\n return (\n <button\n type=\"button\"\n title=\"Search resources (double Shift)\"\n aria-label=\"Search resources\"\n onClick={() => window.dispatchEvent(new Event(OPEN))}\n >\n <AiIcon material=\"search\" />\n </button>\n );\n});\n\nfunction SearchSnippet({ field, query }: { field?: { label: string; text: string }; query: string }) {\n if (!field) return null;\n const token = queryTokens(query).find((token) => field.text.toLocaleLowerCase().includes(token));\n const offset = token ? field.text.toLocaleLowerCase().indexOf(token) : -1;\n return (\n <small className=\"power-resource-search-snippet\">\n {field.label}:{\" \"}\n {offset < 0 || !token ? (\n field.text\n ) : (\n <>\n {field.text.slice(0, offset)}\n <mark>{field.text.slice(offset, offset + token.length)}</mark>\n {field.text.slice(offset + token.length)}\n </>\n )}\n </small>\n );\n}\n\nfunction SearchDialog({ close, clusterId }: { close: () => void; clusterId: string }) {\n const [query, setQuery] = useState(\"\");\n const [knownNamespace, setKnownNamespace] = useState(\"\");\n const [kindFilter, setKindFilter] = useState(\"\");\n const [namespaceFilter, setNamespaceFilter] = useState(\"\");\n const [resources, setResources] = useState<SearchResource[]>([]);\n const [loading, setLoading] = useState(true);\n const [failed, setFailed] = useState(0);\n const [cachedCount, setCachedCount] = useState<number>();\n const [selectedPath, setSelectedPath] = useState<string>();\n const [error, setError] = useState(\"\");\n const dialog = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const searchIndex = useMemo(() => createResourceSearchIndex(resources), [resources]);\n const matches = searchIndex.search(query);\n const selectedResource = matches.find((resource) => resource.path === selectedPath) ?? matches[0];\n const results = matches;\n if (selectedResource && !results.includes(selectedResource)) results[results.length - 1] = selectedResource;\n const selected = results.findIndex((resource) => resource.path === selectedResource?.path);\n useEffect(() => {\n if (selectedPath !== undefined && selectedPath !== selectedResource?.path) setSelectedPath(undefined);\n }, [selectedPath, selectedResource?.path]);\n const [coverage, setCoverage] = useState<SearchCoverage>(currentCoverage);\n const [limit, setLimit] = useState(100);\n const [hasMore, setHasMore] = useState(false);\n useEffect(() => {\n const previous = document.activeElement as HTMLElement | null;\n input.current?.focus();\n const update = () => setCoverage({ ...currentCoverage });\n window.addEventListener(\"power-search-coverage\", update);\n return () => {\n window.removeEventListener(\"power-search-coverage\", update);\n if (previous?.isConnected) previous.focus();\n };\n }, []);\n useEffect(() => {\n let live = true;\n const client = createResourceSearchClient(clusterId, searchContextId());\n const timer = window.setTimeout(() => {\n void client\n .query(query, limit, {\n ...(kindFilter\n ? {\n kind:\n coverage.kinds?.find((kind) => kind.toLocaleLowerCase() === kindFilter.toLocaleLowerCase()) ??\n kindFilter,\n }\n : {}),\n ...(namespaceFilter ? { namespace: namespaceFilter === \"(cluster)\" ? \"\" : namespaceFilter } : {}),\n })\n .then((result) => {\n if (!live || activeId() !== clusterId) return;\n setResources(result.documents);\n setHasMore(result.hasMore);\n setLoading(false);\n setFailed(0);\n void client\n .status?.()\n .then((status) => {\n if (live) setCachedCount(status.count);\n })\n .catch(() => {});\n })\n .catch(() => {\n if (live) {\n setFailed(1);\n setLoading(false);\n }\n });\n }, 100);\n return () => {\n live = false;\n window.clearTimeout(timer);\n };\n }, [clusterId, query, limit, kindFilter, namespaceFilter, coverage.scanned, coverage.indexing]);\n useEffect(() => {\n document.getElementById(`power-resource-result-${selected}`)?.scrollIntoView?.({ block: \"nearest\" });\n }, [selected, selectedResource?.path]);\n const clearCache = () => {\n void createResourceSearchClient(clusterId, searchContextId())\n .clear()\n .then(() => {\n setResources([]);\n restartSearchSync();\n })\n .catch(() => setError(\"Could not clear the local search cache. Try again.\"));\n };\n const open = (resource: SearchResource) => {\n if (activeId() !== clusterId) return;\n void Promise.resolve()\n .then(() => openSearchResource(resource as SearchDocument))\n .then(() => {\n if (activeId() === clusterId) close();\n })\n .catch(() => setError(\"Could not open this resource. Try again or refresh the inventory.\"));\n };\n return (\n <div\n className=\"power-resource-search-backdrop\"\n data-freelens-power-ai-overlay=\"\"\n onClick={(event) => event.stopPropagation()}\n onMouseDown={(event) => {\n event.stopPropagation();\n if (event.target === event.currentTarget) close();\n }}\n >\n <div\n ref={dialog}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"power-resource-search-title\"\n className=\"power-resource-search-dialog\"\n onKeyDown={(event) => {\n if (event.key === \"Escape\") {\n event.stopPropagation();\n close();\n }\n if (event.key === \"Tab\") {\n const controls = Array.from(\n dialog.current?.querySelectorAll<HTMLElement>(\"input, button:not(:disabled), select\") ?? [],\n );\n const index = controls.indexOf(document.activeElement as HTMLElement);\n if (event.shiftKey && index <= 0) {\n event.preventDefault();\n controls.at(-1)?.focus();\n } else if (!event.shiftKey && index === controls.length - 1) {\n event.preventDefault();\n controls[0]?.focus();\n }\n }\n }}\n >\n <div className=\"power-resource-search-heading\">\n <strong id=\"power-resource-search-title\" style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <AiIcon material=\"search\" size={18} />\n Search resources\n </strong>\n <div style={{ display: \"flex\", gap: 4 }}>\n <button\n type=\"button\"\n aria-label=\"Refresh resource inventory\"\n title=\"Refresh resource inventory\"\n onClick={() => restartSearchSync()}\n >\n <AiIcon material=\"refresh\" />\n </button>\n <button type=\"button\" aria-label=\"Close resource search\" onClick={close}>\n <AiIcon material=\"close\" />\n </button>\n </div>\n </div>\n <input\n ref={input}\n aria-label=\"Resource name, namespace, kind, label or indexed text\"\n aria-controls=\"power-resource-search-results\"\n placeholder=\"Name, namespace, label, image, condition…\"\n maxLength={300}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value);\n setSelectedPath(undefined);\n }}\n onKeyDown={(event) => {\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n const next = results.length\n ? (selected + (event.key === \"ArrowDown\" ? 1 : -1) + results.length) % results.length\n : 0;\n setSelectedPath(results[next]?.path);\n }\n if (event.key === \"Enter\" && !event.nativeEvent.isComposing && results[selected]) {\n event.preventDefault();\n open(results[selected]);\n }\n }}\n />\n <div className=\"power-resource-search-filters\" style={{ display: \"flex\", gap: 8, flexWrap: \"wrap\" }}>\n <input\n list=\"power-search-kinds\"\n aria-label=\"Filter by exact resource kind\"\n placeholder=\"Kind (all types)\"\n value={kindFilter}\n maxLength={253}\n onChange={(event) => {\n setKindFilter(event.target.value);\n setSelectedPath(undefined);\n }}\n />\n <input\n list=\"power-search-namespaces\"\n aria-label=\"Filter by exact namespace\"\n placeholder=\"Namespace (all)\"\n value={namespaceFilter}\n maxLength={253}\n onChange={(event) => {\n setNamespaceFilter(event.target.value);\n setSelectedPath(undefined);\n }}\n />\n </div>\n <datalist id=\"power-search-kinds\">\n {(coverage.kinds ?? []).map((kind) => (\n <option key={kind} value={kind} />\n ))}\n </datalist>\n <datalist id=\"power-search-namespaces\">\n <option value=\"(cluster)\">Cluster scoped</option>\n {(coverage.namespaces ?? []).map((namespace) => (\n <option key={namespace} value={namespace} />\n ))}\n </datalist>\n <p role=\"status\">\n {coverage.indexing\n ? `Indexing ${coverage.scanned}/${coverage.discovered} types`\n : coverage.completedAt\n ? `Updated ${new Date(coverage.completedAt).toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" })}`\n : \"Cached inventory\"}\n {cachedCount !== undefined && ` · ${cachedCount.toLocaleString()} resources`}\n {coverage.denied > 0 && ` · ${coverage.denied} restricted scopes`}\n {coverage.unavailable + coverage.unsupported > 0 &&\n ` · ${coverage.unavailable + coverage.unsupported} APIs unavailable`}\n {failed > 0 && \" · Search cache unavailable\"}\n </p>\n {(coverage.message || coverage.denied > 0 || coverage.unavailable + coverage.unsupported > 0) && (\n <details>\n <summary>Inventory coverage</summary>\n <p>\n {coverage.message ?? \"Results include the resources your current permissions and available APIs allow.\"}\n </p>\n </details>\n )}\n {coverage.storageFull && (\n <div role=\"alert\">\n <p>Local search storage is full. Cached results are partial; indexing is paused.</p>\n <button type=\"button\" onClick={clearCache}>\n Clear local search cache\n </button>\n </div>\n )}\n {error && <p role=\"alert\">{error}</p>}\n <div\n id=\"power-resource-search-results\"\n role=\"list\"\n aria-label=\"Matching resources\"\n className=\"power-resource-search-results\"\n >\n {results.map((resource, index) => (\n <div\n key={resource.path}\n id={`power-resource-result-${index}`}\n role=\"listitem\"\n className={`power-resource-search-row ${selected === index ? \"selected\" : \"\"}`}\n >\n <button className=\"power-resource-search-open\" type=\"button\" onClick={() => open(resource)}>\n <AiIcon material={icons.get(resource.kind) ?? \"view_in_ar\"} />\n <span>\n <strong>{resource.name}</strong>\n <small>\n {resource.kind} · {resource.namespace ?? \"cluster scoped\"}\n </small>\n {searchIndex.nameParts(resource) && <small>Name parts</small>}\n {searchIndex.similarName(resource) && <small>Similar name</small>}\n <SearchSnippet field={searchIndex.snippet(resource, query)} query={query} />\n </span>\n </button>\n <DiagnosticExplainButton\n className=\"power-resource-search-ai\"\n aria-label={`Ask AI about ${resource.kind} ${resource.name}`}\n title=\"Ask AI about this resource\"\n onClick={() => {\n if (activeId() !== clusterId) return;\n close();\n explainDiagnosticFinding({\n clusterId,\n title: `${resource.kind}: ${resource.name}`,\n summary: `Resource selected from search. API group: ${(resource as SearchDocument).group || \"core\"}; version: ${(resource as SearchDocument).version}; resource: ${(resource as SearchDocument).resource}; kind: ${resource.kind}; namespace: ${resource.namespace ?? \"cluster scoped\"}; name: ${resource.name}; UID: ${(resource as SearchDocument).uid ?? \"unknown\"}; path: ${resource.path}. No live diagnostic data was collected.`,\n resource: { kind: resource.kind, name: resource.name, namespace: resource.namespace },\n });\n }}\n >\n <AiIcon material=\"auto_awesome\" />\n </DiagnosticExplainButton>\n </div>\n ))}\n {!results.length && <p>{loading ? \"Searching…\" : \"No matching resources in the available inventory\"}</p>}\n </div>\n {hasMore && (\n <button\n type=\"button\"\n disabled={limit >= 1000}\n onClick={() => setLimit((value) => Math.min(1000, value + 100))}\n >\n Show more matches\n </button>\n )}\n <details>\n <summary>Search options</summary>\n <div style={{ display: \"flex\", gap: 8, flexWrap: \"wrap\" }}>\n <input\n aria-label=\"Known namespace for restricted access\"\n placeholder=\"Known namespace\"\n value={knownNamespace}\n maxLength={63}\n onChange={(event) => setKnownNamespace(event.target.value)}\n />\n <button\n type=\"button\"\n disabled={!/^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/.test(knownNamespace)}\n onClick={() => {\n extraNamespaces.add(knownNamespace);\n restartSearchSync();\n }}\n >\n Index namespace\n </button>\n </div>\n {hasMore && limit >= 1000 && (\n <p>Showing up to 1000 candidates. Refine the name, type or namespace to continue.</p>\n )}\n {!coverage.storageFull && (\n <button type=\"button\" onClick={clearCache}>\n Clear local search cache\n </button>\n )}\n </details>\n <p className=\"power-resource-search-shortcuts\">↑↓ Navigate · Enter Open · Esc Close</p>\n </div>\n </div>\n );\n}\n\nlet currentCoverage: SearchCoverage = {\n scanned: 0,\n discovered: 0,\n denied: 0,\n unavailable: 0,\n unsupported: 0,\n indexing: true,\n};\nlet restartSearchSync = () => {};\nconst extraNamespaces = new Set<string>();\n\nexport function startResourceSearch(): () => void {\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n let stop = preferences.resourceSearchEnabled ? startEnabledResourceSearch() : undefined;\n const dispose = reaction(\n () => preferences.resourceSearchEnabled,\n (enabled) => {\n stop?.();\n stop = enabled ? startEnabledResourceSearch() : undefined;\n },\n );\n return () => {\n dispose();\n stop?.();\n stop = undefined;\n };\n}\n\nfunction startEnabledResourceSearch(): () => void {\n let syncAbort: AbortController | undefined;\n const sync = () => {\n syncAbort?.abort();\n closeSearchResourceFallback();\n const clusterId = activeId();\n if (!clusterId || window.top === window) return;\n const phase = Renderer.Catalog.activeCluster.get()?.status?.phase;\n if (phase && phase !== \"connected\") {\n currentCoverage = {\n ...currentCoverage,\n indexing: false,\n message: \"Cluster disconnected; cached results may be stale\",\n };\n window.dispatchEvent(new Event(\"power-search-coverage\"));\n return;\n }\n const controller = new AbortController();\n syncAbort = controller;\n const client = createResourceSearchClient(clusterId, searchContextId());\n const liveStores = new Map(inventory().map(([kind, store]) => [kind as string, store]));\n const liveObjects = new Map<string, Map<string, unknown>>();\n const sink = {\n ...client,\n append: (scope: string, scanId: string, documents: SearchDocument[]) =>\n client.append(\n scope,\n scanId,\n documents.map((item) => {\n const store = liveStores.get(item.kind);\n if (!store) return item;\n let objects = liveObjects.get(item.kind);\n if (!objects) {\n objects = new Map(store.items.map((object) => [object.selfLink, object] as const));\n liveObjects.set(item.kind, objects);\n }\n const object = objects.get(item.path);\n return object ? { ...item, fields: projectSearchFields(item.kind, object) } : item;\n }),\n ),\n };\n let wasIndexing = false;\n const task = createSearchSynchronizer({\n transport: createResourceSearchTransport(clusterId, controller.signal),\n sink,\n signal: controller.signal,\n namespaces: () => [\n ...new Set([...(Renderer.Catalog.activeCluster.get()?.spec?.accessibleNamespaces ?? []), ...extraNamespaces]),\n ],\n onStatus: (status) => {\n if (!controller.signal.aborted) {\n if (status.indexing && !wasIndexing) liveObjects.clear();\n wasIndexing = status.indexing;\n currentCoverage = status;\n window.dispatchEvent(new Event(\"power-search-coverage\"));\n }\n },\n });\n void task.run().catch(() => {\n if (!controller.signal.aborted) {\n currentCoverage = { ...currentCoverage, indexing: false, unavailable: currentCoverage.unavailable + 1 };\n window.dispatchEvent(new Event(\"power-search-coverage\"));\n }\n });\n };\n restartSearchSync = sync;\n sync();\n const container = document.createElement(\"div\");\n const style = document.createElement(\"style\");\n style.textContent = `.power-resource-search-backdrop{position:fixed;inset:0;z-index:10000;background:#0007;display:flex;align-items:flex-start;justify-content:center;padding:8vh 20px}.power-resource-search-dialog{width:680px;max-width:100%;max-height:75vh;display:flex;flex-direction:column;padding:20px;gap:12px;background:var(--mainBackground,#222);color:var(--textColorPrimary,#eee);border:1px solid var(--borderColor,#555);border-radius:8px;box-shadow:0 16px 60px #0008}.power-resource-search-heading{display:flex;align-items:center;justify-content:space-between}.power-resource-search-filters input{flex:1;min-width:180px}.power-resource-search-dialog input{padding:12px;font-size:16px;background:var(--inputControlBackground,#333);color:inherit;border:1px solid var(--borderColor,#666);border-radius:4px}.power-resource-search-dialog p{margin:0;font-size:12px;color:var(--textColorSecondary,#bbb)}.power-resource-search-results{overflow:auto;min-height:180px;flex:1}.power-resource-search-row{display:flex;align-items:center;gap:12px;padding:4px;border-radius:4px}.power-resource-search-row{border-left:3px solid transparent}.power-resource-search-row.selected{background:color-mix(in srgb,var(--primary,#668fff) 16%,var(--mainBackground,#222));color:var(--tableSelectedRowColor,var(--textColorPrimary,#eee));border-left-color:var(--primary,#668fff)}.power-resource-search-row.selected .Icon{color:var(--primary,#8daaff)}.power-resource-search-row:hover{background:var(--tableBgcSelected,var(--contentColor,#292d32))}.power-resource-search-dialog button:hover:not(:disabled){background:#ffffff12;border-radius:4px}.power-resource-search-row>button:last-child{border:1px solid var(--borderColor,#555);border-radius:4px}.power-resource-search-shortcuts{padding-top:8px;border-top:1px solid var(--borderColor,#555)}.power-resource-search-dialog button{min-width:32px;min-height:32px;padding:6px;color:inherit;background:transparent;border:0;cursor:pointer}.power-resource-search-dialog button:disabled{opacity:.45;cursor:default}.power-resource-search-open{display:flex;align-items:center;gap:12px;flex:1;text-align:left;min-width:0}.power-resource-search-open span{min-width:0}.power-resource-search-open strong,.power-resource-search-open small{display:block;overflow-wrap:anywhere}.power-resource-search-open small{opacity:.7}.power-resource-search-row>button.power-resource-search-ai{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;min-width:34px;padding:0;background:var(--contentColor,#292d32);border:1px solid var(--borderColor,#666)}.power-resource-search-row.selected>button.power-resource-search-ai{background:var(--mainBackground,#202326);border-color:color-mix(in srgb,var(--textColorPrimary,#ddd) 55%,var(--borderColor,#666));box-shadow:0 1px 3px #0002}.power-resource-search-row.selected>button.power-resource-search-ai .Icon{color:var(--textColorAccent,#eee)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled){background:var(--contentColor,#30343a);border-color:var(--primary,#8daaff);color:var(--primary,#8daaff)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled) .Icon{color:inherit}.power-resource-search-dialog button:focus-visible{outline:2px solid var(--primary,#668fff)}`;\n document.head.append(style);\n document.body.append(container);\n let visible = false;\n const close = () => {\n if (visible) {\n visible = false;\n ReactDOM.unmountComponentAtNode(container);\n }\n };\n const show = () => {\n const clusterId = activeId();\n if (\n window.top === window ||\n !clusterId ||\n visible ||\n document.querySelector('[aria-modal=\"true\"], .Dialog.is-opened')\n )\n return;\n visible = true;\n ReactDOM.render(<SearchDialog close={close} clusterId={clusterId} />, container);\n };\n let shift = createDoubleShift();\n const resetShift = () => {\n shift = createDoubleShift();\n };\n const key = (event: KeyboardEvent) => {\n if (event.isComposing || event.key === \"Process\") {\n resetShift();\n return;\n }\n if (shift(event, performance.now())) show();\n };\n window.addEventListener(\"blur\", resetShift);\n window.addEventListener(\"keydown\", key);\n window.addEventListener(\"keyup\", key);\n window.addEventListener(OPEN, show);\n const dispose = reaction(\n () => `${searchContextId()}/${Renderer.Catalog.activeCluster.get()?.status?.phase}`,\n () => {\n close();\n extraNamespaces.clear();\n sync();\n },\n );\n return () => {\n close();\n syncAbort?.abort();\n closeSearchResourceFallback();\n restartSearchSync = () => {};\n extraNamespaces.clear();\n dispose();\n window.removeEventListener(\"blur\", resetShift);\n window.removeEventListener(\"keydown\", key);\n window.removeEventListener(\"keyup\", key);\n window.removeEventListener(OPEN, show);\n container.remove();\n style.remove();\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"resource-search.js","names":[],"sources":["../../src/renderer/resource-search.tsx"],"sourcesContent":["import { Renderer } from \"@freelensapp/extensions\";\nimport { reaction } from \"mobx\";\nimport { observer } from \"mobx-react\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport ReactDOM from \"react-dom\";\nimport Select from \"react-select\";\nimport { resourceKindPriority } from \"../common/resource-search-kind-priority\";\nimport { MonitoringPreferencesStore } from \"../common/store/monitoring-preferences-store\";\nimport { explainDiagnosticFinding } from \"./ai-diagnostic-handoff\";\nimport { AiIcon } from \"./ai-icon\";\nimport { DiagnosticExplainButton } from \"./diagnostic-explain-button\";\nimport { createResourceSearchClient, createResourceSearchTransport, searchContextId } from \"./resource-search-client\";\nimport { projectSearchFields } from \"./resource-search-fields\";\nimport {\n createDoubleShift,\n createResourceSearchIndex,\n queryTokens,\n type SearchResource,\n} from \"./resource-search-model\";\nimport { closeSearchResourceFallback, openSearchResource } from \"./resource-search-routing\";\nimport { createSearchSynchronizer, type SearchCoverage } from \"./resource-search-sync\";\n\nimport type { SearchDocument } from \"../common/resource-search\";\n\nconst OPEN = \"power-resource-search\";\nconst activeId = () => Renderer.Catalog.activeCluster.get()?.metadata.uid;\nconst inventory = () =>\n [\n [\"Pod\", Renderer.K8sApi.podsStore, \"view_in_ar\"],\n [\"Node\", Renderer.K8sApi.nodesStore, \"dns\"],\n [\"Deployment\", Renderer.K8sApi.deploymentStore, \"layers\"],\n [\"StatefulSet\", Renderer.K8sApi.statefulSetStore, \"layers\"],\n [\"DaemonSet\", Renderer.K8sApi.daemonSetStore, \"layers\"],\n [\"ReplicaSet\", Renderer.K8sApi.replicaSetStore, \"layers\"],\n [\"Job\", Renderer.K8sApi.jobStore, \"work\"],\n [\"CronJob\", Renderer.K8sApi.cronJobStore, \"schedule\"],\n [\"Service\", Renderer.K8sApi.serviceStore, \"settings_ethernet\"],\n [\"Ingress\", Renderer.K8sApi.ingressStore, \"alt_route\"],\n [\"Namespace\", Renderer.K8sApi.namespaceStore, \"folder\"],\n [\"HorizontalPodAutoscaler\", Renderer.K8sApi.hpaStore, \"swap_vert\"],\n ] as const;\nconst icons = new Map(inventory().map(([kind, , icon]) => [kind as string, icon]));\n\nfunction SearchFilterSelect({\n value,\n options,\n ...props\n}: {\n value: string;\n options: { value: string; label: string }[];\n \"aria-label\": string;\n onMenuOpen(): void;\n onMenuClose(): void;\n onChange(option: { value: string; label: string } | null): void;\n}) {\n return (\n <Select\n {...props}\n className={`Select theme-${Renderer.Theme?.activeTheme?.get()?.type ?? \"dark\"}`}\n classNamePrefix=\"Select\"\n value={options.find((option) => option.value === value) ?? null}\n options={options}\n isClearable={false}\n tabSelectsValue={false}\n menuPlacement=\"auto\"\n />\n );\n}\n\nexport const ResourceSearchLauncher = observer(() => {\n if (!MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>().resourceSearchEnabled) return null;\n return (\n <button\n type=\"button\"\n title=\"Search resources (double Shift)\"\n aria-label=\"Search resources\"\n onClick={() => window.dispatchEvent(new Event(OPEN))}\n >\n <AiIcon material=\"search\" />\n </button>\n );\n});\n\nfunction SearchSnippet({ field, query }: { field?: { label: string; text: string }; query: string }) {\n if (!field) return null;\n const token = queryTokens(query).find((token) => field.text.toLocaleLowerCase().includes(token));\n const offset = token ? field.text.toLocaleLowerCase().indexOf(token) : -1;\n return (\n <small className=\"power-resource-search-snippet\">\n {field.label}:{\" \"}\n {offset < 0 || !token ? (\n field.text\n ) : (\n <>\n {field.text.slice(0, offset)}\n <mark>{field.text.slice(offset, offset + token.length)}</mark>\n {field.text.slice(offset + token.length)}\n </>\n )}\n </small>\n );\n}\n\nfunction SearchDialog({ close, clusterId }: { close: () => void; clusterId: string }) {\n const [query, setQuery] = useState(\"\");\n const [kindFilter, setKindFilter] = useState(\"\");\n const [namespaceFilter, setNamespaceFilter] = useState(\"\");\n const [resources, setResources] = useState<SearchResource[]>([]);\n const [loading, setLoading] = useState(true);\n const [failed, setFailed] = useState(0);\n const [cachedCount, setCachedCount] = useState<number>();\n const [selectedPath, setSelectedPath] = useState<string>();\n const [error, setError] = useState(\"\");\n const dialog = useRef<HTMLDivElement>(null);\n const input = useRef<HTMLInputElement>(null);\n const openFilterMenus = useRef(new Set<string>());\n const escapeFromOpenMenu = useRef(false);\n const searchIndex = useMemo(() => createResourceSearchIndex(resources), [resources]);\n const matches = searchIndex.search(query);\n const selectedResource = matches.find((resource) => resource.path === selectedPath) ?? matches[0];\n const results = matches;\n if (selectedResource && !results.includes(selectedResource)) results[results.length - 1] = selectedResource;\n const selected = results.findIndex((resource) => resource.path === selectedResource?.path);\n useEffect(() => {\n if (selectedPath !== undefined && selectedPath !== selectedResource?.path) setSelectedPath(undefined);\n }, [selectedPath, selectedResource?.path]);\n const [coverage, setCoverage] = useState<SearchCoverage>(currentCoverage);\n const [limit, setLimit] = useState(100);\n const [hasMore, setHasMore] = useState(false);\n useEffect(() => {\n const previous = document.activeElement as HTMLElement | null;\n input.current?.focus();\n const update = () => setCoverage({ ...currentCoverage });\n window.addEventListener(\"power-search-coverage\", update);\n return () => {\n window.removeEventListener(\"power-search-coverage\", update);\n if (previous?.isConnected) previous.focus();\n };\n }, []);\n useEffect(() => {\n let live = true;\n const client = createResourceSearchClient(clusterId, searchContextId());\n const timer = window.setTimeout(() => {\n void client\n .query(query, limit, {\n ...(kindFilter\n ? {\n kind:\n coverage.kinds?.find((kind) => kind.toLocaleLowerCase() === kindFilter.toLocaleLowerCase()) ??\n kindFilter,\n }\n : {}),\n ...(namespaceFilter ? { namespace: namespaceFilter === \"(cluster)\" ? \"\" : namespaceFilter } : {}),\n })\n .then((result) => {\n if (!live || activeId() !== clusterId) return;\n setResources(result.documents);\n setHasMore(result.hasMore);\n setLoading(false);\n setFailed(0);\n void client\n .status?.()\n .then((status) => {\n if (live) setCachedCount(status.count);\n })\n .catch(() => {});\n })\n .catch(() => {\n if (live) {\n setFailed(1);\n setLoading(false);\n }\n });\n }, 100);\n return () => {\n live = false;\n window.clearTimeout(timer);\n };\n }, [clusterId, query, limit, kindFilter, namespaceFilter, coverage.scanned, coverage.indexing]);\n useEffect(() => {\n document.getElementById(`power-resource-result-${selected}`)?.scrollIntoView?.({ block: \"nearest\" });\n }, [selected, selectedResource?.path]);\n const clearCache = () => {\n void createResourceSearchClient(clusterId, searchContextId())\n .clear()\n .then(() => {\n setResources([]);\n restartSearchSync();\n })\n .catch(() => setError(\"Could not clear the local search cache. Try again.\"));\n };\n const open = (resource: SearchResource) => {\n if (activeId() !== clusterId) return;\n void Promise.resolve()\n .then(() => openSearchResource(resource as SearchDocument))\n .then(() => {\n if (activeId() === clusterId) close();\n })\n .catch(() => setError(\"Could not open this resource. Try again or refresh the inventory.\"));\n };\n return (\n <div\n className=\"power-resource-search-backdrop\"\n data-freelens-power-ai-overlay=\"\"\n onClick={(event) => event.stopPropagation()}\n onMouseDown={(event) => {\n event.stopPropagation();\n if (event.target === event.currentTarget) close();\n }}\n >\n <div\n ref={dialog}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"power-resource-search-title\"\n className=\"power-resource-search-dialog\"\n onKeyDownCapture={(event) => {\n if (event.key === \"Escape\") escapeFromOpenMenu.current = openFilterMenus.current.size > 0;\n }}\n onKeyDown={(event) => {\n if (event.key === \"Escape\" && !escapeFromOpenMenu.current) {\n event.stopPropagation();\n close();\n }\n if (event.key === \"Tab\") {\n const controls = Array.from(\n dialog.current?.querySelectorAll<HTMLElement>(\"input, button:not(:disabled), select\") ?? [],\n );\n const index = controls.indexOf(document.activeElement as HTMLElement);\n if (event.shiftKey && index <= 0) {\n event.preventDefault();\n controls.at(-1)?.focus();\n } else if (!event.shiftKey && index === controls.length - 1) {\n event.preventDefault();\n controls[0]?.focus();\n }\n }\n }}\n >\n <div className=\"power-resource-search-heading\">\n <strong id=\"power-resource-search-title\" style={{ display: \"flex\", alignItems: \"center\", gap: 8 }}>\n <AiIcon material=\"search\" size={18} />\n Search resources\n </strong>\n <div style={{ display: \"flex\", gap: 4 }}>\n <button\n type=\"button\"\n aria-label=\"Refresh resource inventory\"\n title=\"Refresh resource inventory\"\n onClick={() => restartSearchSync()}\n >\n <AiIcon material=\"refresh\" />\n </button>\n <button type=\"button\" aria-label=\"Close resource search\" onClick={close}>\n <AiIcon material=\"close\" />\n </button>\n </div>\n </div>\n <input\n ref={input}\n aria-label=\"Resource name, namespace, kind, label or indexed text\"\n aria-controls=\"power-resource-search-results\"\n placeholder=\"Name, namespace, label, image, condition…\"\n maxLength={300}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value);\n setSelectedPath(undefined);\n }}\n onKeyDown={(event) => {\n if (event.key === \"ArrowDown\" || event.key === \"ArrowUp\") {\n event.preventDefault();\n const next = results.length\n ? (selected + (event.key === \"ArrowDown\" ? 1 : -1) + results.length) % results.length\n : 0;\n setSelectedPath(results[next]?.path);\n }\n if (event.key === \"Enter\" && !event.nativeEvent.isComposing && results[selected]) {\n event.preventDefault();\n open(results[selected]);\n }\n }}\n />\n <div className=\"power-resource-search-filters\">\n <label className=\"power-resource-search-filter\">\n <span>Kind</span>\n <SearchFilterSelect\n aria-label=\"Kind\"\n onMenuOpen={() => openFilterMenus.current.add(\"kind\")}\n onMenuClose={() => openFilterMenus.current.delete(\"kind\")}\n value={kindFilter}\n options={[\n { value: \"\", label: \"All types\" },\n ...[...(coverage.kinds ?? [])]\n .sort(\n (first, second) =>\n resourceKindPriority(first) - resourceKindPriority(second) || first.localeCompare(second, \"en\"),\n )\n .map((kind) => ({ value: kind, label: kind })),\n ]}\n onChange={(option) => {\n setKindFilter(option?.value ?? \"\");\n setSelectedPath(undefined);\n }}\n />\n </label>\n <label className=\"power-resource-search-filter\">\n <span>Namespace</span>\n <SearchFilterSelect\n aria-label=\"Namespace\"\n onMenuOpen={() => openFilterMenus.current.add(\"namespace\")}\n onMenuClose={() => openFilterMenus.current.delete(\"namespace\")}\n value={namespaceFilter}\n options={[\n { value: \"\", label: \"All namespaces\" },\n { value: \"(cluster)\", label: \"Cluster scoped\" },\n ...(coverage.namespaces ?? []).map((namespace) => ({ value: namespace, label: namespace })),\n ]}\n onChange={(option) => {\n setNamespaceFilter(option?.value ?? \"\");\n setSelectedPath(undefined);\n }}\n />\n </label>\n </div>\n <p role=\"status\">\n {coverage.indexing\n ? `Indexing ${coverage.scanned}/${coverage.discovered} types`\n : coverage.completedAt\n ? `Updated ${new Date(coverage.completedAt).toLocaleTimeString([], { hour: \"2-digit\", minute: \"2-digit\" })}`\n : \"Cached inventory\"}\n {cachedCount !== undefined && ` · ${cachedCount.toLocaleString()} resources`}\n {coverage.denied > 0 && ` · ${coverage.denied} restricted scopes`}\n {coverage.unavailable + coverage.unsupported > 0 &&\n ` · ${coverage.unavailable + coverage.unsupported} APIs unavailable`}\n {failed > 0 && \" · Search cache unavailable\"}\n </p>\n {(coverage.message || coverage.denied > 0 || coverage.unavailable + coverage.unsupported > 0) && (\n <details>\n <summary>Inventory coverage</summary>\n <p>\n {coverage.message ?? \"Results include the resources your current permissions and available APIs allow.\"}\n </p>\n </details>\n )}\n {coverage.storageFull && (\n <div role=\"alert\">\n <p>Local search storage is full. Cached results are partial; indexing is paused.</p>\n </div>\n )}\n {error && <p role=\"alert\">{error}</p>}\n <div\n id=\"power-resource-search-results\"\n role=\"list\"\n aria-label=\"Matching resources\"\n className=\"power-resource-search-results\"\n >\n {results.map((resource, index) => (\n <div\n key={resource.path}\n id={`power-resource-result-${index}`}\n role=\"listitem\"\n className={`power-resource-search-row ${selected === index ? \"selected\" : \"\"}`}\n >\n <button className=\"power-resource-search-open\" type=\"button\" onClick={() => open(resource)}>\n <AiIcon material={icons.get(resource.kind) ?? \"view_in_ar\"} />\n <span>\n <strong>{resource.name}</strong>\n <small>\n {resource.kind} · {resource.namespace ?? \"cluster scoped\"}\n </small>\n {searchIndex.nameParts(resource) && <small>Name parts</small>}\n {searchIndex.similarName(resource) && <small>Similar name</small>}\n <SearchSnippet field={searchIndex.snippet(resource, query)} query={query} />\n </span>\n </button>\n <DiagnosticExplainButton\n className=\"power-resource-search-ai\"\n aria-label={`Ask AI about ${resource.kind} ${resource.name}`}\n title=\"Ask AI about this resource\"\n onClick={() => {\n if (activeId() !== clusterId) return;\n close();\n explainDiagnosticFinding({\n clusterId,\n title: `${resource.kind}: ${resource.name}`,\n summary: `Resource selected from search. API group: ${(resource as SearchDocument).group || \"core\"}; version: ${(resource as SearchDocument).version}; resource: ${(resource as SearchDocument).resource}; kind: ${resource.kind}; namespace: ${resource.namespace ?? \"cluster scoped\"}; name: ${resource.name}; UID: ${(resource as SearchDocument).uid ?? \"unknown\"}; path: ${resource.path}. No live diagnostic data was collected.`,\n resource: { kind: resource.kind, name: resource.name, namespace: resource.namespace },\n });\n }}\n >\n <AiIcon material=\"auto_awesome\" />\n </DiagnosticExplainButton>\n </div>\n ))}\n {!results.length && <p>{loading ? \"Searching…\" : \"No matching resources in the available inventory\"}</p>}\n </div>\n {hasMore && (\n <button\n type=\"button\"\n disabled={limit >= 1000}\n onClick={() => setLimit((value) => Math.min(1000, value + 100))}\n >\n Show more matches\n </button>\n )}\n {hasMore && limit >= 1000 && (\n <p>Showing up to 1000 candidates. Refine the name, type or namespace to continue.</p>\n )}\n <div className=\"power-resource-search-footer\">\n <p className=\"power-resource-search-shortcuts\">↑↓ Navigate · Enter Open · Esc Close</p>\n <button\n type=\"button\"\n className=\"power-resource-search-clear\"\n title=\"Clear local search cache\"\n aria-label=\"Clear local search cache\"\n onClick={clearCache}\n >\n <AiIcon material=\"delete_sweep\" size={16} />\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nlet currentCoverage: SearchCoverage = {\n scanned: 0,\n discovered: 0,\n denied: 0,\n unavailable: 0,\n unsupported: 0,\n indexing: true,\n};\nlet restartSearchSync = () => {};\n\nexport function startResourceSearch(): () => void {\n const preferences = MonitoringPreferencesStore.getInstanceOrCreate<MonitoringPreferencesStore>();\n let stop = preferences.resourceSearchEnabled ? startEnabledResourceSearch() : undefined;\n const dispose = reaction(\n () => preferences.resourceSearchEnabled,\n (enabled) => {\n stop?.();\n stop = enabled ? startEnabledResourceSearch() : undefined;\n },\n );\n return () => {\n dispose();\n stop?.();\n stop = undefined;\n };\n}\n\nfunction startEnabledResourceSearch(): () => void {\n let syncAbort: AbortController | undefined;\n const sync = () => {\n syncAbort?.abort();\n closeSearchResourceFallback();\n const clusterId = activeId();\n if (!clusterId || window.top === window) return;\n const phase = Renderer.Catalog.activeCluster.get()?.status?.phase;\n if (phase && phase !== \"connected\") {\n currentCoverage = {\n ...currentCoverage,\n indexing: false,\n message: \"Cluster disconnected; cached results may be stale\",\n };\n window.dispatchEvent(new Event(\"power-search-coverage\"));\n return;\n }\n const controller = new AbortController();\n syncAbort = controller;\n const client = createResourceSearchClient(clusterId, searchContextId());\n const liveStores = new Map(inventory().map(([kind, store]) => [kind as string, store]));\n const liveObjects = new Map<string, Map<string, unknown>>();\n const sink = {\n ...client,\n append: (scope: string, scanId: string, documents: SearchDocument[]) =>\n client.append(\n scope,\n scanId,\n documents.map((item) => {\n const store = liveStores.get(item.kind);\n if (!store) return item;\n let objects = liveObjects.get(item.kind);\n if (!objects) {\n objects = new Map(store.items.map((object) => [object.selfLink, object] as const));\n liveObjects.set(item.kind, objects);\n }\n const object = objects.get(item.path);\n return object ? { ...item, fields: projectSearchFields(item.kind, object) } : item;\n }),\n ),\n };\n let wasIndexing = false;\n const task = createSearchSynchronizer({\n transport: createResourceSearchTransport(clusterId, controller.signal),\n sink,\n signal: controller.signal,\n namespaces: () => Renderer.Catalog.activeCluster.get()?.spec?.accessibleNamespaces ?? [],\n onStatus: (status) => {\n if (!controller.signal.aborted) {\n if (status.indexing && !wasIndexing) liveObjects.clear();\n wasIndexing = status.indexing;\n currentCoverage = status;\n window.dispatchEvent(new Event(\"power-search-coverage\"));\n }\n },\n });\n void task.run().catch(() => {\n if (!controller.signal.aborted) {\n currentCoverage = { ...currentCoverage, indexing: false, unavailable: currentCoverage.unavailable + 1 };\n window.dispatchEvent(new Event(\"power-search-coverage\"));\n }\n });\n };\n restartSearchSync = sync;\n sync();\n const container = document.createElement(\"div\");\n const style = document.createElement(\"style\");\n style.textContent = `.power-resource-search-backdrop{position:fixed;inset:0;z-index:10000;background:#0007;display:flex;align-items:flex-start;justify-content:center;padding:8vh 20px}.power-resource-search-dialog{width:680px;max-width:100%;max-height:75vh;display:flex;flex-direction:column;padding:20px;gap:12px;background:var(--mainBackground,#222);color:var(--textColorPrimary,#eee);border:1px solid var(--borderColor,#555);border-radius:8px;box-shadow:0 16px 60px #0008}.power-resource-search-heading{display:flex;align-items:center;justify-content:space-between}.power-resource-search-filters{display:flex;align-items:end;gap:8px;flex-wrap:wrap}.power-resource-search-filter{display:flex;flex-direction:column;gap:4px;flex:1;min-width:180px;font-size:12px;color:var(--textColorSecondary)}.power-resource-search-filter .Select{width:100%;min-width:0}.power-resource-search-filter .Select__control{min-height:30px;height:30px;font-size:12px}.power-resource-search-filter .Select__value-container{padding:0 8px;min-width:0}.power-resource-search-filter .Select__input-container{margin:0;padding:0}.power-resource-search-filter .Select__indicator{padding:4px 8px}.power-resource-search-filter .Select__single-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.power-resource-search-dialog > input,.power-resource-search-dialog details input{padding:12px;font-size:16px;background:var(--inputControlBackground,#333);color:inherit;border:1px solid var(--borderColor,#666);border-radius:4px}.power-resource-search-dialog p{margin:0;font-size:12px;color:var(--textColorSecondary,#bbb)}.power-resource-search-results{overflow:auto;min-height:180px;flex:1}.power-resource-search-row{display:flex;align-items:center;gap:12px;padding:4px;border-radius:4px}.power-resource-search-row{border-left:3px solid transparent}.power-resource-search-row.selected{background:color-mix(in srgb,var(--primary,#668fff) 16%,var(--mainBackground,#222));color:var(--tableSelectedRowColor,var(--textColorPrimary,#eee));border-left-color:var(--primary,#668fff)}.power-resource-search-row.selected .Icon{color:var(--primary,#8daaff)}.power-resource-search-row:hover{background:var(--tableBgcSelected,var(--contentColor,#292d32))}.power-resource-search-dialog button:hover:not(:disabled){background:#ffffff12;border-radius:4px}.power-resource-search-row>button:last-child{border:1px solid var(--borderColor,#555);border-radius:4px}.power-resource-search-footer{display:flex;align-items:center;justify-content:space-between;gap:8px;padding-top:8px;border-top:1px solid var(--borderColor,#555)}.power-resource-search-shortcuts{flex:1}.power-resource-search-footer .power-resource-search-clear{display:inline-flex;align-items:center;justify-content:center;min-width:28px;min-height:28px;width:28px;height:28px;padding:0}.power-resource-search-dialog button{min-width:32px;min-height:32px;padding:6px;color:inherit;background:transparent;border:0;cursor:pointer}.power-resource-search-dialog button:disabled{opacity:.45;cursor:default}.power-resource-search-open{display:flex;align-items:center;gap:12px;flex:1;text-align:left;min-width:0}.power-resource-search-open span{min-width:0}.power-resource-search-open strong,.power-resource-search-open small{display:block;overflow-wrap:anywhere}.power-resource-search-open small{opacity:.7}.power-resource-search-row>button.power-resource-search-ai{display:inline-flex;align-items:center;justify-content:center;flex-shrink:0;width:34px;height:34px;min-width:34px;padding:0;background:var(--contentColor,#292d32);border:1px solid var(--borderColor,#666)}.power-resource-search-row.selected>button.power-resource-search-ai{background:var(--mainBackground,#202326);border-color:color-mix(in srgb,var(--textColorPrimary,#ddd) 55%,var(--borderColor,#666));box-shadow:0 1px 3px #0002}.power-resource-search-row.selected>button.power-resource-search-ai .Icon{color:var(--textColorAccent,#eee)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled){background:var(--contentColor,#30343a);border-color:var(--primary,#8daaff);color:var(--primary,#8daaff)}.power-resource-search-row>button.power-resource-search-ai:hover:not(:disabled) .Icon{color:inherit}.power-resource-search-dialog button:focus-visible{outline:2px solid var(--primary,#668fff)}`;\n document.head.append(style);\n document.body.append(container);\n let visible = false;\n const close = () => {\n if (visible) {\n visible = false;\n ReactDOM.unmountComponentAtNode(container);\n }\n };\n const show = () => {\n const clusterId = activeId();\n if (\n window.top === window ||\n !clusterId ||\n visible ||\n document.querySelector('[aria-modal=\"true\"], .Dialog.is-opened')\n )\n return;\n visible = true;\n ReactDOM.render(<SearchDialog close={close} clusterId={clusterId} />, container);\n };\n let shift = createDoubleShift();\n const resetShift = () => {\n shift = createDoubleShift();\n };\n const key = (event: KeyboardEvent) => {\n if (event.isComposing || event.key === \"Process\") {\n resetShift();\n return;\n }\n if (shift(event, performance.now())) show();\n };\n window.addEventListener(\"blur\", resetShift);\n window.addEventListener(\"keydown\", key);\n window.addEventListener(\"keyup\", key);\n window.addEventListener(OPEN, show);\n const dispose = reaction(\n () => `${searchContextId()}/${Renderer.Catalog.activeCluster.get()?.status?.phase}`,\n () => {\n close();\n sync();\n },\n );\n return () => {\n close();\n syncAbort?.abort();\n closeSearchResourceFallback();\n restartSearchSync = () => {};\n dispose();\n window.removeEventListener(\"blur\", resetShift);\n window.removeEventListener(\"keydown\", key);\n window.removeEventListener(\"keyup\", key);\n window.removeEventListener(OPEN, show);\n container.remove();\n style.remove();\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ //#region src/common/power-log-field-filters.ts
2
+ var maxNodes = 2e5;
3
+ function validPath(path) {
4
+ if (!Array.isArray(path) || path.length > maxNodes) return false;
5
+ for (const part of path) if (typeof part !== "string" && !(typeof part === "number" && Number.isSafeInteger(part) && part >= 0)) return false;
6
+ return true;
7
+ }
8
+ function extractJsonPath(fields, path) {
9
+ if (!validPath(path)) return { found: false };
10
+ let value = fields;
11
+ for (const part of path) {
12
+ if (value === null || typeof value !== "object") return { found: false };
13
+ if (Array.isArray(value) ? typeof part !== "number" || part >= value.length : typeof part !== "string") return { found: false };
14
+ const property = Object.getOwnPropertyDescriptor(value, part);
15
+ if (!property || !("value" in property)) return { found: false };
16
+ value = property.value;
17
+ }
18
+ return {
19
+ found: true,
20
+ value
21
+ };
22
+ }
23
+ function validJson(value) {
24
+ const pending = [{ value }];
25
+ const ancestors = /* @__PURE__ */ new WeakSet();
26
+ let visited = 0;
27
+ while (pending.length) {
28
+ const item = pending.pop();
29
+ const current = item.value;
30
+ if (item.leaving) {
31
+ ancestors.delete(current);
32
+ continue;
33
+ }
34
+ if (++visited > maxNodes) return false;
35
+ if (current === null || typeof current === "string" || typeof current === "boolean") continue;
36
+ if (typeof current === "number") {
37
+ if (!Number.isFinite(current)) return false;
38
+ continue;
39
+ }
40
+ if (typeof current !== "object" || ancestors.has(current)) return false;
41
+ if (!Array.isArray(current) && ![Object.prototype, null].includes(Object.getPrototypeOf(current))) return false;
42
+ ancestors.add(current);
43
+ pending.push({
44
+ value: current,
45
+ leaving: true
46
+ });
47
+ const keys = Object.keys(current);
48
+ if (keys.length > maxNodes || Array.isArray(current) && keys.length !== current.length) return false;
49
+ for (const key of keys) {
50
+ if (Array.isArray(current) && (!/^(0|[1-9]\d*)$/.test(key) || Number(key) >= current.length)) return false;
51
+ const property = Object.getOwnPropertyDescriptor(current, key);
52
+ if (!("value" in property)) return false;
53
+ pending.push({ value: property.value });
54
+ }
55
+ }
56
+ return true;
57
+ }
58
+ function equalValues(left, right) {
59
+ const pending = [[left, right]];
60
+ while (pending.length) {
61
+ const [a, b] = pending.pop();
62
+ if (a === b) continue;
63
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") return false;
64
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
65
+ const keys = Object.keys(a);
66
+ if (keys.length !== Object.keys(b).length) return false;
67
+ for (const key of keys) {
68
+ const other = Object.getOwnPropertyDescriptor(b, key);
69
+ if (!other) return false;
70
+ pending.push([Object.getOwnPropertyDescriptor(a, key).value, other.value]);
71
+ }
72
+ }
73
+ return true;
74
+ }
75
+ function jsonValuesEqual(left, right) {
76
+ return validJson(left) && validJson(right) && equalValues(left, right);
77
+ }
78
+ function compileJsonFilters(filters) {
79
+ if (!Array.isArray(filters) || filters.length > 32 || filters.some((filter) => !filter || !validPath(filter.path) || !["eq", "neq"].includes(filter.operator) || !validJson(filter.value))) return () => false;
80
+ return (fields) => filters.every((filter) => {
81
+ const result = extractJsonPath(fields, filter.path);
82
+ const actual = result.found ? result.value : void 0;
83
+ const equal = result.found && (actual === filter.value || actual !== null && filter.value !== null && typeof actual === "object" && typeof filter.value === "object" && validJson(actual) && equalValues(actual, filter.value));
84
+ return filter.operator === "eq" ? equal : !equal;
85
+ });
86
+ }
87
+ //#endregion
88
+ exports.compileJsonFilters = compileJsonFilters;
89
+ exports.extractJsonPath = extractJsonPath;
90
+ exports.jsonValuesEqual = jsonValuesEqual;
91
+
92
+ //# sourceMappingURL=power-log-field-filters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"power-log-field-filters.js","names":[],"sources":["../../../../src/common/power-log-field-filters.ts"],"sourcesContent":["export type JSONValue = null | boolean | number | string | JSONValue[] | { [key: string]: JSONValue };\nexport type JsonPath = (string | number)[];\nexport interface JsonFieldFilter {\n path: JsonPath;\n operator: \"eq\" | \"neq\";\n value: JSONValue;\n}\nexport type JsonPathResult = { found: false } | { found: true; value: unknown };\n\nconst maxNodes = 200_000;\n\nfunction validPath(path: unknown): path is JsonPath {\n if (!Array.isArray(path) || path.length > maxNodes) return false;\n for (const part of path) {\n if (typeof part !== \"string\" && !(typeof part === \"number\" && Number.isSafeInteger(part) && part >= 0))\n return false;\n }\n return true;\n}\n\nexport function extractJsonPath(fields: unknown, path: JsonPath): JsonPathResult {\n if (!validPath(path)) return { found: false };\n let value = fields;\n for (const part of path) {\n if (value === null || typeof value !== \"object\") return { found: false };\n if (Array.isArray(value) ? typeof part !== \"number\" || part >= value.length : typeof part !== \"string\") {\n return { found: false };\n }\n const property = Object.getOwnPropertyDescriptor(value, part);\n if (!property || !(\"value\" in property)) return { found: false };\n value = property.value;\n }\n return { found: true, value };\n}\n\nfunction validJson(value: unknown): value is JSONValue {\n const pending: { value: unknown; leaving?: boolean }[] = [{ value }];\n const ancestors = new WeakSet<object>();\n let visited = 0;\n while (pending.length) {\n const item = pending.pop()!;\n const current = item.value;\n if (item.leaving) {\n ancestors.delete(current as object);\n continue;\n }\n if (++visited > maxNodes) return false;\n if (current === null || typeof current === \"string\" || typeof current === \"boolean\") continue;\n if (typeof current === \"number\") {\n if (!Number.isFinite(current)) return false;\n continue;\n }\n if (typeof current !== \"object\" || ancestors.has(current)) return false;\n if (!Array.isArray(current) && ![Object.prototype, null].includes(Object.getPrototypeOf(current))) return false;\n ancestors.add(current);\n pending.push({ value: current, leaving: true });\n const keys = Object.keys(current);\n if (keys.length > maxNodes || (Array.isArray(current) && keys.length !== current.length)) return false;\n for (const key of keys) {\n if (Array.isArray(current) && (!/^(0|[1-9]\\d*)$/.test(key) || Number(key) >= current.length)) return false;\n const property = Object.getOwnPropertyDescriptor(current, key)!;\n if (!(\"value\" in property)) return false;\n pending.push({ value: property.value });\n }\n }\n return true;\n}\n\nfunction equalValues(left: JSONValue, right: JSONValue): boolean {\n const pending: [JSONValue, JSONValue][] = [[left, right]];\n while (pending.length) {\n const [a, b] = pending.pop()!;\n if (a === b) continue;\n if (a === null || b === null || typeof a !== \"object\" || typeof b !== \"object\") return false;\n if (Array.isArray(a) !== Array.isArray(b)) return false;\n const keys = Object.keys(a);\n if (keys.length !== Object.keys(b).length) return false;\n for (const key of keys) {\n const other = Object.getOwnPropertyDescriptor(b, key);\n if (!other) return false;\n pending.push([Object.getOwnPropertyDescriptor(a, key)!.value, other.value]);\n }\n }\n return true;\n}\n\nexport function jsonValuesEqual(left: unknown, right: unknown): boolean {\n return validJson(left) && validJson(right) && equalValues(left, right);\n}\n\nexport function compileJsonFilters(filters: readonly JsonFieldFilter[]): (fields: unknown) => boolean {\n if (\n !Array.isArray(filters) ||\n filters.length > 32 ||\n filters.some(\n (filter) =>\n !filter || !validPath(filter.path) || ![\"eq\", \"neq\"].includes(filter.operator) || !validJson(filter.value),\n )\n )\n return () => false;\n return (fields) =>\n filters.every((filter) => {\n const result = extractJsonPath(fields, filter.path);\n const actual = result.found ? result.value : undefined;\n const equal =\n result.found &&\n (actual === filter.value ||\n (actual !== null &&\n filter.value !== null &&\n typeof actual === \"object\" &&\n typeof filter.value === \"object\" &&\n validJson(actual) &&\n equalValues(actual, filter.value)));\n return filter.operator === \"eq\" ? equal : !equal;\n });\n}\n\nexport function matchesAllJsonFilters(fields: unknown, filters: readonly JsonFieldFilter[]): boolean {\n return compileJsonFilters(filters)(fields);\n}\n"],"mappings":"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"}