@flanksource/clicky-ui 0.2.14 → 0.2.16

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 (489) hide show
  1. package/dist/chat.cjs +20 -0
  2. package/dist/chat.cjs.map +1 -0
  3. package/dist/chat.d.ts +2 -0
  4. package/dist/chat.d.ts.map +1 -0
  5. package/dist/chat.js +20 -0
  6. package/dist/chat.js.map +1 -0
  7. package/dist/components/Combobox.cjs +19 -9
  8. package/dist/components/Combobox.cjs.map +1 -1
  9. package/dist/components/Combobox.d.ts +10 -0
  10. package/dist/components/Combobox.d.ts.map +1 -1
  11. package/dist/components/Combobox.js +19 -9
  12. package/dist/components/Combobox.js.map +1 -1
  13. package/dist/components/DateTimePicker.cjs +6 -1
  14. package/dist/components/DateTimePicker.cjs.map +1 -1
  15. package/dist/components/DateTimePicker.d.ts +11 -3
  16. package/dist/components/DateTimePicker.d.ts.map +1 -1
  17. package/dist/components/DateTimePicker.js +6 -1
  18. package/dist/components/DateTimePicker.js.map +1 -1
  19. package/dist/components/Field.cjs +33 -0
  20. package/dist/components/Field.cjs.map +1 -0
  21. package/dist/components/Field.d.ts +27 -0
  22. package/dist/components/Field.d.ts.map +1 -0
  23. package/dist/components/Field.js +33 -0
  24. package/dist/components/Field.js.map +1 -0
  25. package/dist/components/FilterBar.cjs +49 -55
  26. package/dist/components/FilterBar.cjs.map +1 -1
  27. package/dist/components/FilterBar.d.ts +2 -2
  28. package/dist/components/FilterBar.d.ts.map +1 -1
  29. package/dist/components/FilterBar.js +44 -50
  30. package/dist/components/FilterBar.js.map +1 -1
  31. package/dist/components/FormatOptionsDropdown.cjs +2 -18
  32. package/dist/components/FormatOptionsDropdown.cjs.map +1 -1
  33. package/dist/components/FormatOptionsDropdown.d.ts +1 -17
  34. package/dist/components/FormatOptionsDropdown.d.ts.map +1 -1
  35. package/dist/components/FormatOptionsDropdown.js +1 -17
  36. package/dist/components/FormatOptionsDropdown.js.map +1 -1
  37. package/dist/components/JsonSchemaForm.cjs +128 -12
  38. package/dist/components/JsonSchemaForm.cjs.map +1 -1
  39. package/dist/components/JsonSchemaForm.d.ts +1 -1
  40. package/dist/components/JsonSchemaForm.d.ts.map +1 -1
  41. package/dist/components/JsonSchemaForm.js +131 -15
  42. package/dist/components/JsonSchemaForm.js.map +1 -1
  43. package/dist/components/MultiSelect.cjs +2 -1
  44. package/dist/components/MultiSelect.cjs.map +1 -1
  45. package/dist/components/MultiSelect.d.ts +5 -1
  46. package/dist/components/MultiSelect.d.ts.map +1 -1
  47. package/dist/components/MultiSelect.js +2 -1
  48. package/dist/components/MultiSelect.js.map +1 -1
  49. package/dist/components/SecretKeySelector.cjs +0 -1
  50. package/dist/components/SecretKeySelector.cjs.map +1 -1
  51. package/dist/components/SecretKeySelector.d.ts +0 -2
  52. package/dist/components/SecretKeySelector.d.ts.map +1 -1
  53. package/dist/components/SecretKeySelector.js +1 -2
  54. package/dist/components/SecretKeySelector.js.map +1 -1
  55. package/dist/components/TreePickerField.cjs +137 -0
  56. package/dist/components/TreePickerField.cjs.map +1 -0
  57. package/dist/components/TreePickerField.d.ts +30 -0
  58. package/dist/components/TreePickerField.d.ts.map +1 -0
  59. package/dist/components/TreePickerField.js +137 -0
  60. package/dist/components/TreePickerField.js.map +1 -0
  61. package/dist/components/WorkloadPicker.cjs +6 -81
  62. package/dist/components/WorkloadPicker.cjs.map +1 -1
  63. package/dist/components/WorkloadPicker.d.ts +1 -20
  64. package/dist/components/WorkloadPicker.d.ts.map +1 -1
  65. package/dist/components/WorkloadPicker.js +3 -78
  66. package/dist/components/WorkloadPicker.js.map +1 -1
  67. package/dist/components/button-variants.cjs +30 -0
  68. package/dist/components/button-variants.cjs.map +1 -0
  69. package/dist/components/button-variants.d.ts +5 -0
  70. package/dist/components/button-variants.d.ts.map +1 -0
  71. package/dist/components/button-variants.js +30 -0
  72. package/dist/components/button-variants.js.map +1 -0
  73. package/dist/components/button.cjs +11 -82
  74. package/dist/components/button.cjs.map +1 -1
  75. package/dist/components/button.d.ts +1 -5
  76. package/dist/components/button.d.ts.map +1 -1
  77. package/dist/components/button.js +5 -76
  78. package/dist/components/button.js.map +1 -1
  79. package/dist/components/filter-bar-utils.cjs +37 -0
  80. package/dist/components/filter-bar-utils.cjs.map +1 -0
  81. package/dist/components/filter-bar-utils.d.ts +4 -0
  82. package/dist/components/filter-bar-utils.d.ts.map +1 -0
  83. package/dist/components/filter-bar-utils.js +37 -0
  84. package/dist/components/filter-bar-utils.js.map +1 -0
  85. package/dist/components/format-options.cjs +20 -0
  86. package/dist/components/format-options.cjs.map +1 -0
  87. package/dist/components/format-options.d.ts +18 -0
  88. package/dist/components/format-options.d.ts.map +1 -0
  89. package/dist/components/format-options.js +20 -0
  90. package/dist/components/format-options.js.map +1 -0
  91. package/dist/components/json-schema-form-array.cjs +13 -17
  92. package/dist/components/json-schema-form-array.cjs.map +1 -1
  93. package/dist/components/json-schema-form-array.d.ts +1 -2
  94. package/dist/components/json-schema-form-array.d.ts.map +1 -1
  95. package/dist/components/json-schema-form-array.js +3 -7
  96. package/dist/components/json-schema-form-array.js.map +1 -1
  97. package/dist/components/json-schema-form-fields.cjs +97 -232
  98. package/dist/components/json-schema-form-fields.cjs.map +1 -1
  99. package/dist/components/json-schema-form-fields.d.ts +51 -6
  100. package/dist/components/json-schema-form-fields.d.ts.map +1 -1
  101. package/dist/components/json-schema-form-fields.js +89 -224
  102. package/dist/components/json-schema-form-fields.js.map +1 -1
  103. package/dist/components/json-schema-form-object.cjs +149 -0
  104. package/dist/components/json-schema-form-object.cjs.map +1 -0
  105. package/dist/components/json-schema-form-object.d.ts +10 -0
  106. package/dist/components/json-schema-form-object.d.ts.map +1 -0
  107. package/dist/components/json-schema-form-object.js +149 -0
  108. package/dist/components/json-schema-form-object.js.map +1 -0
  109. package/dist/components/json-schema-form-preferences.cjs +41 -0
  110. package/dist/components/json-schema-form-preferences.cjs.map +1 -0
  111. package/dist/components/json-schema-form-preferences.d.ts +10 -0
  112. package/dist/components/json-schema-form-preferences.d.ts.map +1 -0
  113. package/dist/components/json-schema-form-preferences.js +41 -0
  114. package/dist/components/json-schema-form-preferences.js.map +1 -0
  115. package/dist/components/json-schema-form-render.cjs +43 -72
  116. package/dist/components/json-schema-form-render.cjs.map +1 -1
  117. package/dist/components/json-schema-form-render.d.ts +5 -33
  118. package/dist/components/json-schema-form-render.d.ts.map +1 -1
  119. package/dist/components/json-schema-form-render.js +41 -70
  120. package/dist/components/json-schema-form-render.js.map +1 -1
  121. package/dist/components/json-schema-form-resolve.cjs +9 -1
  122. package/dist/components/json-schema-form-resolve.cjs.map +1 -1
  123. package/dist/components/json-schema-form-resolve.d.ts.map +1 -1
  124. package/dist/components/json-schema-form-resolve.js +9 -1
  125. package/dist/components/json-schema-form-resolve.js.map +1 -1
  126. package/dist/components/json-schema-form-types.d.ts +59 -1
  127. package/dist/components/json-schema-form-types.d.ts.map +1 -1
  128. package/dist/components/json-schema-form-utils.cjs +96 -0
  129. package/dist/components/json-schema-form-utils.cjs.map +1 -0
  130. package/dist/components/json-schema-form-utils.d.ts +17 -0
  131. package/dist/components/json-schema-form-utils.d.ts.map +1 -0
  132. package/dist/components/json-schema-form-utils.js +96 -0
  133. package/dist/components/json-schema-form-utils.js.map +1 -0
  134. package/dist/components/loading.cjs +109 -0
  135. package/dist/components/loading.cjs.map +1 -0
  136. package/dist/components/loading.d.ts +29 -0
  137. package/dist/components/loading.d.ts.map +1 -0
  138. package/dist/components/loading.js +109 -0
  139. package/dist/components/loading.js.map +1 -0
  140. package/dist/components/use-form.cjs +27 -0
  141. package/dist/components/use-form.cjs.map +1 -0
  142. package/dist/components/use-form.d.ts +30 -0
  143. package/dist/components/use-form.d.ts.map +1 -0
  144. package/dist/components/use-form.js +27 -0
  145. package/dist/components/use-form.js.map +1 -0
  146. package/dist/components/workload-picker-utils.cjs +88 -0
  147. package/dist/components/workload-picker-utils.cjs.map +1 -0
  148. package/dist/components/workload-picker-utils.d.ts +34 -0
  149. package/dist/components/workload-picker-utils.d.ts.map +1 -0
  150. package/dist/components/workload-picker-utils.js +88 -0
  151. package/dist/components/workload-picker-utils.js.map +1 -0
  152. package/dist/components.cjs +25 -6
  153. package/dist/components.cjs.map +1 -1
  154. package/dist/components.d.ts +14 -4
  155. package/dist/components.d.ts.map +1 -1
  156. package/dist/components.js +24 -5
  157. package/dist/components.js.map +1 -1
  158. package/dist/data/Badge.cjs +11 -91
  159. package/dist/data/Badge.cjs.map +1 -1
  160. package/dist/data/Badge.d.ts +1 -5
  161. package/dist/data/Badge.d.ts.map +1 -1
  162. package/dist/data/Badge.js +11 -91
  163. package/dist/data/Badge.js.map +1 -1
  164. package/dist/data/Clicky.cjs +4 -3
  165. package/dist/data/Clicky.cjs.map +1 -1
  166. package/dist/data/Clicky.d.ts.map +1 -1
  167. package/dist/data/Clicky.js +4 -3
  168. package/dist/data/Clicky.js.map +1 -1
  169. package/dist/data/DataTable.cjs +161 -156
  170. package/dist/data/DataTable.cjs.map +1 -1
  171. package/dist/data/DataTable.d.ts +25 -4
  172. package/dist/data/DataTable.d.ts.map +1 -1
  173. package/dist/data/DataTable.js +140 -135
  174. package/dist/data/DataTable.js.map +1 -1
  175. package/dist/data/FilterPill.cjs +3 -0
  176. package/dist/data/FilterPill.cjs.map +1 -1
  177. package/dist/data/FilterPill.d.ts.map +1 -1
  178. package/dist/data/FilterPill.js +3 -0
  179. package/dist/data/FilterPill.js.map +1 -1
  180. package/dist/data/Icon.cjs +7 -7
  181. package/dist/data/Icon.cjs.map +1 -1
  182. package/dist/data/Icon.js +7 -7
  183. package/dist/data/Icon.js.map +1 -1
  184. package/dist/data/LogDetails.cjs +5 -14
  185. package/dist/data/LogDetails.cjs.map +1 -1
  186. package/dist/data/LogDetails.d.ts +8 -4
  187. package/dist/data/LogDetails.d.ts.map +1 -1
  188. package/dist/data/LogDetails.js +4 -13
  189. package/dist/data/LogDetails.js.map +1 -1
  190. package/dist/data/LogsTable.cjs +6 -165
  191. package/dist/data/LogsTable.cjs.map +1 -1
  192. package/dist/data/LogsTable.d.ts +2 -15
  193. package/dist/data/LogsTable.d.ts.map +1 -1
  194. package/dist/data/LogsTable.js +6 -165
  195. package/dist/data/LogsTable.js.map +1 -1
  196. package/dist/data/TimeseriesPanel.axes.cjs.map +1 -1
  197. package/dist/data/TimeseriesPanel.axes.js.map +1 -1
  198. package/dist/data/TreeNode.cjs +13 -7
  199. package/dist/data/TreeNode.cjs.map +1 -1
  200. package/dist/data/TreeNode.d.ts.map +1 -1
  201. package/dist/data/TreeNode.js +13 -7
  202. package/dist/data/TreeNode.js.map +1 -1
  203. package/dist/data/badge-variants.cjs +85 -0
  204. package/dist/data/badge-variants.cjs.map +1 -0
  205. package/dist/data/badge-variants.d.ts +6 -0
  206. package/dist/data/badge-variants.d.ts.map +1 -0
  207. package/dist/data/badge-variants.js +85 -0
  208. package/dist/data/badge-variants.js.map +1 -0
  209. package/dist/data/cache-browser/CacheBrowser.cjs +59 -0
  210. package/dist/data/cache-browser/CacheBrowser.cjs.map +1 -0
  211. package/dist/data/cache-browser/CacheBrowser.d.ts +26 -0
  212. package/dist/data/cache-browser/CacheBrowser.d.ts.map +1 -0
  213. package/dist/data/cache-browser/CacheBrowser.js +59 -0
  214. package/dist/data/cache-browser/CacheBrowser.js.map +1 -0
  215. package/dist/data/cache-browser/CacheDetailPanel.cjs +193 -0
  216. package/dist/data/cache-browser/CacheDetailPanel.cjs.map +1 -0
  217. package/dist/data/cache-browser/CacheDetailPanel.d.ts +20 -0
  218. package/dist/data/cache-browser/CacheDetailPanel.d.ts.map +1 -0
  219. package/dist/data/cache-browser/CacheDetailPanel.js +193 -0
  220. package/dist/data/cache-browser/CacheDetailPanel.js.map +1 -0
  221. package/dist/data/cache-browser/CacheStatsOverview.cjs +126 -0
  222. package/dist/data/cache-browser/CacheStatsOverview.cjs.map +1 -0
  223. package/dist/data/cache-browser/CacheStatsOverview.d.ts +17 -0
  224. package/dist/data/cache-browser/CacheStatsOverview.d.ts.map +1 -0
  225. package/dist/data/cache-browser/CacheStatsOverview.js +126 -0
  226. package/dist/data/cache-browser/CacheStatsOverview.js.map +1 -0
  227. package/dist/data/cache-browser/CacheTree.cjs +189 -0
  228. package/dist/data/cache-browser/CacheTree.cjs.map +1 -0
  229. package/dist/data/cache-browser/CacheTree.d.ts +27 -0
  230. package/dist/data/cache-browser/CacheTree.d.ts.map +1 -0
  231. package/dist/data/cache-browser/CacheTree.js +189 -0
  232. package/dist/data/cache-browser/CacheTree.js.map +1 -0
  233. package/dist/data/cache-browser/CacheValue.cjs +86 -0
  234. package/dist/data/cache-browser/CacheValue.cjs.map +1 -0
  235. package/dist/data/cache-browser/CacheValue.d.ts +11 -0
  236. package/dist/data/cache-browser/CacheValue.d.ts.map +1 -0
  237. package/dist/data/cache-browser/CacheValue.js +86 -0
  238. package/dist/data/cache-browser/CacheValue.js.map +1 -0
  239. package/dist/data/cache-browser/adapter.cjs +52 -0
  240. package/dist/data/cache-browser/adapter.cjs.map +1 -0
  241. package/dist/data/cache-browser/adapter.d.ts +48 -0
  242. package/dist/data/cache-browser/adapter.d.ts.map +1 -0
  243. package/dist/data/cache-browser/adapter.js +52 -0
  244. package/dist/data/cache-browser/adapter.js.map +1 -0
  245. package/dist/data/cache-browser/api.cjs +42 -0
  246. package/dist/data/cache-browser/api.cjs.map +1 -0
  247. package/dist/data/cache-browser/api.d.ts +33 -0
  248. package/dist/data/cache-browser/api.d.ts.map +1 -0
  249. package/dist/data/cache-browser/api.js +42 -0
  250. package/dist/data/cache-browser/api.js.map +1 -0
  251. package/dist/data/cache-browser/index.d.ts +9 -0
  252. package/dist/data/cache-browser/index.d.ts.map +1 -0
  253. package/dist/data/cache-browser/types.cjs +7 -0
  254. package/dist/data/cache-browser/types.cjs.map +1 -0
  255. package/dist/data/cache-browser/types.d.ts +78 -0
  256. package/dist/data/cache-browser/types.d.ts.map +1 -0
  257. package/dist/data/cache-browser/types.js +7 -0
  258. package/dist/data/cache-browser/types.js.map +1 -0
  259. package/dist/data/cells/TagList.cjs +4 -101
  260. package/dist/data/cells/TagList.cjs.map +1 -1
  261. package/dist/data/cells/TagList.d.ts +1 -49
  262. package/dist/data/cells/TagList.d.ts.map +1 -1
  263. package/dist/data/cells/TagList.js +3 -100
  264. package/dist/data/cells/TagList.js.map +1 -1
  265. package/dist/data/cells/Timestamp.cjs +3 -192
  266. package/dist/data/cells/Timestamp.cjs.map +1 -1
  267. package/dist/data/cells/Timestamp.d.ts +1 -50
  268. package/dist/data/cells/Timestamp.d.ts.map +1 -1
  269. package/dist/data/cells/Timestamp.js +2 -191
  270. package/dist/data/cells/Timestamp.js.map +1 -1
  271. package/dist/data/cells/tag-utils.cjs +103 -0
  272. package/dist/data/cells/tag-utils.cjs.map +1 -0
  273. package/dist/data/cells/tag-utils.d.ts +51 -0
  274. package/dist/data/cells/tag-utils.d.ts.map +1 -0
  275. package/dist/data/cells/tag-utils.js +103 -0
  276. package/dist/data/cells/tag-utils.js.map +1 -0
  277. package/dist/data/cells/timestamp-format.cjs +193 -0
  278. package/dist/data/cells/timestamp-format.cjs.map +1 -0
  279. package/dist/data/cells/timestamp-format.d.ts +51 -0
  280. package/dist/data/cells/timestamp-format.d.ts.map +1 -0
  281. package/dist/data/cells/timestamp-format.js +193 -0
  282. package/dist/data/cells/timestamp-format.js.map +1 -0
  283. package/dist/data/chat/Chat.cjs +48 -0
  284. package/dist/data/chat/Chat.cjs.map +1 -0
  285. package/dist/data/chat/Chat.d.ts +26 -0
  286. package/dist/data/chat/Chat.d.ts.map +1 -0
  287. package/dist/data/chat/Chat.fixtures.d.ts +6 -0
  288. package/dist/data/chat/Chat.fixtures.d.ts.map +1 -0
  289. package/dist/data/chat/Chat.js +48 -0
  290. package/dist/data/chat/Chat.js.map +1 -0
  291. package/dist/data/chat/Conversation.cjs +34 -0
  292. package/dist/data/chat/Conversation.cjs.map +1 -0
  293. package/dist/data/chat/Conversation.d.ts +11 -0
  294. package/dist/data/chat/Conversation.d.ts.map +1 -0
  295. package/dist/data/chat/Conversation.js +34 -0
  296. package/dist/data/chat/Conversation.js.map +1 -0
  297. package/dist/data/chat/Message.cjs +44 -0
  298. package/dist/data/chat/Message.cjs.map +1 -0
  299. package/dist/data/chat/Message.d.ts +10 -0
  300. package/dist/data/chat/Message.d.ts.map +1 -0
  301. package/dist/data/chat/Message.js +44 -0
  302. package/dist/data/chat/Message.js.map +1 -0
  303. package/dist/data/chat/PromptInput.cjs +61 -0
  304. package/dist/data/chat/PromptInput.cjs.map +1 -0
  305. package/dist/data/chat/PromptInput.d.ts +16 -0
  306. package/dist/data/chat/PromptInput.d.ts.map +1 -0
  307. package/dist/data/chat/PromptInput.js +61 -0
  308. package/dist/data/chat/PromptInput.js.map +1 -0
  309. package/dist/data/chat/ToolCall.cjs +92 -0
  310. package/dist/data/chat/ToolCall.cjs.map +1 -0
  311. package/dist/data/chat/ToolCall.d.ts +14 -0
  312. package/dist/data/chat/ToolCall.d.ts.map +1 -0
  313. package/dist/data/chat/ToolCall.js +92 -0
  314. package/dist/data/chat/ToolCall.js.map +1 -0
  315. package/dist/data/chat/clickyOperationsToTools.cjs +73 -0
  316. package/dist/data/chat/clickyOperationsToTools.cjs.map +1 -0
  317. package/dist/data/chat/clickyOperationsToTools.d.ts +10 -0
  318. package/dist/data/chat/clickyOperationsToTools.d.ts.map +1 -0
  319. package/dist/data/chat/clickyOperationsToTools.js +73 -0
  320. package/dist/data/chat/clickyOperationsToTools.js.map +1 -0
  321. package/dist/data/chat/index.d.ts +8 -0
  322. package/dist/data/chat/index.d.ts.map +1 -0
  323. package/dist/data/chat/types.cjs +18 -0
  324. package/dist/data/chat/types.cjs.map +1 -0
  325. package/dist/data/chat/types.d.ts +41 -0
  326. package/dist/data/chat/types.d.ts.map +1 -0
  327. package/dist/data/chat/types.js +18 -0
  328. package/dist/data/chat/types.js.map +1 -0
  329. package/dist/data/data-table-utils.cjs +55 -0
  330. package/dist/data/data-table-utils.cjs.map +1 -0
  331. package/dist/data/data-table-utils.d.ts +24 -0
  332. package/dist/data/data-table-utils.d.ts.map +1 -0
  333. package/dist/data/data-table-utils.js +55 -0
  334. package/dist/data/data-table-utils.js.map +1 -0
  335. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs +2 -1
  336. package/dist/data/diagnostics/DiagnosticsDetailPanel.cjs.map +1 -1
  337. package/dist/data/diagnostics/DiagnosticsDetailPanel.d.ts.map +1 -1
  338. package/dist/data/diagnostics/DiagnosticsDetailPanel.js +3 -2
  339. package/dist/data/diagnostics/DiagnosticsDetailPanel.js.map +1 -1
  340. package/dist/data/diagnostics/GoroutineCard.cjs +3 -22
  341. package/dist/data/diagnostics/GoroutineCard.cjs.map +1 -1
  342. package/dist/data/diagnostics/GoroutineCard.d.ts +0 -2
  343. package/dist/data/diagnostics/GoroutineCard.d.ts.map +1 -1
  344. package/dist/data/diagnostics/GoroutineCard.js +2 -21
  345. package/dist/data/diagnostics/GoroutineCard.js.map +1 -1
  346. package/dist/data/diagnostics/ThreadCard.cjs +3 -38
  347. package/dist/data/diagnostics/ThreadCard.cjs.map +1 -1
  348. package/dist/data/diagnostics/ThreadCard.d.ts +0 -2
  349. package/dist/data/diagnostics/ThreadCard.d.ts.map +1 -1
  350. package/dist/data/diagnostics/ThreadCard.js +2 -37
  351. package/dist/data/diagnostics/ThreadCard.js.map +1 -1
  352. package/dist/data/diagnostics/state-styles.cjs +59 -0
  353. package/dist/data/diagnostics/state-styles.cjs.map +1 -0
  354. package/dist/data/diagnostics/state-styles.d.ts +5 -0
  355. package/dist/data/diagnostics/state-styles.d.ts.map +1 -0
  356. package/dist/data/diagnostics/state-styles.js +59 -0
  357. package/dist/data/diagnostics/state-styles.js.map +1 -0
  358. package/dist/data/logs-normalize.cjs +166 -0
  359. package/dist/data/logs-normalize.cjs.map +1 -0
  360. package/dist/data/logs-normalize.d.ts +16 -0
  361. package/dist/data/logs-normalize.d.ts.map +1 -0
  362. package/dist/data/logs-normalize.js +166 -0
  363. package/dist/data/logs-normalize.js.map +1 -0
  364. package/dist/data/task-status.cjs +19 -19
  365. package/dist/data/task-status.cjs.map +1 -1
  366. package/dist/data/task-status.js +19 -19
  367. package/dist/data/task-status.js.map +1 -1
  368. package/dist/data/version-info.cjs +3 -3
  369. package/dist/data/version-info.js +3 -3
  370. package/dist/data.cjs +43 -18
  371. package/dist/data.cjs.map +1 -1
  372. package/dist/data.d.ts +11 -5
  373. package/dist/data.d.ts.map +1 -1
  374. package/dist/data.js +30 -5
  375. package/dist/data.js.map +1 -1
  376. package/dist/hooks/density-provider.cjs +38 -0
  377. package/dist/hooks/density-provider.cjs.map +1 -0
  378. package/dist/hooks/density-provider.d.ts +20 -0
  379. package/dist/hooks/density-provider.d.ts.map +1 -0
  380. package/dist/hooks/density-provider.js +38 -0
  381. package/dist/hooks/density-provider.js.map +1 -0
  382. package/dist/hooks/theme-provider.cjs +43 -0
  383. package/dist/hooks/theme-provider.cjs.map +1 -0
  384. package/dist/hooks/theme-provider.d.ts +9 -0
  385. package/dist/hooks/theme-provider.d.ts.map +1 -0
  386. package/dist/hooks/theme-provider.js +43 -0
  387. package/dist/hooks/theme-provider.js.map +1 -0
  388. package/dist/hooks/use-density.cjs +8 -37
  389. package/dist/hooks/use-density.cjs.map +1 -1
  390. package/dist/hooks/use-density.d.ts +5 -20
  391. package/dist/hooks/use-density.d.ts.map +1 -1
  392. package/dist/hooks/use-density.js +9 -38
  393. package/dist/hooks/use-density.js.map +1 -1
  394. package/dist/hooks/use-theme.cjs +10 -43
  395. package/dist/hooks/use-theme.cjs.map +1 -1
  396. package/dist/hooks/use-theme.d.ts +6 -9
  397. package/dist/hooks/use-theme.d.ts.map +1 -1
  398. package/dist/hooks/use-theme.js +11 -44
  399. package/dist/hooks/use-theme.js.map +1 -1
  400. package/dist/hooks.cjs +5 -2
  401. package/dist/hooks.cjs.map +1 -1
  402. package/dist/hooks.d.ts +4 -2
  403. package/dist/hooks.d.ts.map +1 -1
  404. package/dist/hooks.js +5 -2
  405. package/dist/hooks.js.map +1 -1
  406. package/dist/icons/changeIconAliases.cjs +13 -13
  407. package/dist/icons/changeIconAliases.cjs.map +1 -1
  408. package/dist/icons/changeIconAliases.d.ts.map +1 -1
  409. package/dist/icons/changeIconAliases.js +13 -13
  410. package/dist/icons/changeIconAliases.js.map +1 -1
  411. package/dist/index.cjs +78 -30
  412. package/dist/index.cjs.map +1 -1
  413. package/dist/index.js +61 -13
  414. package/dist/index.js.map +1 -1
  415. package/dist/overlay/DropdownMenu.cjs +2 -0
  416. package/dist/overlay/DropdownMenu.cjs.map +1 -1
  417. package/dist/overlay/DropdownMenu.d.ts +3 -1
  418. package/dist/overlay/DropdownMenu.d.ts.map +1 -1
  419. package/dist/overlay/DropdownMenu.js +2 -0
  420. package/dist/overlay/DropdownMenu.js.map +1 -1
  421. package/dist/overlay/Modal.cjs +38 -27
  422. package/dist/overlay/Modal.cjs.map +1 -1
  423. package/dist/overlay/Modal.d.ts +8 -2
  424. package/dist/overlay/Modal.d.ts.map +1 -1
  425. package/dist/overlay/Modal.js +38 -27
  426. package/dist/overlay/Modal.js.map +1 -1
  427. package/dist/overlay/modalStack.cjs +35 -0
  428. package/dist/overlay/modalStack.cjs.map +1 -0
  429. package/dist/overlay/modalStack.d.ts +13 -0
  430. package/dist/overlay/modalStack.d.ts.map +1 -0
  431. package/dist/overlay/modalStack.js +35 -0
  432. package/dist/overlay/modalStack.js.map +1 -0
  433. package/dist/rpc/AcceptPicker.cjs +2 -18
  434. package/dist/rpc/AcceptPicker.cjs.map +1 -1
  435. package/dist/rpc/AcceptPicker.d.ts +1 -41
  436. package/dist/rpc/AcceptPicker.d.ts.map +1 -1
  437. package/dist/rpc/AcceptPicker.js +2 -18
  438. package/dist/rpc/AcceptPicker.js.map +1 -1
  439. package/dist/rpc/CommandOutput.cjs +1 -1
  440. package/dist/rpc/CommandOutput.cjs.map +1 -1
  441. package/dist/rpc/CommandOutput.js +1 -1
  442. package/dist/rpc/CommandOutput.js.map +1 -1
  443. package/dist/rpc/EndpointList.cjs +1 -1
  444. package/dist/rpc/EndpointList.cjs.map +1 -1
  445. package/dist/rpc/EndpointList.js +1 -1
  446. package/dist/rpc/EndpointList.js.map +1 -1
  447. package/dist/rpc/FilterForm.cjs +4 -4
  448. package/dist/rpc/FilterForm.cjs.map +1 -1
  449. package/dist/rpc/FilterForm.js +4 -4
  450. package/dist/rpc/FilterForm.js.map +1 -1
  451. package/dist/rpc/OperationCatalog.cjs +38 -60
  452. package/dist/rpc/OperationCatalog.cjs.map +1 -1
  453. package/dist/rpc/OperationCatalog.d.ts +3 -3
  454. package/dist/rpc/OperationCatalog.d.ts.map +1 -1
  455. package/dist/rpc/OperationCatalog.js +40 -62
  456. package/dist/rpc/OperationCatalog.js.map +1 -1
  457. package/dist/rpc/OperationCommandPage.cjs.map +1 -1
  458. package/dist/rpc/OperationCommandPage.d.ts.map +1 -1
  459. package/dist/rpc/OperationCommandPage.js.map +1 -1
  460. package/dist/rpc/accept-options.cjs +20 -0
  461. package/dist/rpc/accept-options.cjs.map +1 -0
  462. package/dist/rpc/accept-options.d.ts +42 -0
  463. package/dist/rpc/accept-options.d.ts.map +1 -0
  464. package/dist/rpc/accept-options.js +20 -0
  465. package/dist/rpc/accept-options.js.map +1 -0
  466. package/dist/rpc/classify.cjs +15 -4
  467. package/dist/rpc/classify.cjs.map +1 -1
  468. package/dist/rpc/classify.d.ts.map +1 -1
  469. package/dist/rpc/classify.js +15 -4
  470. package/dist/rpc/classify.js.map +1 -1
  471. package/dist/rpc/clickyMetadata.cjs +13 -3
  472. package/dist/rpc/clickyMetadata.cjs.map +1 -1
  473. package/dist/rpc/clickyMetadata.d.ts +2 -0
  474. package/dist/rpc/clickyMetadata.d.ts.map +1 -1
  475. package/dist/rpc/clickyMetadata.js +14 -4
  476. package/dist/rpc/clickyMetadata.js.map +1 -1
  477. package/dist/rpc/formMetadata.cjs +5 -3
  478. package/dist/rpc/formMetadata.cjs.map +1 -1
  479. package/dist/rpc/formMetadata.d.ts.map +1 -1
  480. package/dist/rpc/formMetadata.js +5 -3
  481. package/dist/rpc/formMetadata.js.map +1 -1
  482. package/dist/rpc.cjs +3 -2
  483. package/dist/rpc.cjs.map +1 -1
  484. package/dist/rpc.d.ts +2 -1
  485. package/dist/rpc.d.ts.map +1 -1
  486. package/dist/rpc.js +2 -1
  487. package/dist/rpc.js.map +1 -1
  488. package/dist/styles.css +1 -1
  489. package/package.json +16 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheStatsOverview.d.ts","sourceRoot":"","sources":["../../../src/data/cache-browser/CacheStatsOverview.tsx"],"names":[],"mappings":"AAKA,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,EAAE,WAAW,CAAC;IACpB,6EAA6E;IAC7E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,CAAC,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,UAAe,EACf,QAAQ,EACR,SAAS,GACV,EAAE,uBAAuB,2CAiGzB"}
@@ -0,0 +1,126 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { useQuery } from "@tanstack/react-query";
3
+ import { cn } from "../../lib/utils.js";
4
+ import { formatShort, formatBytes, formatDuration } from "../../lib/format.js";
5
+ import { Gauge } from "../Gauge.js";
6
+ import { cacheQueryKeys } from "./api.js";
7
+ import { UiDatabase } from "../../icons/components/UiDatabase.js";
8
+ import { UiMemoryStick } from "../../icons/components/UiMemoryStick.js";
9
+ import { UiClock } from "../../icons/components/UiClock.js";
10
+ function CacheStatsOverview({
11
+ client,
12
+ rootPrefix = "",
13
+ onSelect,
14
+ className
15
+ }) {
16
+ var _a, _b;
17
+ const stats = useQuery({
18
+ queryKey: cacheQueryKeys.stats(client.baseUrl),
19
+ queryFn: () => client.stats()
20
+ });
21
+ const tree = useQuery({
22
+ queryKey: cacheQueryKeys.tree(client.baseUrl, rootPrefix),
23
+ queryFn: () => client.tree(rootPrefix)
24
+ });
25
+ const s = stats.data;
26
+ const hitTotal = ((s == null ? void 0 : s.hits) ?? 0) + ((s == null ? void 0 : s.misses) ?? 0);
27
+ const nodes = ((_a = tree.data) == null ? void 0 : _a.nodes) ?? [];
28
+ const maxKeys = Math.max(1, ...nodes.map((n) => n.keys));
29
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex min-h-0 flex-col gap-density-3 overflow-y-auto p-density-3", className), children: [
30
+ stats.isError && /* @__PURE__ */ jsx(OverviewError, { error: stats.error }),
31
+ (s == null ? void 0 : s.infoError) && /* @__PURE__ */ jsxs("div", { className: "rounded-md border border-yellow-300 bg-yellow-50 px-density-3 py-density-2 text-xs text-yellow-800 dark:border-yellow-700 dark:bg-yellow-950 dark:text-yellow-200", children: [
32
+ "Server stats unavailable: ",
33
+ s.infoError
34
+ ] }),
35
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap gap-density-3", children: [
36
+ /* @__PURE__ */ jsx(
37
+ Gauge,
38
+ {
39
+ label: "Keys",
40
+ icon: UiDatabase,
41
+ value: (s == null ? void 0 : s.keys) ?? 0,
42
+ max: (s == null ? void 0 : s.keys) ?? 0,
43
+ suffix: "",
44
+ subtitle: (s == null ? void 0 : s.keysTruncated) ? "lower bound (scan capped)" : void 0,
45
+ meta: formatShort(s == null ? void 0 : s.keys)
46
+ }
47
+ ),
48
+ !!(s == null ? void 0 : s.usedMemoryBytes) && /* @__PURE__ */ jsx(
49
+ Gauge,
50
+ {
51
+ label: "Memory",
52
+ icon: UiMemoryStick,
53
+ value: s.usedMemoryBytes,
54
+ max: s.maxMemoryBytes || s.usedMemoryBytes,
55
+ suffix: "",
56
+ tone: memoryTone(s.usedMemoryBytes, s.maxMemoryBytes),
57
+ subtitle: s.maxMemoryBytes ? `of ${formatBytes(s.maxMemoryBytes)}` : "no maxmemory",
58
+ meta: formatBytes(s.usedMemoryBytes)
59
+ }
60
+ ),
61
+ hitTotal > 0 && /* @__PURE__ */ jsx(
62
+ Gauge,
63
+ {
64
+ label: "Hit rate",
65
+ value: Math.round(((s == null ? void 0 : s.hits) ?? 0) / hitTotal * 100),
66
+ subtitle: `${formatShort(s == null ? void 0 : s.hits)} hits / ${formatShort(s == null ? void 0 : s.misses)} misses`,
67
+ meta: (s == null ? void 0 : s.evictedKeys) ? `${formatShort(s.evictedKeys)} evicted` : void 0
68
+ }
69
+ ),
70
+ !!(s == null ? void 0 : s.uptimeSeconds) && /* @__PURE__ */ jsx(
71
+ Gauge,
72
+ {
73
+ label: "Uptime",
74
+ icon: UiClock,
75
+ value: s.uptimeSeconds,
76
+ max: s.uptimeSeconds,
77
+ suffix: "",
78
+ subtitle: s.version ? `v${s.version}` : void 0,
79
+ meta: formatDuration(s.uptimeSeconds, { from: "s" })
80
+ }
81
+ )
82
+ ] }),
83
+ /* @__PURE__ */ jsxs("div", { children: [
84
+ /* @__PURE__ */ jsxs("h3", { className: "mb-density-2 text-sm font-semibold", children: [
85
+ "Keys by prefix",
86
+ ((_b = tree.data) == null ? void 0 : _b.truncated) ? " (truncated)" : ""
87
+ ] }),
88
+ tree.isError && /* @__PURE__ */ jsx(OverviewError, { error: tree.error }),
89
+ tree.isLoading && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: "Loading keys…" }),
90
+ /* @__PURE__ */ jsx("div", { className: "flex flex-col", children: nodes.map((node) => /* @__PURE__ */ jsxs(
91
+ "button",
92
+ {
93
+ type: "button",
94
+ onClick: () => onSelect == null ? void 0 : onSelect(node),
95
+ className: "grid grid-cols-[minmax(0,14rem)_minmax(0,1fr)_4rem] items-center gap-density-3 rounded px-density-2 py-density-1 text-left text-sm hover:bg-accent",
96
+ children: [
97
+ /* @__PURE__ */ jsx("span", { className: "truncate font-mono text-xs", children: node.name }),
98
+ /* @__PURE__ */ jsx("span", { className: "h-2 overflow-hidden rounded bg-muted", children: /* @__PURE__ */ jsx(
99
+ "span",
100
+ {
101
+ className: "block h-full bg-primary/60",
102
+ style: { width: `${node.keys / maxKeys * 100}%` }
103
+ }
104
+ ) }),
105
+ /* @__PURE__ */ jsx("span", { className: "text-right text-xs text-muted-foreground", children: formatShort(node.keys) })
106
+ ]
107
+ },
108
+ node.prefix ?? node.key ?? node.name
109
+ )) })
110
+ ] })
111
+ ] });
112
+ }
113
+ function memoryTone(used, max) {
114
+ if (!max) return "neutral";
115
+ const pct = used / max;
116
+ if (pct >= 0.9) return "danger";
117
+ if (pct >= 0.75) return "warning";
118
+ return "success";
119
+ }
120
+ function OverviewError({ error }) {
121
+ return /* @__PURE__ */ jsx("div", { className: "rounded-md border border-red-300 bg-red-50 px-density-3 py-density-2 text-xs text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200", children: error instanceof Error ? error.message : String(error) });
122
+ }
123
+ export {
124
+ CacheStatsOverview
125
+ };
126
+ //# sourceMappingURL=CacheStatsOverview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheStatsOverview.js","sources":["../../../src/data/cache-browser/CacheStatsOverview.tsx"],"sourcesContent":["import { useQuery } from \"@tanstack/react-query\";\nimport { cn } from \"../../lib/utils\";\nimport { formatBytes, formatDuration, formatShort } from \"../../lib/format\";\nimport { Gauge } from \"../Gauge\";\nimport { UiClock, UiDatabase, UiMemoryStick } from \"../../icons\";\nimport { cacheQueryKeys, type CacheClient } from \"./api\";\nimport type { CacheTreeNode } from \"./types\";\n\nexport type CacheStatsOverviewProps = {\n client: CacheClient;\n /** Logical prefix the overview aggregates; matches the tree's rootPrefix. */\n rootPrefix?: string;\n /** Drill into a top-level prefix/key from the breakdown rows. */\n onSelect?: (node: CacheTreeNode) => void;\n className?: string;\n};\n\n/**\n * Whole-keyspace overview: server stats (memory, hit rate, uptime) plus a\n * keys-per-prefix breakdown of the top tree level. Shown when nothing is\n * selected in the browser.\n */\nexport function CacheStatsOverview({\n client,\n rootPrefix = \"\",\n onSelect,\n className,\n}: CacheStatsOverviewProps) {\n const stats = useQuery({\n queryKey: cacheQueryKeys.stats(client.baseUrl),\n queryFn: () => client.stats(),\n });\n const tree = useQuery({\n queryKey: cacheQueryKeys.tree(client.baseUrl, rootPrefix),\n queryFn: () => client.tree(rootPrefix),\n });\n\n const s = stats.data;\n const hitTotal = (s?.hits ?? 0) + (s?.misses ?? 0);\n const nodes = tree.data?.nodes ?? [];\n const maxKeys = Math.max(1, ...nodes.map((n) => n.keys));\n\n return (\n <div className={cn(\"flex min-h-0 flex-col gap-density-3 overflow-y-auto p-density-3\", className)}>\n {stats.isError && <OverviewError error={stats.error} />}\n {s?.infoError && (\n <div className=\"rounded-md border border-yellow-300 bg-yellow-50 px-density-3 py-density-2 text-xs text-yellow-800 dark:border-yellow-700 dark:bg-yellow-950 dark:text-yellow-200\">\n Server stats unavailable: {s.infoError}\n </div>\n )}\n\n <div className=\"flex flex-wrap gap-density-3\">\n <Gauge\n label=\"Keys\"\n icon={UiDatabase}\n value={s?.keys ?? 0}\n max={s?.keys ?? 0}\n suffix=\"\"\n subtitle={s?.keysTruncated ? \"lower bound (scan capped)\" : undefined}\n meta={formatShort(s?.keys)}\n />\n {!!s?.usedMemoryBytes && (\n <Gauge\n label=\"Memory\"\n icon={UiMemoryStick}\n value={s.usedMemoryBytes}\n max={s.maxMemoryBytes || s.usedMemoryBytes}\n suffix=\"\"\n tone={memoryTone(s.usedMemoryBytes, s.maxMemoryBytes)}\n subtitle={s.maxMemoryBytes ? `of ${formatBytes(s.maxMemoryBytes)}` : \"no maxmemory\"}\n meta={formatBytes(s.usedMemoryBytes)}\n />\n )}\n {hitTotal > 0 && (\n <Gauge\n label=\"Hit rate\"\n value={Math.round(((s?.hits ?? 0) / hitTotal) * 100)}\n subtitle={`${formatShort(s?.hits)} hits / ${formatShort(s?.misses)} misses`}\n meta={s?.evictedKeys ? `${formatShort(s.evictedKeys)} evicted` : undefined}\n />\n )}\n {!!s?.uptimeSeconds && (\n <Gauge\n label=\"Uptime\"\n icon={UiClock}\n value={s.uptimeSeconds}\n max={s.uptimeSeconds}\n suffix=\"\"\n subtitle={s.version ? `v${s.version}` : undefined}\n meta={formatDuration(s.uptimeSeconds, { from: \"s\" })}\n />\n )}\n </div>\n\n <div>\n <h3 className=\"mb-density-2 text-sm font-semibold\">\n Keys by prefix{tree.data?.truncated ? \" (truncated)\" : \"\"}\n </h3>\n {tree.isError && <OverviewError error={tree.error} />}\n {tree.isLoading && <div className=\"text-sm text-muted-foreground\">Loading keys…</div>}\n <div className=\"flex flex-col\">\n {nodes.map((node) => (\n <button\n key={node.prefix ?? node.key ?? node.name}\n type=\"button\"\n onClick={() => onSelect?.(node)}\n className=\"grid grid-cols-[minmax(0,14rem)_minmax(0,1fr)_4rem] items-center gap-density-3 rounded px-density-2 py-density-1 text-left text-sm hover:bg-accent\"\n >\n <span className=\"truncate font-mono text-xs\">{node.name}</span>\n <span className=\"h-2 overflow-hidden rounded bg-muted\">\n <span\n className=\"block h-full bg-primary/60\"\n style={{ width: `${(node.keys / maxKeys) * 100}%` }}\n />\n </span>\n <span className=\"text-right text-xs text-muted-foreground\">\n {formatShort(node.keys)}\n </span>\n </button>\n ))}\n </div>\n </div>\n </div>\n );\n}\n\nfunction memoryTone(used: number, max?: number) {\n if (!max) return \"neutral\" as const;\n const pct = used / max;\n if (pct >= 0.9) return \"danger\" as const;\n if (pct >= 0.75) return \"warning\" as const;\n return \"success\" as const;\n}\n\nfunction OverviewError({ error }: { error: unknown }) {\n return (\n <div className=\"rounded-md border border-red-300 bg-red-50 px-density-3 py-density-2 text-xs text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200\">\n {error instanceof Error ? error.message : String(error)}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const reactQuery = require("@tanstack/react-query");
6
+ const utils = require("../../lib/utils.cjs");
7
+ const format = require("../../lib/format.cjs");
8
+ const Icon = require("../Icon.cjs");
9
+ const Tree = require("../Tree.cjs");
10
+ const api = require("./api.cjs");
11
+ const types = require("./types.cjs");
12
+ const UiLayers = require("../../icons/components/UiLayers.cjs");
13
+ const UiTag = require("../../icons/components/UiTag.cjs");
14
+ const UiListFlat = require("../../icons/components/UiListFlat.cjs");
15
+ const UiBraces = require("../../icons/components/UiBraces.cjs");
16
+ const UiFileText = require("../../icons/components/UiFileText.cjs");
17
+ const UiKey = require("../../icons/components/UiKey.cjs");
18
+ const UiFolder = require("../../icons/components/UiFolder.cjs");
19
+ const UiSearch = require("../../icons/components/UiSearch.cjs");
20
+ const UiClose = require("../../icons/components/UiClose.cjs");
21
+ const typeIcons = {
22
+ string: UiFileText.UiFileText,
23
+ hash: UiBraces.UiBraces,
24
+ list: UiListFlat.UiListFlat,
25
+ set: UiTag.UiTag,
26
+ zset: UiLayers.UiLayers
27
+ };
28
+ function CacheTree({
29
+ client,
30
+ registry,
31
+ rootPrefix = "",
32
+ selected,
33
+ onSelect,
34
+ className
35
+ }) {
36
+ var _a, _b, _c;
37
+ const [searchInput, setSearchInput] = react.useState("");
38
+ const [search, setSearch] = react.useState("");
39
+ react.useEffect(() => {
40
+ const handle = setTimeout(() => setSearch(searchInput.trim()), 300);
41
+ return () => clearTimeout(handle);
42
+ }, [searchInput]);
43
+ const root = reactQuery.useQuery({
44
+ queryKey: api.cacheQueryKeys.tree(client.baseUrl, rootPrefix),
45
+ queryFn: () => client.tree(rootPrefix)
46
+ });
47
+ const searchResults = reactQuery.useQuery({
48
+ queryKey: api.cacheQueryKeys.search(client.baseUrl, search),
49
+ queryFn: () => client.search(search),
50
+ enabled: search.length > 0
51
+ });
52
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: utils.cn("flex min-h-0 flex-col", className), children: [
53
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "m-density-2 flex items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs shadow-sm", children: [
54
+ /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiSearch.UiSearch, className: "text-xs text-muted-foreground" }),
55
+ /* @__PURE__ */ jsxRuntime.jsx(
56
+ "input",
57
+ {
58
+ type: "search",
59
+ value: searchInput,
60
+ onChange: (e) => setSearchInput(e.target.value),
61
+ placeholder: "Search keys",
62
+ "aria-label": "Search cache keys",
63
+ className: "h-5 w-full border-0 bg-transparent p-0 text-xs outline-none placeholder:text-muted-foreground"
64
+ }
65
+ ),
66
+ searchInput && /* @__PURE__ */ jsxRuntime.jsx(
67
+ "button",
68
+ {
69
+ type: "button",
70
+ onClick: () => setSearchInput(""),
71
+ "aria-label": "Clear key search",
72
+ className: "inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
73
+ children: /* @__PURE__ */ jsxRuntime.jsx(Icon.Icon, { icon: UiClose.UiClose, className: "text-xs" })
74
+ }
75
+ )
76
+ ] }),
77
+ root.isError && /* @__PURE__ */ jsxRuntime.jsx(QueryError, { error: root.error }),
78
+ search ? /* @__PURE__ */ jsxRuntime.jsx(
79
+ SearchResults,
80
+ {
81
+ nodes: ((_a = searchResults.data) == null ? void 0 : _a.keys) ?? [],
82
+ truncated: ((_b = searchResults.data) == null ? void 0 : _b.truncated) ?? false,
83
+ loading: searchResults.isLoading,
84
+ error: searchResults.isError ? searchResults.error : null,
85
+ registry,
86
+ client,
87
+ selected,
88
+ onSelect
89
+ }
90
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
91
+ Tree.Tree,
92
+ {
93
+ roots: ((_c = root.data) == null ? void 0 : _c.nodes) ?? [],
94
+ className: "min-h-0 flex-1",
95
+ empty: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: root.isLoading ? "Loading keys…" : "No keys found." }),
96
+ getKey: (node) => node.prefix ?? node.key ?? node.name,
97
+ getChildren: () => void 0,
98
+ hasMoreChildren: (node) => !types.isLeaf(node),
99
+ loadChildren: async (node) => (await client.tree(node.prefix ?? "")).nodes,
100
+ selected,
101
+ onSelect,
102
+ defaultOpen: () => false,
103
+ getSearchText: (node) => node.name,
104
+ renderRow: ({ node, selected: isSelected, error }) => /* @__PURE__ */ jsxRuntime.jsx(
105
+ CacheNodeRow,
106
+ {
107
+ node,
108
+ selected: isSelected,
109
+ error,
110
+ registry,
111
+ client
112
+ }
113
+ )
114
+ }
115
+ )
116
+ ] });
117
+ }
118
+ function SearchResults({
119
+ nodes,
120
+ truncated,
121
+ loading,
122
+ error,
123
+ registry,
124
+ client,
125
+ selected,
126
+ onSelect
127
+ }) {
128
+ if (error) return /* @__PURE__ */ jsxRuntime.jsx(QueryError, { error });
129
+ if (loading) {
130
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: "Searching…" });
131
+ }
132
+ if (nodes.length === 0) {
133
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: "No matching keys." });
134
+ }
135
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "min-h-0 flex-1 overflow-auto", role: "listbox", "aria-label": "Matching cache keys", children: [
136
+ truncated && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "px-3 py-1 text-xs text-muted-foreground", children: [
137
+ "Showing the first ",
138
+ nodes.length,
139
+ " matches — refine the search to narrow down."
140
+ ] }),
141
+ nodes.map((node) => /* @__PURE__ */ jsxRuntime.jsx(
142
+ "button",
143
+ {
144
+ type: "button",
145
+ role: "option",
146
+ "aria-selected": (selected == null ? void 0 : selected.key) === node.key,
147
+ onClick: () => onSelect(node),
148
+ className: utils.cn(
149
+ "flex w-full items-center gap-1.5 px-2 py-1 text-left text-sm",
150
+ (selected == null ? void 0 : selected.key) === node.key ? "border-l-2 border-primary bg-primary/10" : "hover:bg-accent"
151
+ ),
152
+ children: /* @__PURE__ */ jsxRuntime.jsx(CacheNodeRow, { node, selected: (selected == null ? void 0 : selected.key) === node.key, registry, client })
153
+ },
154
+ node.key ?? node.name
155
+ ))
156
+ ] });
157
+ }
158
+ function CacheNodeRow({
159
+ node,
160
+ selected: _selected,
161
+ error,
162
+ registry,
163
+ client
164
+ }) {
165
+ const adapter = registry.resolveRowIcon(node, null);
166
+ const icon = adapter ? adapter.renderRowIcon({ node, detail: null, client }) : /* @__PURE__ */ jsxRuntime.jsx(
167
+ Icon.Icon,
168
+ {
169
+ icon: types.isLeaf(node) ? typeIcons[node.type ?? ""] ?? UiKey.UiKey : UiFolder.UiFolder,
170
+ className: "shrink-0 text-xs text-muted-foreground"
171
+ }
172
+ );
173
+ return /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: [
174
+ icon,
175
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "truncate font-mono text-xs", children: node.name }),
176
+ !types.isLeaf(node) && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "ml-auto flex shrink-0 items-center gap-1.5 text-[10px] text-muted-foreground", children: [
177
+ node.bytes ? /* @__PURE__ */ jsxRuntime.jsx("span", { children: format.formatBytes(node.bytes) }) : null,
178
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "rounded-full bg-muted px-1.5", children: format.formatShort(node.keys) })
179
+ ] }),
180
+ types.isLeaf(node) && node.bytes ? /* @__PURE__ */ jsxRuntime.jsx("span", { className: "ml-auto shrink-0 text-[10px] text-muted-foreground", children: format.formatBytes(node.bytes) }) : null,
181
+ error != null && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "shrink-0 text-[10px] text-red-600 dark:text-red-400", children: "load failed" })
182
+ ] });
183
+ }
184
+ function QueryError({ error }) {
185
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "m-density-2 rounded-md border border-red-300 bg-red-50 px-density-3 py-density-2 text-xs text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200", children: error instanceof Error ? error.message : String(error) });
186
+ }
187
+ exports.CacheNodeRow = CacheNodeRow;
188
+ exports.CacheTree = CacheTree;
189
+ //# sourceMappingURL=CacheTree.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheTree.cjs","sources":["../../../src/data/cache-browser/CacheTree.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { cn } from \"../../lib/utils\";\nimport { formatBytes, formatShort } from \"../../lib/format\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport {\n UiBraces,\n UiClose,\n UiFileText,\n UiFolder,\n UiKey,\n UiLayers,\n UiListFlat,\n UiSearch,\n UiTag,\n} from \"../../icons\";\nimport { Tree } from \"../Tree\";\nimport { cacheQueryKeys, type CacheClient } from \"./api\";\nimport type { CacheAdapterRegistry } from \"./adapter\";\nimport { isLeaf, type CacheTreeNode } from \"./types\";\n\nconst typeIcons: Record<string, StaticIconComponent> = {\n string: UiFileText,\n hash: UiBraces,\n list: UiListFlat,\n set: UiTag,\n zset: UiLayers,\n};\n\nexport type CacheTreeProps = {\n client: CacheClient;\n registry: CacheAdapterRegistry;\n /** Logical prefix the tree is rooted at; empty browses the whole keyspace. */\n rootPrefix?: string;\n selected: CacheTreeNode | null;\n onSelect: (node: CacheTreeNode | null) => void;\n className?: string;\n};\n\n/**\n * Lazy key tree over the cache-browser tree endpoint, with a server-side\n * substring search that swaps the tree for a flat result list while active.\n * (The tree's own toolbar filter still narrows already-loaded nodes.)\n */\nexport function CacheTree({\n client,\n registry,\n rootPrefix = \"\",\n selected,\n onSelect,\n className,\n}: CacheTreeProps) {\n const [searchInput, setSearchInput] = useState(\"\");\n const [search, setSearch] = useState(\"\");\n useEffect(() => {\n const handle = setTimeout(() => setSearch(searchInput.trim()), 300);\n return () => clearTimeout(handle);\n }, [searchInput]);\n\n const root = useQuery({\n queryKey: cacheQueryKeys.tree(client.baseUrl, rootPrefix),\n queryFn: () => client.tree(rootPrefix),\n });\n\n const searchResults = useQuery({\n queryKey: cacheQueryKeys.search(client.baseUrl, search),\n queryFn: () => client.search(search),\n enabled: search.length > 0,\n });\n\n return (\n <div className={cn(\"flex min-h-0 flex-col\", className)}>\n <label className=\"m-density-2 flex items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs shadow-sm\">\n <Icon icon={UiSearch} className=\"text-xs text-muted-foreground\" />\n <input\n type=\"search\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder=\"Search keys\"\n aria-label=\"Search cache keys\"\n className=\"h-5 w-full border-0 bg-transparent p-0 text-xs outline-none placeholder:text-muted-foreground\"\n />\n {searchInput && (\n <button\n type=\"button\"\n onClick={() => setSearchInput(\"\")}\n aria-label=\"Clear key search\"\n className=\"inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n </label>\n\n {root.isError && <QueryError error={root.error} />}\n\n {search ? (\n <SearchResults\n nodes={searchResults.data?.keys ?? []}\n truncated={searchResults.data?.truncated ?? false}\n loading={searchResults.isLoading}\n error={searchResults.isError ? searchResults.error : null}\n registry={registry}\n client={client}\n selected={selected}\n onSelect={onSelect}\n />\n ) : (\n <Tree<CacheTreeNode>\n roots={root.data?.nodes ?? []}\n className=\"min-h-0 flex-1\"\n empty={\n <div className=\"px-3 py-4 text-sm text-muted-foreground\">\n {root.isLoading ? \"Loading keys…\" : \"No keys found.\"}\n </div>\n }\n getKey={(node) => node.prefix ?? node.key ?? node.name}\n getChildren={() => undefined}\n hasMoreChildren={(node) => !isLeaf(node)}\n loadChildren={async (node) => (await client.tree(node.prefix ?? \"\")).nodes}\n selected={selected}\n onSelect={onSelect}\n defaultOpen={() => false}\n getSearchText={(node) => node.name}\n renderRow={({ node, selected: isSelected, error }) => (\n <CacheNodeRow\n node={node}\n selected={isSelected}\n error={error}\n registry={registry}\n client={client}\n />\n )}\n />\n )}\n </div>\n );\n}\n\nfunction SearchResults({\n nodes,\n truncated,\n loading,\n error,\n registry,\n client,\n selected,\n onSelect,\n}: {\n nodes: CacheTreeNode[];\n truncated: boolean;\n loading: boolean;\n error: unknown;\n registry: CacheAdapterRegistry;\n client: CacheClient;\n selected: CacheTreeNode | null;\n onSelect: (node: CacheTreeNode) => void;\n}) {\n if (error) return <QueryError error={error} />;\n if (loading) {\n return <div className=\"px-3 py-4 text-sm text-muted-foreground\">Searching…</div>;\n }\n if (nodes.length === 0) {\n return <div className=\"px-3 py-4 text-sm text-muted-foreground\">No matching keys.</div>;\n }\n return (\n <div className=\"min-h-0 flex-1 overflow-auto\" role=\"listbox\" aria-label=\"Matching cache keys\">\n {truncated && (\n <div className=\"px-3 py-1 text-xs text-muted-foreground\">\n Showing the first {nodes.length} matches — refine the search to narrow down.\n </div>\n )}\n {nodes.map((node) => (\n <button\n key={node.key ?? node.name}\n type=\"button\"\n role=\"option\"\n aria-selected={selected?.key === node.key}\n onClick={() => onSelect(node)}\n className={cn(\n \"flex w-full items-center gap-1.5 px-2 py-1 text-left text-sm\",\n selected?.key === node.key\n ? \"border-l-2 border-primary bg-primary/10\"\n : \"hover:bg-accent\",\n )}\n >\n <CacheNodeRow node={node} selected={selected?.key === node.key} registry={registry} client={client} />\n </button>\n ))}\n </div>\n );\n}\n\n/** Shared row body: adapter icon (or type/folder icon), name and size hints. */\nexport function CacheNodeRow({\n node,\n selected: _selected,\n error,\n registry,\n client,\n}: {\n node: CacheTreeNode;\n selected: boolean;\n error?: unknown;\n registry: CacheAdapterRegistry;\n client: CacheClient;\n}) {\n const adapter = registry.resolveRowIcon(node, null);\n const icon = adapter ? (\n adapter.renderRowIcon!({ node, detail: null, client })\n ) : (\n <Icon\n icon={isLeaf(node) ? (typeIcons[node.type ?? \"\"] ?? UiKey) : UiFolder}\n className=\"shrink-0 text-xs text-muted-foreground\"\n />\n );\n return (\n <span className=\"flex min-w-0 flex-1 items-center gap-1.5\">\n {icon}\n <span className=\"truncate font-mono text-xs\">{node.name}</span>\n {!isLeaf(node) && (\n <span className=\"ml-auto flex shrink-0 items-center gap-1.5 text-[10px] text-muted-foreground\">\n {node.bytes ? <span>{formatBytes(node.bytes)}</span> : null}\n <span className=\"rounded-full bg-muted px-1.5\">\n {formatShort(node.keys)}\n </span>\n </span>\n )}\n {isLeaf(node) && node.bytes ? (\n <span className=\"ml-auto shrink-0 text-[10px] text-muted-foreground\">\n {formatBytes(node.bytes)}\n </span>\n ) : null}\n {error != null && (\n <span className=\"shrink-0 text-[10px] text-red-600 dark:text-red-400\">\n load failed\n </span>\n )}\n </span>\n );\n}\n\nfunction QueryError({ error }: { error: unknown }) {\n return (\n <div className=\"m-density-2 rounded-md border border-red-300 bg-red-50 px-density-3 py-density-2 text-xs text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200\">\n {error instanceof Error ? error.message : String(error)}\n </div>\n );\n}\n"],"names":["UiFileText","UiBraces","UiListFlat","UiTag","UiLayers","useState","useEffect","useQuery","cacheQueryKeys","cn","jsxs","jsx","Icon","UiSearch","UiClose","Tree","isLeaf","UiKey","UiFolder","formatShort","formatBytes"],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { CacheClient } from './api';
2
+ import { CacheAdapterRegistry } from './adapter';
3
+ import { CacheTreeNode } from './types';
4
+ export type CacheTreeProps = {
5
+ client: CacheClient;
6
+ registry: CacheAdapterRegistry;
7
+ /** Logical prefix the tree is rooted at; empty browses the whole keyspace. */
8
+ rootPrefix?: string;
9
+ selected: CacheTreeNode | null;
10
+ onSelect: (node: CacheTreeNode | null) => void;
11
+ className?: string;
12
+ };
13
+ /**
14
+ * Lazy key tree over the cache-browser tree endpoint, with a server-side
15
+ * substring search that swaps the tree for a flat result list while active.
16
+ * (The tree's own toolbar filter still narrows already-loaded nodes.)
17
+ */
18
+ export declare function CacheTree({ client, registry, rootPrefix, selected, onSelect, className, }: CacheTreeProps): import("react/jsx-runtime").JSX.Element;
19
+ /** Shared row body: adapter icon (or type/folder icon), name and size hints. */
20
+ export declare function CacheNodeRow({ node, selected: _selected, error, registry, client, }: {
21
+ node: CacheTreeNode;
22
+ selected: boolean;
23
+ error?: unknown;
24
+ registry: CacheAdapterRegistry;
25
+ client: CacheClient;
26
+ }): import("react/jsx-runtime").JSX.Element;
27
+ //# sourceMappingURL=CacheTree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheTree.d.ts","sourceRoot":"","sources":["../../../src/data/cache-browser/CacheTree.tsx"],"names":[],"mappings":"AAiBA,OAAO,EAAkB,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAU,KAAK,aAAa,EAAE,MAAM,SAAS,CAAC;AAUrD,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,8EAA8E;IAC9E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,aAAa,GAAG,IAAI,CAAC;IAC/B,QAAQ,EAAE,CAAC,IAAI,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;IAC/C,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,QAAQ,EACR,UAAe,EACf,QAAQ,EACR,QAAQ,EACR,SAAS,GACV,EAAE,cAAc,2CAsFhB;AAwDD,gFAAgF;AAChF,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,QAAQ,EAAE,SAAS,EACnB,KAAK,EACL,QAAQ,EACR,MAAM,GACP,EAAE;IACD,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,MAAM,EAAE,WAAW,CAAC;CACrB,2CAkCA"}
@@ -0,0 +1,189 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useState, useEffect } from "react";
3
+ import { useQuery } from "@tanstack/react-query";
4
+ import { cn } from "../../lib/utils.js";
5
+ import { formatBytes, formatShort } from "../../lib/format.js";
6
+ import { Icon } from "../Icon.js";
7
+ import { Tree } from "../Tree.js";
8
+ import { cacheQueryKeys } from "./api.js";
9
+ import { isLeaf } from "./types.js";
10
+ import { UiLayers } from "../../icons/components/UiLayers.js";
11
+ import { UiTag } from "../../icons/components/UiTag.js";
12
+ import { UiListFlat } from "../../icons/components/UiListFlat.js";
13
+ import { UiBraces } from "../../icons/components/UiBraces.js";
14
+ import { UiFileText } from "../../icons/components/UiFileText.js";
15
+ import { UiKey } from "../../icons/components/UiKey.js";
16
+ import { UiFolder } from "../../icons/components/UiFolder.js";
17
+ import { UiSearch } from "../../icons/components/UiSearch.js";
18
+ import { UiClose } from "../../icons/components/UiClose.js";
19
+ const typeIcons = {
20
+ string: UiFileText,
21
+ hash: UiBraces,
22
+ list: UiListFlat,
23
+ set: UiTag,
24
+ zset: UiLayers
25
+ };
26
+ function CacheTree({
27
+ client,
28
+ registry,
29
+ rootPrefix = "",
30
+ selected,
31
+ onSelect,
32
+ className
33
+ }) {
34
+ var _a, _b, _c;
35
+ const [searchInput, setSearchInput] = useState("");
36
+ const [search, setSearch] = useState("");
37
+ useEffect(() => {
38
+ const handle = setTimeout(() => setSearch(searchInput.trim()), 300);
39
+ return () => clearTimeout(handle);
40
+ }, [searchInput]);
41
+ const root = useQuery({
42
+ queryKey: cacheQueryKeys.tree(client.baseUrl, rootPrefix),
43
+ queryFn: () => client.tree(rootPrefix)
44
+ });
45
+ const searchResults = useQuery({
46
+ queryKey: cacheQueryKeys.search(client.baseUrl, search),
47
+ queryFn: () => client.search(search),
48
+ enabled: search.length > 0
49
+ });
50
+ return /* @__PURE__ */ jsxs("div", { className: cn("flex min-h-0 flex-col", className), children: [
51
+ /* @__PURE__ */ jsxs("label", { className: "m-density-2 flex items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs shadow-sm", children: [
52
+ /* @__PURE__ */ jsx(Icon, { icon: UiSearch, className: "text-xs text-muted-foreground" }),
53
+ /* @__PURE__ */ jsx(
54
+ "input",
55
+ {
56
+ type: "search",
57
+ value: searchInput,
58
+ onChange: (e) => setSearchInput(e.target.value),
59
+ placeholder: "Search keys",
60
+ "aria-label": "Search cache keys",
61
+ className: "h-5 w-full border-0 bg-transparent p-0 text-xs outline-none placeholder:text-muted-foreground"
62
+ }
63
+ ),
64
+ searchInput && /* @__PURE__ */ jsx(
65
+ "button",
66
+ {
67
+ type: "button",
68
+ onClick: () => setSearchInput(""),
69
+ "aria-label": "Clear key search",
70
+ className: "inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground",
71
+ children: /* @__PURE__ */ jsx(Icon, { icon: UiClose, className: "text-xs" })
72
+ }
73
+ )
74
+ ] }),
75
+ root.isError && /* @__PURE__ */ jsx(QueryError, { error: root.error }),
76
+ search ? /* @__PURE__ */ jsx(
77
+ SearchResults,
78
+ {
79
+ nodes: ((_a = searchResults.data) == null ? void 0 : _a.keys) ?? [],
80
+ truncated: ((_b = searchResults.data) == null ? void 0 : _b.truncated) ?? false,
81
+ loading: searchResults.isLoading,
82
+ error: searchResults.isError ? searchResults.error : null,
83
+ registry,
84
+ client,
85
+ selected,
86
+ onSelect
87
+ }
88
+ ) : /* @__PURE__ */ jsx(
89
+ Tree,
90
+ {
91
+ roots: ((_c = root.data) == null ? void 0 : _c.nodes) ?? [],
92
+ className: "min-h-0 flex-1",
93
+ empty: /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: root.isLoading ? "Loading keys…" : "No keys found." }),
94
+ getKey: (node) => node.prefix ?? node.key ?? node.name,
95
+ getChildren: () => void 0,
96
+ hasMoreChildren: (node) => !isLeaf(node),
97
+ loadChildren: async (node) => (await client.tree(node.prefix ?? "")).nodes,
98
+ selected,
99
+ onSelect,
100
+ defaultOpen: () => false,
101
+ getSearchText: (node) => node.name,
102
+ renderRow: ({ node, selected: isSelected, error }) => /* @__PURE__ */ jsx(
103
+ CacheNodeRow,
104
+ {
105
+ node,
106
+ selected: isSelected,
107
+ error,
108
+ registry,
109
+ client
110
+ }
111
+ )
112
+ }
113
+ )
114
+ ] });
115
+ }
116
+ function SearchResults({
117
+ nodes,
118
+ truncated,
119
+ loading,
120
+ error,
121
+ registry,
122
+ client,
123
+ selected,
124
+ onSelect
125
+ }) {
126
+ if (error) return /* @__PURE__ */ jsx(QueryError, { error });
127
+ if (loading) {
128
+ return /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: "Searching…" });
129
+ }
130
+ if (nodes.length === 0) {
131
+ return /* @__PURE__ */ jsx("div", { className: "px-3 py-4 text-sm text-muted-foreground", children: "No matching keys." });
132
+ }
133
+ return /* @__PURE__ */ jsxs("div", { className: "min-h-0 flex-1 overflow-auto", role: "listbox", "aria-label": "Matching cache keys", children: [
134
+ truncated && /* @__PURE__ */ jsxs("div", { className: "px-3 py-1 text-xs text-muted-foreground", children: [
135
+ "Showing the first ",
136
+ nodes.length,
137
+ " matches — refine the search to narrow down."
138
+ ] }),
139
+ nodes.map((node) => /* @__PURE__ */ jsx(
140
+ "button",
141
+ {
142
+ type: "button",
143
+ role: "option",
144
+ "aria-selected": (selected == null ? void 0 : selected.key) === node.key,
145
+ onClick: () => onSelect(node),
146
+ className: cn(
147
+ "flex w-full items-center gap-1.5 px-2 py-1 text-left text-sm",
148
+ (selected == null ? void 0 : selected.key) === node.key ? "border-l-2 border-primary bg-primary/10" : "hover:bg-accent"
149
+ ),
150
+ children: /* @__PURE__ */ jsx(CacheNodeRow, { node, selected: (selected == null ? void 0 : selected.key) === node.key, registry, client })
151
+ },
152
+ node.key ?? node.name
153
+ ))
154
+ ] });
155
+ }
156
+ function CacheNodeRow({
157
+ node,
158
+ selected: _selected,
159
+ error,
160
+ registry,
161
+ client
162
+ }) {
163
+ const adapter = registry.resolveRowIcon(node, null);
164
+ const icon = adapter ? adapter.renderRowIcon({ node, detail: null, client }) : /* @__PURE__ */ jsx(
165
+ Icon,
166
+ {
167
+ icon: isLeaf(node) ? typeIcons[node.type ?? ""] ?? UiKey : UiFolder,
168
+ className: "shrink-0 text-xs text-muted-foreground"
169
+ }
170
+ );
171
+ return /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-1 items-center gap-1.5", children: [
172
+ icon,
173
+ /* @__PURE__ */ jsx("span", { className: "truncate font-mono text-xs", children: node.name }),
174
+ !isLeaf(node) && /* @__PURE__ */ jsxs("span", { className: "ml-auto flex shrink-0 items-center gap-1.5 text-[10px] text-muted-foreground", children: [
175
+ node.bytes ? /* @__PURE__ */ jsx("span", { children: formatBytes(node.bytes) }) : null,
176
+ /* @__PURE__ */ jsx("span", { className: "rounded-full bg-muted px-1.5", children: formatShort(node.keys) })
177
+ ] }),
178
+ isLeaf(node) && node.bytes ? /* @__PURE__ */ jsx("span", { className: "ml-auto shrink-0 text-[10px] text-muted-foreground", children: formatBytes(node.bytes) }) : null,
179
+ error != null && /* @__PURE__ */ jsx("span", { className: "shrink-0 text-[10px] text-red-600 dark:text-red-400", children: "load failed" })
180
+ ] });
181
+ }
182
+ function QueryError({ error }) {
183
+ return /* @__PURE__ */ jsx("div", { className: "m-density-2 rounded-md border border-red-300 bg-red-50 px-density-3 py-density-2 text-xs text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200", children: error instanceof Error ? error.message : String(error) });
184
+ }
185
+ export {
186
+ CacheNodeRow,
187
+ CacheTree
188
+ };
189
+ //# sourceMappingURL=CacheTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CacheTree.js","sources":["../../../src/data/cache-browser/CacheTree.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { cn } from \"../../lib/utils\";\nimport { formatBytes, formatShort } from \"../../lib/format\";\nimport { Icon, type StaticIconComponent } from \"../Icon\";\nimport {\n UiBraces,\n UiClose,\n UiFileText,\n UiFolder,\n UiKey,\n UiLayers,\n UiListFlat,\n UiSearch,\n UiTag,\n} from \"../../icons\";\nimport { Tree } from \"../Tree\";\nimport { cacheQueryKeys, type CacheClient } from \"./api\";\nimport type { CacheAdapterRegistry } from \"./adapter\";\nimport { isLeaf, type CacheTreeNode } from \"./types\";\n\nconst typeIcons: Record<string, StaticIconComponent> = {\n string: UiFileText,\n hash: UiBraces,\n list: UiListFlat,\n set: UiTag,\n zset: UiLayers,\n};\n\nexport type CacheTreeProps = {\n client: CacheClient;\n registry: CacheAdapterRegistry;\n /** Logical prefix the tree is rooted at; empty browses the whole keyspace. */\n rootPrefix?: string;\n selected: CacheTreeNode | null;\n onSelect: (node: CacheTreeNode | null) => void;\n className?: string;\n};\n\n/**\n * Lazy key tree over the cache-browser tree endpoint, with a server-side\n * substring search that swaps the tree for a flat result list while active.\n * (The tree's own toolbar filter still narrows already-loaded nodes.)\n */\nexport function CacheTree({\n client,\n registry,\n rootPrefix = \"\",\n selected,\n onSelect,\n className,\n}: CacheTreeProps) {\n const [searchInput, setSearchInput] = useState(\"\");\n const [search, setSearch] = useState(\"\");\n useEffect(() => {\n const handle = setTimeout(() => setSearch(searchInput.trim()), 300);\n return () => clearTimeout(handle);\n }, [searchInput]);\n\n const root = useQuery({\n queryKey: cacheQueryKeys.tree(client.baseUrl, rootPrefix),\n queryFn: () => client.tree(rootPrefix),\n });\n\n const searchResults = useQuery({\n queryKey: cacheQueryKeys.search(client.baseUrl, search),\n queryFn: () => client.search(search),\n enabled: search.length > 0,\n });\n\n return (\n <div className={cn(\"flex min-h-0 flex-col\", className)}>\n <label className=\"m-density-2 flex items-center gap-2 rounded-md border border-border bg-background px-2 py-1 text-xs shadow-sm\">\n <Icon icon={UiSearch} className=\"text-xs text-muted-foreground\" />\n <input\n type=\"search\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n placeholder=\"Search keys\"\n aria-label=\"Search cache keys\"\n className=\"h-5 w-full border-0 bg-transparent p-0 text-xs outline-none placeholder:text-muted-foreground\"\n />\n {searchInput && (\n <button\n type=\"button\"\n onClick={() => setSearchInput(\"\")}\n aria-label=\"Clear key search\"\n className=\"inline-flex items-center rounded p-0.5 text-muted-foreground hover:bg-accent hover:text-accent-foreground\"\n >\n <Icon icon={UiClose} className=\"text-xs\" />\n </button>\n )}\n </label>\n\n {root.isError && <QueryError error={root.error} />}\n\n {search ? (\n <SearchResults\n nodes={searchResults.data?.keys ?? []}\n truncated={searchResults.data?.truncated ?? false}\n loading={searchResults.isLoading}\n error={searchResults.isError ? searchResults.error : null}\n registry={registry}\n client={client}\n selected={selected}\n onSelect={onSelect}\n />\n ) : (\n <Tree<CacheTreeNode>\n roots={root.data?.nodes ?? []}\n className=\"min-h-0 flex-1\"\n empty={\n <div className=\"px-3 py-4 text-sm text-muted-foreground\">\n {root.isLoading ? \"Loading keys…\" : \"No keys found.\"}\n </div>\n }\n getKey={(node) => node.prefix ?? node.key ?? node.name}\n getChildren={() => undefined}\n hasMoreChildren={(node) => !isLeaf(node)}\n loadChildren={async (node) => (await client.tree(node.prefix ?? \"\")).nodes}\n selected={selected}\n onSelect={onSelect}\n defaultOpen={() => false}\n getSearchText={(node) => node.name}\n renderRow={({ node, selected: isSelected, error }) => (\n <CacheNodeRow\n node={node}\n selected={isSelected}\n error={error}\n registry={registry}\n client={client}\n />\n )}\n />\n )}\n </div>\n );\n}\n\nfunction SearchResults({\n nodes,\n truncated,\n loading,\n error,\n registry,\n client,\n selected,\n onSelect,\n}: {\n nodes: CacheTreeNode[];\n truncated: boolean;\n loading: boolean;\n error: unknown;\n registry: CacheAdapterRegistry;\n client: CacheClient;\n selected: CacheTreeNode | null;\n onSelect: (node: CacheTreeNode) => void;\n}) {\n if (error) return <QueryError error={error} />;\n if (loading) {\n return <div className=\"px-3 py-4 text-sm text-muted-foreground\">Searching…</div>;\n }\n if (nodes.length === 0) {\n return <div className=\"px-3 py-4 text-sm text-muted-foreground\">No matching keys.</div>;\n }\n return (\n <div className=\"min-h-0 flex-1 overflow-auto\" role=\"listbox\" aria-label=\"Matching cache keys\">\n {truncated && (\n <div className=\"px-3 py-1 text-xs text-muted-foreground\">\n Showing the first {nodes.length} matches — refine the search to narrow down.\n </div>\n )}\n {nodes.map((node) => (\n <button\n key={node.key ?? node.name}\n type=\"button\"\n role=\"option\"\n aria-selected={selected?.key === node.key}\n onClick={() => onSelect(node)}\n className={cn(\n \"flex w-full items-center gap-1.5 px-2 py-1 text-left text-sm\",\n selected?.key === node.key\n ? \"border-l-2 border-primary bg-primary/10\"\n : \"hover:bg-accent\",\n )}\n >\n <CacheNodeRow node={node} selected={selected?.key === node.key} registry={registry} client={client} />\n </button>\n ))}\n </div>\n );\n}\n\n/** Shared row body: adapter icon (or type/folder icon), name and size hints. */\nexport function CacheNodeRow({\n node,\n selected: _selected,\n error,\n registry,\n client,\n}: {\n node: CacheTreeNode;\n selected: boolean;\n error?: unknown;\n registry: CacheAdapterRegistry;\n client: CacheClient;\n}) {\n const adapter = registry.resolveRowIcon(node, null);\n const icon = adapter ? (\n adapter.renderRowIcon!({ node, detail: null, client })\n ) : (\n <Icon\n icon={isLeaf(node) ? (typeIcons[node.type ?? \"\"] ?? UiKey) : UiFolder}\n className=\"shrink-0 text-xs text-muted-foreground\"\n />\n );\n return (\n <span className=\"flex min-w-0 flex-1 items-center gap-1.5\">\n {icon}\n <span className=\"truncate font-mono text-xs\">{node.name}</span>\n {!isLeaf(node) && (\n <span className=\"ml-auto flex shrink-0 items-center gap-1.5 text-[10px] text-muted-foreground\">\n {node.bytes ? <span>{formatBytes(node.bytes)}</span> : null}\n <span className=\"rounded-full bg-muted px-1.5\">\n {formatShort(node.keys)}\n </span>\n </span>\n )}\n {isLeaf(node) && node.bytes ? (\n <span className=\"ml-auto shrink-0 text-[10px] text-muted-foreground\">\n {formatBytes(node.bytes)}\n </span>\n ) : null}\n {error != null && (\n <span className=\"shrink-0 text-[10px] text-red-600 dark:text-red-400\">\n load failed\n </span>\n )}\n </span>\n );\n}\n\nfunction QueryError({ error }: { error: unknown }) {\n return (\n <div className=\"m-density-2 rounded-md border border-red-300 bg-red-50 px-density-3 py-density-2 text-xs text-red-800 dark:border-red-800 dark:bg-red-950 dark:text-red-200\">\n {error instanceof Error ? error.message : String(error)}\n </div>\n );\n}\n"],"names":[],"mappings":"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"}