@mcp-b/react-components 0.16.1 → 0.18.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 (371) hide show
  1. package/dist/{AgentActivity-BNUNrP9O.d.ts → AgentActivity-D2SHSGFX.d.ts} +1 -1
  2. package/dist/{AgentChat-CrlpbvQJ.d.ts → AgentChat-ClxViuUM.d.ts} +4 -29
  3. package/dist/AgentMessageParts-CyD2UB3V.d.ts +46 -0
  4. package/dist/AgentToolRunsContext-BVe4stgw.d.ts +21 -0
  5. package/dist/{Button-FX_hpqxm.d.ts → Button-DLGzHsjc.d.ts} +13 -7
  6. package/dist/{CodeBlock-BmB4Xaqq.js → CodeBlock-Bfp5PAg3.js} +9 -6
  7. package/dist/{CodeBlock-BRajW4QU.d.ts → CodeBlock-gV4kZeCI.d.ts} +2 -9
  8. package/dist/Collapsible-N64ASIQr.d.ts +119 -0
  9. package/dist/{Combobox-B9Fcd6q-.d.ts → Combobox-CYc37s5l.d.ts} +11 -33
  10. package/dist/{FileTree-CkVbIMWV.js → FileTree-3zYtrddG.js} +46 -20
  11. package/dist/{Menu-Bgu-ufb5.d.ts → Menu-L6MZm-7N.d.ts} +15 -56
  12. package/dist/{Message-BkMdE3bS.js → Message-BXtmfc9Q.js} +13 -20
  13. package/dist/{ModelSelector-SlJNgwKY.js → ModelSelector-Cqw_qrUG.js} +18 -25
  14. package/dist/{PromptInput-BWTuXMOD.d.ts → PromptInput-Bdh9pqlo.d.ts} +41 -71
  15. package/dist/{ResponsiveSidebarShell-Dd9DCcBT.d.ts → ResponsiveSidebarShell-CsAh4NyL.d.ts} +1 -0
  16. package/dist/{Select-BeEsefzh.d.ts → Select-B_13gg_J.d.ts} +16 -44
  17. package/dist/{Tabs-3Zc4tb9D.d.ts → Tabs-ColWK-XA.d.ts} +14 -20
  18. package/dist/{ThinkChat-CzC-zNGA.js → ThinkChat-15EhfvYJ.js} +123 -73
  19. package/dist/{ThinkChatActivity-BFQnb2ct.d.ts → ThinkChatActivity-Bzot45kX.d.ts} +9 -4
  20. package/dist/{ThinkChatActivitySummary-BPmu9a-c.d.ts → ThinkChatActivitySummary-D1xOrNrq.d.ts} +1 -1
  21. package/dist/{ThinkChatContext-C3Eb1Xpi.d.ts → ThinkChatContext-DrsZqdaO.d.ts} +1 -1
  22. package/dist/ThinkRecoveryNotice-DFIcG9UX.d.ts +19 -0
  23. package/dist/{Toggle-CAAlNl-M.d.ts → Toggle-JKZ43D5S.d.ts} +2 -2
  24. package/dist/{ToggleGroup-8hPv-b69.d.ts → ToggleGroup-DNd6cDJZ.d.ts} +4 -5
  25. package/dist/Workspace-Jez8ffUj.d.ts +274 -0
  26. package/dist/WorkspaceExplorer-B9dQWNVK.d.ts +32 -0
  27. package/dist/{WorkspaceFile-DOZkPwzu.d.ts → WorkspaceFile-CzyHnESE.d.ts} +1 -1
  28. package/dist/{WorkspaceFileView-rSN_yT0L.js → WorkspaceFileView-C68Ub8S8.js} +121 -128
  29. package/dist/{WorkspaceLink-DIPbXrUM.js → WorkspaceLink-BYYeTQLf.js} +20 -55
  30. package/dist/{WorkspaceLink-DK1DWMHe.d.ts → WorkspaceLink-O-EBKUJ8.d.ts} +6 -9
  31. package/dist/class-names-BiMDVpUo.js +14 -0
  32. package/dist/components/Accordion.d.ts +5 -15
  33. package/dist/components/Accordion.js +16 -10
  34. package/dist/components/Activity.d.ts +5 -10
  35. package/dist/components/Activity.js +2 -2
  36. package/dist/components/AgentActivity.d.ts +1 -1
  37. package/dist/components/AgentActivity.js +4 -5
  38. package/dist/components/AgentActivityPreview.d.ts +9 -9
  39. package/dist/components/AgentActivityPreview.js +8 -12
  40. package/dist/components/AgentAttention.d.ts +2 -2
  41. package/dist/components/AgentAttention.js +1 -1
  42. package/dist/components/AgentChat.d.ts +2 -2
  43. package/dist/components/AgentChat.js +113 -218
  44. package/dist/components/AgentChatMessageEditor.js +3 -3
  45. package/dist/components/AgentChatTurnError.js +2 -2
  46. package/dist/components/AgentConnection.js +4 -4
  47. package/dist/components/AgentMessageParts.d.ts +2 -0
  48. package/dist/components/AgentMessageParts.js +119 -0
  49. package/dist/components/AgentToolDetail.d.ts +57 -0
  50. package/dist/components/AgentToolDetail.js +100 -0
  51. package/dist/components/AgentToolRunsContext.d.ts +2 -0
  52. package/dist/components/AgentToolRunsContext.js +16 -0
  53. package/dist/components/AlertDialog.d.ts +7 -19
  54. package/dist/components/AlertDialog.js +21 -32
  55. package/dist/components/AppTopBar.d.ts +28 -8
  56. package/dist/components/AppTopBar.js +36 -12
  57. package/dist/components/Approval.d.ts +102 -0
  58. package/dist/components/Approval.js +227 -0
  59. package/dist/components/Artifact.d.ts +3 -5
  60. package/dist/components/Artifact.js +7 -5
  61. package/dist/components/Autocomplete.d.ts +11 -33
  62. package/dist/components/Autocomplete.js +23 -30
  63. package/dist/components/Avatar.d.ts +4 -12
  64. package/dist/components/Avatar.js +13 -12
  65. package/dist/components/Badge.js +3 -0
  66. package/dist/components/BrowserLiveView.js +27 -12
  67. package/dist/components/BrowserReplay.js +4 -3
  68. package/dist/components/BrowserRunPanel.js +58 -78
  69. package/dist/components/Button.d.ts +1 -1
  70. package/dist/components/Button.js +14 -16
  71. package/dist/components/Card.d.ts +7 -8
  72. package/dist/components/Card.js +19 -10
  73. package/dist/components/ChainOfThought.d.ts +5 -11
  74. package/dist/components/ChainOfThought.js +3 -2
  75. package/dist/components/ChatGptSignInScreen.js +8 -8
  76. package/dist/components/Checkbox.d.ts +2 -4
  77. package/dist/components/Checkbox.js +6 -5
  78. package/dist/components/CheckboxGroup.d.ts +1 -3
  79. package/dist/components/CheckboxGroup.js +15 -14
  80. package/dist/components/Checkpoint.d.ts +64 -0
  81. package/dist/components/Checkpoint.js +63 -0
  82. package/dist/components/CodeBlock.d.ts +1 -1
  83. package/dist/components/CodeBlock.js +1 -1
  84. package/dist/components/CodexModelSelector.d.ts +1 -1
  85. package/dist/components/CodexModelSelector.js +2 -2
  86. package/dist/components/Collapsible.d.ts +1 -124
  87. package/dist/components/Collapsible.js +7 -10
  88. package/dist/components/Combobox.d.ts +1 -1
  89. package/dist/components/Combobox.js +23 -30
  90. package/dist/components/Commit.d.ts +5 -11
  91. package/dist/components/Commit.js +6 -5
  92. package/dist/components/Context.js +1 -1
  93. package/dist/components/ContextMenu.d.ts +21 -37
  94. package/dist/components/ContextMenu.js +34 -51
  95. package/dist/components/Conversation.d.ts +3 -5
  96. package/dist/components/Conversation.js +5 -4
  97. package/dist/components/DescriptionListParts.js +1 -1
  98. package/dist/components/Dialog.d.ts +6 -17
  99. package/dist/components/Dialog.js +17 -24
  100. package/dist/components/EnvironmentVariables.d.ts +1 -1
  101. package/dist/components/EnvironmentVariables.js +4 -3
  102. package/dist/components/Field.d.ts +17 -20
  103. package/dist/components/Field.js +20 -17
  104. package/dist/components/Fieldset.d.ts +2 -7
  105. package/dist/components/Fieldset.js +7 -6
  106. package/dist/components/FileTree.d.ts +6 -0
  107. package/dist/components/FileTree.js +1 -1
  108. package/dist/components/Form.d.ts +1 -4
  109. package/dist/components/Form.js +3 -2
  110. package/dist/components/GithubMotionMark.js +1 -1
  111. package/dist/components/IconButton.d.ts +2 -3
  112. package/dist/components/IconButton.js +2 -1
  113. package/dist/components/InlineCitation.d.ts +66 -0
  114. package/dist/components/InlineCitation.js +142 -0
  115. package/dist/components/Input.d.ts +1 -4
  116. package/dist/components/Input.js +3 -2
  117. package/dist/components/Marker.js +1 -1
  118. package/dist/components/McpConnectionRequest.js +2 -2
  119. package/dist/components/McpServerPicker.d.ts +1 -1
  120. package/dist/components/McpServerPicker.js +6 -5
  121. package/dist/components/MediaPreviewCard.d.ts +103 -0
  122. package/dist/components/MediaPreviewCard.js +193 -0
  123. package/dist/components/Menu.d.ts +1 -1
  124. package/dist/components/Menu.js +33 -52
  125. package/dist/components/Menubar.d.ts +22 -43
  126. package/dist/components/Menubar.js +36 -53
  127. package/dist/components/Message.d.ts +7 -7
  128. package/dist/components/Message.js +1 -1
  129. package/dist/components/MessageScroller.d.ts +2 -2
  130. package/dist/components/MessageScroller.js +6 -5
  131. package/dist/components/Meter.d.ts +5 -20
  132. package/dist/components/Meter.js +11 -10
  133. package/dist/components/ModelSelector.d.ts +6 -9
  134. package/dist/components/ModelSelector.js +1 -1
  135. package/dist/components/NavigationMenu.d.ts +11 -33
  136. package/dist/components/NavigationMenu.js +23 -30
  137. package/dist/components/NumberField.d.ts +6 -24
  138. package/dist/components/NumberField.js +13 -12
  139. package/dist/components/Plan.d.ts +103 -0
  140. package/dist/components/Plan.js +113 -0
  141. package/dist/components/Popover.d.ts +9 -36
  142. package/dist/components/Popover.js +23 -34
  143. package/dist/components/PreviewCard.d.ts +6 -24
  144. package/dist/components/PreviewCard.js +13 -24
  145. package/dist/components/PricingBillingToggle.js +1 -1
  146. package/dist/components/PricingFAQ.js +1 -1
  147. package/dist/components/PricingPage.js +2 -1
  148. package/dist/components/PricingPlanCard.js +5 -4
  149. package/dist/components/PricingUsageCalculator.js +3 -3
  150. package/dist/components/Progress.d.ts +3 -8
  151. package/dist/components/Progress.js +7 -10
  152. package/dist/components/PromptInput.d.ts +2 -2
  153. package/dist/components/PromptInput.js +83 -218
  154. package/dist/components/Queue.d.ts +7 -17
  155. package/dist/components/Queue.js +2 -3
  156. package/dist/components/RadioGroup.d.ts +3 -8
  157. package/dist/components/RadioGroup.js +7 -10
  158. package/dist/components/Reasoning.d.ts +4 -8
  159. package/dist/components/Reasoning.js +3 -6
  160. package/dist/components/ResizableSidePanel.js +2 -2
  161. package/dist/components/ResponsiveSidebarShell.d.ts +1 -1
  162. package/dist/components/ResponsiveSidebarShell.js +18 -11
  163. package/dist/components/ScrollArea.d.ts +5 -20
  164. package/dist/components/ScrollArea.js +12 -10
  165. package/dist/components/SearchField.d.ts +43 -0
  166. package/dist/components/SearchField.js +52 -0
  167. package/dist/components/Select.d.ts +1 -1
  168. package/dist/components/Select.js +33 -57
  169. package/dist/components/Separator.d.ts +1 -5
  170. package/dist/components/Separator.js +3 -6
  171. package/dist/components/Slider.d.ts +6 -19
  172. package/dist/components/Slider.js +15 -14
  173. package/dist/components/Sources.d.ts +4 -9
  174. package/dist/components/Sources.js +3 -2
  175. package/dist/components/Stepper.js +16 -9
  176. package/dist/components/SubagentRunDetails.js +1 -1
  177. package/dist/components/SubagentRunIndicator.js +2 -2
  178. package/dist/components/SubagentRunList.d.ts +3 -5
  179. package/dist/components/SubagentRunList.js +3 -5
  180. package/dist/components/SubagentRunSelector.d.ts +9 -22
  181. package/dist/components/SubagentRunSelector.js +29 -31
  182. package/dist/components/Switch.d.ts +4 -7
  183. package/dist/components/Switch.js +6 -10
  184. package/dist/components/Tabs.d.ts +2 -2
  185. package/dist/components/Tabs.js +21 -18
  186. package/dist/components/Task.d.ts +4 -9
  187. package/dist/components/Task.js +4 -3
  188. package/dist/components/Terminal.d.ts +3 -4
  189. package/dist/components/Terminal.js +5 -4
  190. package/dist/components/TestResults.d.ts +4 -9
  191. package/dist/components/TestResults.js +11 -6
  192. package/dist/components/Textarea.js +1 -1
  193. package/dist/components/ThemeModeControl.js +1 -1
  194. package/dist/components/ThinkChat.d.ts +45 -22
  195. package/dist/components/ThinkChat.js +7 -5
  196. package/dist/components/ThinkChatActivity.d.ts +2 -2
  197. package/dist/components/ThinkChatActivity.js +24 -7
  198. package/dist/components/ThinkChatActivitySummary.d.ts +1 -1
  199. package/dist/components/ThinkChatActivitySummary.js +7 -3
  200. package/dist/components/ThinkChatContext.d.ts +1 -1
  201. package/dist/components/ThinkChatToolPanels.js +27 -17
  202. package/dist/components/ThinkExecutionDetail.js +2 -2
  203. package/dist/components/ThinkExecutionStatus.js +2 -2
  204. package/dist/components/ThinkExecutionWorkbench.d.ts +30 -8
  205. package/dist/components/ThinkExecutionWorkbench.js +70 -134
  206. package/dist/components/ThinkFullApp.d.ts +40 -15
  207. package/dist/components/ThinkFullApp.js +193 -117
  208. package/dist/components/ThinkFullAppViewSwitch.d.ts +1 -1
  209. package/dist/components/ThinkFullAppViewSwitch.js +2 -2
  210. package/dist/components/ThinkPendingApproval.d.ts +60 -0
  211. package/dist/components/ThinkPendingApproval.js +99 -0
  212. package/dist/components/ThinkRecoveryNotice.d.ts +2 -0
  213. package/dist/components/ThinkRecoveryNotice.js +46 -0
  214. package/dist/components/ThinkRoutine.js +1 -0
  215. package/dist/components/ThinkRoutineBrowser.d.ts +17 -9
  216. package/dist/components/ThinkRoutineBrowser.js +37 -44
  217. package/dist/components/ThinkRoutineDetail.d.ts +5 -2
  218. package/dist/components/ThinkRoutineDetail.js +4 -4
  219. package/dist/components/ThinkRoutineForm.d.ts +3 -2
  220. package/dist/components/ThinkRoutineForm.js +11 -10
  221. package/dist/components/ThinkRoutineLibrary.d.ts +27 -25
  222. package/dist/components/ThinkRoutineLibrary.js +104 -80
  223. package/dist/components/ThinkRoutineRuns.d.ts +3 -2
  224. package/dist/components/ThinkRoutineRuns.js +31 -24
  225. package/dist/components/ThinkThreadPicker.d.ts +17 -11
  226. package/dist/components/ThinkThreadPicker.js +163 -39
  227. package/dist/components/ThinkThreadShell.d.ts +1 -1
  228. package/dist/components/Toast.d.ts +7 -28
  229. package/dist/components/Toast.js +15 -14
  230. package/dist/components/Toggle.d.ts +1 -1
  231. package/dist/components/Toggle.js +10 -8
  232. package/dist/components/ToggleGroup.d.ts +1 -1
  233. package/dist/components/ToggleGroup.js +21 -26
  234. package/dist/components/ToolApproval.d.ts +28 -0
  235. package/dist/components/ToolApproval.js +35 -0
  236. package/dist/components/ToolInvocation.d.ts +26 -0
  237. package/dist/components/ToolInvocation.js +72 -0
  238. package/dist/components/Toolbar.d.ts +6 -24
  239. package/dist/components/Toolbar.js +13 -12
  240. package/dist/components/Tooltip.d.ts +11 -10
  241. package/dist/components/Tooltip.js +17 -11
  242. package/dist/components/TransitionSurface.d.ts +27 -0
  243. package/dist/components/TransitionSurface.js +20 -0
  244. package/dist/components/WebPreview.d.ts +6 -7
  245. package/dist/components/WebPreview.js +70 -55
  246. package/dist/components/Workspace.d.ts +2 -2
  247. package/dist/components/Workspace.js +361 -346
  248. package/dist/components/WorkspaceBrowser.d.ts +4 -7
  249. package/dist/components/WorkspaceBrowser.js +16 -26
  250. package/dist/components/WorkspaceExplorer.d.ts +5 -33
  251. package/dist/components/WorkspaceExplorer.js +19 -32
  252. package/dist/components/WorkspaceFile.d.ts +1 -1
  253. package/dist/components/WorkspaceFileView.d.ts +14 -2
  254. package/dist/components/WorkspaceFileView.js +1 -1
  255. package/dist/components/WorkspaceHeader.d.ts +0 -8
  256. package/dist/components/WorkspaceHeader.js +3 -15
  257. package/dist/components/WorkspaceLink.d.ts +1 -1
  258. package/dist/components/WorkspaceLink.js +1 -1
  259. package/dist/components/icons.d.ts +2 -2
  260. package/dist/components/icons.js +2 -2
  261. package/dist/{copy-button-DtPMgN7e.d.ts → copy-button-D7aAYA-2.d.ts} +2 -3
  262. package/dist/{copy-button-Dejn5heL.js → copy-button-DeK6KXEV.js} +3 -2
  263. package/dist/{icons-CpfUer49.js → icons-CQJ-aMnI.js} +7 -3
  264. package/dist/{icons-GQd1xF4e.d.ts → icons-CYXmvKlJ.d.ts} +22 -2
  265. package/dist/navigation-link-Cob7KBlM.js +19 -0
  266. package/dist/styles/accordion.css +4 -19
  267. package/dist/styles/activity.css +48 -56
  268. package/dist/styles/agent-activity-preview.css +6 -0
  269. package/dist/styles/agent-chat.css +14 -63
  270. package/dist/styles/agent-connection.css +0 -12
  271. package/dist/styles/agent-tool-detail.css +54 -0
  272. package/dist/styles/alert-dialog.css +16 -18
  273. package/dist/styles/app-top-bar.css +17 -9
  274. package/dist/styles/approval.css +177 -0
  275. package/dist/styles/artifact.css +6 -18
  276. package/dist/styles/autocomplete.css +2 -1
  277. package/dist/styles/avatar.css +35 -30
  278. package/dist/styles/badge.css +10 -10
  279. package/dist/styles/base-ui-motion.css +94 -39
  280. package/dist/styles/browser-control-overlay.css +0 -1
  281. package/dist/styles/browser-live-view.css +39 -22
  282. package/dist/styles/browser-replay.css +1 -1
  283. package/dist/styles/browser-run-panel.css +13 -6
  284. package/dist/styles/button.css +36 -33
  285. package/dist/styles/card.css +5 -6
  286. package/dist/styles/chain-of-thought.css +22 -24
  287. package/dist/styles/checkbox.css +18 -5
  288. package/dist/styles/checkpoint.css +58 -0
  289. package/dist/styles/codex-model-selector.css +3 -7
  290. package/dist/styles/collapsible.css +10 -10
  291. package/dist/styles/combobox.css +4 -3
  292. package/dist/styles/commit.css +19 -39
  293. package/dist/styles/composition-motion.css +83 -0
  294. package/dist/styles/context-menu.css +3 -11
  295. package/dist/styles/context.css +11 -10
  296. package/dist/styles/conversation.css +18 -23
  297. package/dist/styles/dialog.css +15 -15
  298. package/dist/styles/environment-variables.css +0 -13
  299. package/dist/styles/field.css +32 -12
  300. package/dist/styles/file-tree.css +66 -22
  301. package/dist/styles/form.css +1 -1
  302. package/dist/styles/index.css +13 -4
  303. package/dist/styles/inline-citation.css +107 -0
  304. package/dist/styles/input.css +2 -2
  305. package/dist/styles/marker.css +14 -13
  306. package/dist/styles/mcp-server-picker.css +20 -47
  307. package/dist/styles/media-preview-card.css +160 -0
  308. package/dist/styles/menu.css +11 -40
  309. package/dist/styles/menubar.css +12 -19
  310. package/dist/styles/message-scroller.css +0 -12
  311. package/dist/styles/message.css +25 -31
  312. package/dist/styles/meter.css +2 -2
  313. package/dist/styles/model-selector.css +16 -34
  314. package/dist/styles/motion-reduction.css +29 -0
  315. package/dist/styles/navigation-menu.css +14 -30
  316. package/dist/styles/number-field.css +22 -4
  317. package/dist/styles/plan.css +132 -0
  318. package/dist/styles/popover.css +15 -52
  319. package/dist/styles/preview-card.css +2 -32
  320. package/dist/styles/progress.css +8 -3
  321. package/dist/styles/prompt-input.css +76 -269
  322. package/dist/styles/queue.css +48 -32
  323. package/dist/styles/radio.css +19 -12
  324. package/dist/styles/reasoning.css +2 -1
  325. package/dist/styles/recipes.css +207 -26
  326. package/dist/styles/resizable-side-panel.css +4 -10
  327. package/dist/styles/responsive-sidebar-shell.css +32 -34
  328. package/dist/styles/scroll-area.css +32 -15
  329. package/dist/styles/search-field.css +21 -0
  330. package/dist/styles/select.css +19 -12
  331. package/dist/styles/slider.css +25 -29
  332. package/dist/styles/sources.css +3 -11
  333. package/dist/styles/stepper.css +36 -26
  334. package/dist/styles/subagent-run.css +13 -71
  335. package/dist/styles/switch.css +32 -29
  336. package/dist/styles/tabs.css +79 -23
  337. package/dist/styles/task.css +11 -23
  338. package/dist/styles/test-results.css +29 -36
  339. package/dist/styles/theme-mode-control.css +8 -0
  340. package/dist/styles/think-execution-workbench.css +18 -15
  341. package/dist/styles/think-full-app.css +51 -100
  342. package/dist/styles/think-routine-library.css +51 -40
  343. package/dist/styles/think-thread-picker.css +207 -50
  344. package/dist/styles/toast.css +48 -34
  345. package/dist/styles/toggle-group.css +2 -36
  346. package/dist/styles/toggle.css +29 -5
  347. package/dist/styles/toolbar.css +25 -27
  348. package/dist/styles/tooltip.css +2 -32
  349. package/dist/styles/transition-surface.css +55 -0
  350. package/dist/styles/utilities.css +31 -0
  351. package/dist/styles/web-preview.css +0 -21
  352. package/dist/styles/workspace-explorer.css +104 -99
  353. package/dist/summarize-tool-input-CqTcGRYy.js +15 -0
  354. package/dist/think-agent-Cip5KAPj.d.ts +7 -0
  355. package/dist/utils/codex-model-catalog.d.ts +4 -4
  356. package/dist/utils/mcp-server-catalog.d.ts +132 -0
  357. package/dist/utils/mcp-server-catalog.js +90 -0
  358. package/dist/utils/structured-code.d.ts +1 -1
  359. package/dist/workspace-path-L_KmjRjq.js +26 -0
  360. package/package.json +14 -9
  361. package/dist/Workspace-D39LxGvP.d.ts +0 -62
  362. package/dist/class-names-9UtZwb0J.js +0 -12
  363. package/dist/components/AppFrame.d.ts +0 -24
  364. package/dist/components/AppFrame.js +0 -25
  365. package/dist/components/Shell.d.ts +0 -163
  366. package/dist/components/Shell.js +0 -137
  367. package/dist/components/SubagentRun.d.ts +0 -86
  368. package/dist/components/SubagentRun.js +0 -108
  369. package/dist/styles/app-frame.css +0 -15
  370. package/dist/styles/shell.css +0 -122
  371. package/dist/summarize-tool-input-BUJsENSn.js +0 -12
@@ -1,33 +1,29 @@
1
+ import { n as isWorkspacePathWithinRoot, t as canonicalizeAbsoluteWorkspacePath } from "../workspace-path-L_KmjRjq.js";
1
2
  import { getWorkspaceBasename, inferWorkspaceMedia } from "./WorkspaceFile.js";
2
3
  import * as React from "react";
4
+ import { queryOptions, useQueries, useQuery, useQueryClient } from "@tanstack/react-query";
3
5
  //#region src/components/Workspace.ts
4
6
  const DEFAULT_MAX_INLINE_ASSET_BYTES = 32 * 1024 * 1024;
5
7
  const WORKSPACE_DIRECTORY_PAGE_SIZE = 1e3;
8
+ const ACTIVE_FILE_GC_TIME = 2e3;
6
9
  const EMPTY_ENTRIES_BY_DIRECTORY = Object.freeze({});
7
10
  const EMPTY_ENTRY_BY_PATH = /* @__PURE__ */ new Map();
8
11
  const EMPTY_PATHS = /* @__PURE__ */ new Set();
12
+ const INACTIVE_FILE_INFO = {
13
+ path: "",
14
+ name: "",
15
+ type: "file",
16
+ mimeType: "text/plain",
17
+ size: 0,
18
+ createdAt: 0,
19
+ updatedAt: 0
20
+ };
21
+ const INACTIVE_FILE_ASSET_RESOLVER = () => null;
9
22
  function toErrorMessage(error) {
10
23
  return error instanceof Error ? error.message : String(error);
11
24
  }
12
- function normalizeWorkspacePath(path) {
13
- if (!path.startsWith("/") || path.includes("\0")) return null;
14
- const segments = [];
15
- for (const segment of path.split("/")) {
16
- if (!segment || segment === ".") continue;
17
- if (segment === "..") segments.pop();
18
- else segments.push(segment);
19
- }
20
- return `/${segments.join("/")}`;
21
- }
22
- function isPathWithinWorkspaceRoot(path, root) {
23
- const normalizedPath = normalizeWorkspacePath(path);
24
- const normalizedRoot = normalizeWorkspacePath(root);
25
- if (!normalizedPath || !normalizedRoot) return false;
26
- return normalizedRoot === "/" || normalizedPath === normalizedRoot || normalizedPath.startsWith(`${normalizedRoot}/`);
27
- }
28
- function getWorkspaceParentPath(path) {
29
- const separatorIndex = path.lastIndexOf("/");
30
- return separatorIndex <= 0 ? "/" : path.slice(0, separatorIndex);
25
+ function throwIfAborted(signal) {
26
+ if (signal.aborted) throw signal.reason ?? new DOMException("The query was cancelled.", "AbortError");
31
27
  }
32
28
  function getAssetDataSize(asset) {
33
29
  if (asset.kind === "url") return void 0;
@@ -42,10 +38,7 @@ function normalizeWorkspaceAsset(asset, path, inferredMedia, info) {
42
38
  size: asset.size ?? getAssetDataSize(asset) ?? info.size
43
39
  };
44
40
  return {
45
- asset: asset.kind === "url" ? {
46
- ...asset,
47
- ...metadata
48
- } : {
41
+ asset: {
49
42
  ...asset,
50
43
  ...metadata
51
44
  },
@@ -65,360 +58,382 @@ async function readWorkspaceAssetBytes(source, path, info, maxInlineAssetBytes)
65
58
  } : null;
66
59
  }
67
60
  /**
68
- * Headless state for browsing a Think workspace: lazy directory loading,
69
- * cached file reads, expansion/selection, and refresh. Feed the result to
70
- * `WorkspaceExplorer`, or compose `WorkspaceBrowser` and `WorkspaceFileView`.
61
+ * Source/root prefix for cache inspection, cancellation, or removal.
62
+ * Do not broadly invalidate this prefix: active file queries must refresh in
63
+ * stat → resolver → content order. Use a resource option key or `refresh()`.
71
64
  */
72
- function useWorkspace({ source, root = "/", resolveFileAsset, maxInlineAssetBytes = DEFAULT_MAX_INLINE_ASSET_BYTES }) {
73
- const [entriesByDirectory, setEntriesByDirectory] = React.useState({});
74
- const [filesByPath, setFilesByPath] = React.useState({});
75
- const [expandedPaths, setExpandedPathsState] = React.useState(/* @__PURE__ */ new Set());
76
- const [selectedPath, setSelectedPath] = React.useState(null);
77
- const [isLoading, setIsLoading] = React.useState(false);
78
- const [loadingPaths, setLoadingPaths] = React.useState(/* @__PURE__ */ new Set());
79
- const [directoryErrorsByPath, setDirectoryErrorsByPath] = React.useState({});
80
- const [info, setInfo] = React.useState(null);
81
- const [activeAssetFile, setActiveAssetFile] = React.useState(null);
82
- const [stateGeneration, setStateGeneration] = React.useState(0);
83
- const loadedDirectoriesRef = React.useRef(/* @__PURE__ */ new Set());
84
- const directoryRequestVersionsRef = React.useRef(/* @__PURE__ */ new Map());
85
- const nextDirectoryRequestVersionRef = React.useRef(0);
86
- const nextInfoRequestVersionRef = React.useRef(0);
87
- const refreshRequestVersionRef = React.useRef(0);
88
- const loadingOperationVersionRef = React.useRef(0);
89
- const selectedPathRef = React.useRef(null);
90
- const fileRequestRef = React.useRef(null);
91
- const resolveFileAssetRef = React.useRef(resolveFileAsset);
92
- resolveFileAssetRef.current = resolveFileAsset;
93
- const maxInlineAssetBytesRef = React.useRef(DEFAULT_MAX_INLINE_ASSET_BYTES);
94
- maxInlineAssetBytesRef.current = Number.isFinite(maxInlineAssetBytes) && maxInlineAssetBytes >= 0 ? maxInlineAssetBytes : DEFAULT_MAX_INLINE_ASSET_BYTES;
95
- const sourceIdentityRef = React.useRef({
96
- source,
97
- root,
98
- generation: 0
99
- });
100
- if (sourceIdentityRef.current.source !== source || sourceIdentityRef.current.root !== root) sourceIdentityRef.current = {
101
- source,
102
- root,
103
- generation: sourceIdentityRef.current.generation + 1
65
+ function workspaceQueryKey(sourceKey, root) {
66
+ return [
67
+ "workspace",
68
+ sourceKey,
69
+ root
70
+ ];
71
+ }
72
+ function workspaceFileQueryKey(sourceKey, root, requestedPath) {
73
+ return [
74
+ ...workspaceQueryKey(sourceKey, root),
75
+ "file",
76
+ requestedPath
77
+ ];
78
+ }
79
+ function workspaceFileVersion(target) {
80
+ return {
81
+ path: target.readPath,
82
+ name: target.info.name,
83
+ type: target.info.type,
84
+ mimeType: target.info.mimeType ?? null,
85
+ size: target.info.size,
86
+ createdAt: target.info.createdAt,
87
+ updatedAt: target.info.updatedAt,
88
+ target: target.info.target ?? null
104
89
  };
105
- const entryByPath = React.useMemo(() => {
106
- const map = /* @__PURE__ */ new Map();
107
- for (const entries of Object.values(entriesByDirectory)) for (const entry of entries) map.set(entry.path, entry);
108
- return map;
109
- }, [entriesByDirectory]);
110
- const markLoading = React.useCallback((path, loading) => {
111
- setLoadingPaths((current) => {
112
- const next = new Set(current);
113
- if (loading) next.add(path);
114
- else next.delete(path);
115
- return next;
116
- });
117
- }, []);
118
- const setDirectoryError = React.useCallback((path, message) => {
119
- setDirectoryErrorsByPath((current) => {
120
- if (message !== null) {
121
- if (current[path] === message) return current;
122
- return {
123
- ...current,
124
- [path]: message
125
- };
126
- }
127
- if (!Object.hasOwn(current, path)) return current;
128
- const next = { ...current };
129
- delete next[path];
130
- return next;
131
- });
132
- }, []);
133
- const activateAssetFile = React.useCallback((file) => {
134
- setFilesByPath((current) => {
135
- if (!Object.hasOwn(current, file.path)) return current;
136
- const next = { ...current };
137
- delete next[file.path];
138
- return next;
139
- });
140
- setActiveAssetFile(file);
141
- }, []);
142
- const cacheTextFile = React.useCallback((file) => {
143
- setActiveAssetFile((current) => current?.path === file.path ? null : current);
144
- setFilesByPath((current) => ({
145
- ...current,
146
- [file.path]: file
147
- }));
148
- }, []);
149
- const cancelFileLoad = React.useCallback(() => {
150
- const request = fileRequestRef.current;
151
- if (!request) return;
152
- request.controller.abort();
153
- fileRequestRef.current = null;
154
- markLoading(request.path, false);
155
- }, [markLoading]);
156
- const loadDirectory = React.useCallback(async (path, { force = false } = {}) => {
157
- if (!force && loadedDirectoriesRef.current.has(path)) return;
158
- const identity = sourceIdentityRef.current;
159
- if (identity.source !== source || identity.root !== root) return;
160
- const generation = identity.generation;
161
- const requestVersion = nextDirectoryRequestVersionRef.current + 1;
162
- nextDirectoryRequestVersionRef.current = requestVersion;
163
- directoryRequestVersionsRef.current.set(path, requestVersion);
164
- const requestIsCurrent = () => generation === sourceIdentityRef.current.generation && directoryRequestVersionsRef.current.get(path) === requestVersion;
165
- markLoading(path, true);
166
- try {
90
+ }
91
+ /** Shared directory options for workspace components and route loaders. */
92
+ function workspaceDirectoryQueryOptions(source, sourceKey, root, path) {
93
+ return queryOptions({
94
+ queryKey: [
95
+ ...workspaceQueryKey(sourceKey, root),
96
+ "directory",
97
+ path
98
+ ],
99
+ queryFn: async ({ signal }) => {
167
100
  const entries = [];
168
101
  let offset = 0;
169
102
  for (;;) {
103
+ throwIfAborted(signal);
170
104
  const page = await source.readDir(path, {
171
105
  limit: WORKSPACE_DIRECTORY_PAGE_SIZE,
172
106
  offset
173
107
  });
174
- if (!requestIsCurrent()) return;
108
+ throwIfAborted(signal);
175
109
  entries.push(...page);
176
- if (page.length < WORKSPACE_DIRECTORY_PAGE_SIZE) break;
110
+ if (page.length < WORKSPACE_DIRECTORY_PAGE_SIZE) return entries;
177
111
  offset += page.length;
178
112
  }
179
- loadedDirectoriesRef.current.add(path);
180
- setEntriesByDirectory((current) => ({
181
- ...current,
182
- [path]: entries
183
- }));
184
- setDirectoryError(path, null);
185
- return entries;
186
- } catch (listError) {
187
- if (!requestIsCurrent()) return;
188
- setDirectoryError(path, toErrorMessage(listError));
189
- return null;
190
- } finally {
191
- if (requestIsCurrent()) markLoading(path, false);
192
- }
193
- }, [
194
- source,
195
- root,
196
- markLoading,
197
- setDirectoryError
198
- ]);
199
- const loadFile = React.useCallback(async (path, { force = false, refreshRequestVersion } = {}) => {
200
- const listedFileInfo = entryByPath.get(path) ?? null;
201
- const cachedFile = filesByPath[path];
202
- if (!force && cachedFile && !inferWorkspaceMedia(path, listedFileInfo?.mimeType)) return;
203
- const identity = sourceIdentityRef.current;
204
- if (identity.source !== source || identity.root !== root) return;
205
- const generation = identity.generation;
206
- cancelFileLoad();
207
- const controller = new AbortController();
208
- const request = {
209
- path,
210
- controller
211
- };
212
- fileRequestRef.current = request;
213
- markLoading(path, true);
214
- let fileInfo = listedFileInfo;
215
- let media = inferWorkspaceMedia(path, fileInfo?.mimeType);
216
- const requestIsCurrent = () => !controller.signal.aborted && generation === sourceIdentityRef.current.generation && selectedPathRef.current === path && (refreshRequestVersion === void 0 || refreshRequestVersionRef.current === refreshRequestVersion);
217
- try {
218
- if (!isPathWithinWorkspaceRoot(path, root)) throw new Error("This file is outside the configured workspace root.");
219
- const resolvedInfo = await source.stat(path);
220
- if (!requestIsCurrent()) return;
221
- if (!resolvedInfo) {
222
- fileInfo = null;
223
- throw new Error("File metadata is unavailable because source.stat() returned null.");
224
- }
225
- fileInfo = resolvedInfo;
226
- const readPath = normalizeWorkspacePath(resolvedInfo.path);
113
+ },
114
+ staleTime: Infinity
115
+ });
116
+ }
117
+ /** Shared workspace-summary options for workspace components and route loaders. */
118
+ function workspaceInfoQueryOptions(source, sourceKey, root) {
119
+ return queryOptions({
120
+ queryKey: [...workspaceQueryKey(sourceKey, root), "info"],
121
+ queryFn: async ({ signal }) => {
122
+ if (!("getWorkspaceInfo" in source) || typeof source.getWorkspaceInfo !== "function") return null;
123
+ const info = await source.getWorkspaceInfo();
124
+ throwIfAborted(signal);
125
+ return info;
126
+ },
127
+ staleTime: Infinity
128
+ });
129
+ }
130
+ /** Re-stat and validate a requested path before any resolver or file read. */
131
+ function workspaceFileStatQueryOptions(source, sourceKey, root, requestedPath) {
132
+ return queryOptions({
133
+ queryKey: [...workspaceFileQueryKey(sourceKey, root, requestedPath), "stat"],
134
+ queryFn: async ({ signal }) => {
135
+ if (!isWorkspacePathWithinRoot(requestedPath, root)) throw new Error("This file is outside the configured workspace root.");
136
+ const info = await source.stat(requestedPath);
137
+ throwIfAborted(signal);
138
+ if (!info) throw new Error("File metadata is unavailable because source.stat() returned null.");
139
+ const readPath = canonicalizeAbsoluteWorkspacePath(info.path);
227
140
  if (!readPath) throw new Error("The workspace source returned an invalid file path from stat().");
228
- if (readPath !== resolvedInfo.path) throw new Error("The workspace source returned a non-canonical file path from stat().");
229
- if (!isPathWithinWorkspaceRoot(readPath, root)) throw new Error("This file's resolved path is outside the configured workspace root.");
230
- media = inferWorkspaceMedia(readPath, resolvedInfo.mimeType);
231
- const resolver = resolveFileAssetRef.current;
232
- const resolvedAsset = resolver ? await resolver({
233
- path: readPath,
234
- requestedPath: path,
235
- root: normalizeWorkspacePath(root) ?? root,
236
- info: resolvedInfo,
237
- signal: controller.signal
238
- }) : null;
239
- if (!requestIsCurrent()) return;
240
- if (resolvedAsset) {
241
- const normalized = normalizeWorkspaceAsset(resolvedAsset, readPath, media, resolvedInfo);
242
- if (!normalized) throw new Error("The host returned an asset without a supported image, PDF, audio, or video MIME type.");
243
- media = normalized.media;
244
- activateAssetFile({
245
- path,
246
- name: getWorkspaceBasename(path),
247
- content: null,
248
- asset: normalized.asset,
249
- info: resolvedInfo,
250
- error: null
251
- });
252
- return;
253
- }
254
- if (media) {
255
- const byteAsset = await readWorkspaceAssetBytes(source, readPath, resolvedInfo, maxInlineAssetBytesRef.current);
256
- if (!requestIsCurrent()) return;
257
- const normalized = byteAsset ? normalizeWorkspaceAsset(byteAsset, readPath, media, resolvedInfo) : null;
258
- activateAssetFile({
259
- path,
260
- name: getWorkspaceBasename(path),
261
- content: null,
262
- asset: normalized?.asset ?? null,
263
- info: resolvedInfo,
264
- error: null
265
- });
266
- return;
267
- }
268
- const content = await source.readFile(readPath);
269
- if (!requestIsCurrent()) return;
270
- cacheTextFile({
271
- path,
272
- name: getWorkspaceBasename(path),
273
- content,
274
- asset: null,
275
- info: resolvedInfo,
276
- error: null
277
- });
278
- } catch (readError) {
279
- if (!requestIsCurrent()) return;
280
- const failedFile = {
281
- path,
282
- name: getWorkspaceBasename(path),
283
- content: null,
284
- asset: null,
285
- info: fileInfo,
286
- error: toErrorMessage(readError)
141
+ if (readPath !== info.path) throw new Error("The workspace source returned a non-canonical file path from stat().");
142
+ if (!isWorkspacePathWithinRoot(readPath, root)) throw new Error("This file's resolved path is outside the configured workspace root.");
143
+ return {
144
+ requestedPath,
145
+ readPath,
146
+ info,
147
+ media: inferWorkspaceMedia(readPath, info.mimeType)
287
148
  };
288
- if (media) activateAssetFile(failedFile);
289
- else cacheTextFile(failedFile);
290
- } finally {
291
- if (fileRequestRef.current === request && generation === sourceIdentityRef.current.generation) {
292
- fileRequestRef.current = null;
293
- markLoading(path, false);
294
- }
295
- }
296
- }, [
297
- activateAssetFile,
298
- cacheTextFile,
299
- cancelFileLoad,
300
- entryByPath,
301
- filesByPath,
302
- markLoading,
303
- root,
304
- source
305
- ]);
306
- const loadInfo = React.useCallback(async () => {
307
- if (!("getWorkspaceInfo" in source)) return;
308
- if (typeof source.getWorkspaceInfo !== "function") return;
309
- const identity = sourceIdentityRef.current;
310
- if (identity.source !== source || identity.root !== root) return;
311
- const generation = identity.generation;
312
- const requestVersion = nextInfoRequestVersionRef.current + 1;
313
- nextInfoRequestVersionRef.current = requestVersion;
314
- const requestIsCurrent = () => generation === sourceIdentityRef.current.generation && nextInfoRequestVersionRef.current === requestVersion;
315
- try {
316
- const nextInfo = await source.getWorkspaceInfo();
317
- if (requestIsCurrent()) setInfo(nextInfo);
318
- } catch {
319
- if (requestIsCurrent()) setInfo(null);
320
- }
321
- }, [source, root]);
322
- React.useEffect(() => {
323
- const generation = sourceIdentityRef.current.generation;
324
- const loadingOperationVersion = loadingOperationVersionRef.current + 1;
325
- loadingOperationVersionRef.current = loadingOperationVersion;
326
- refreshRequestVersionRef.current += 1;
327
- cancelFileLoad();
328
- setEntriesByDirectory({});
329
- setFilesByPath({});
330
- setActiveAssetFile(null);
331
- setExpandedPathsState(/* @__PURE__ */ new Set());
332
- setSelectedPath(null);
333
- selectedPathRef.current = null;
334
- setLoadingPaths(/* @__PURE__ */ new Set());
335
- setDirectoryErrorsByPath({});
336
- setInfo(null);
337
- setStateGeneration(generation);
338
- loadedDirectoriesRef.current = /* @__PURE__ */ new Set();
339
- directoryRequestVersionsRef.current = /* @__PURE__ */ new Map();
340
- setIsLoading(true);
341
- Promise.all([loadDirectory(root, { force: true }), loadInfo()]).finally(() => {
342
- if (generation === sourceIdentityRef.current.generation && loadingOperationVersionRef.current === loadingOperationVersion) setIsLoading(false);
149
+ },
150
+ staleTime: 0,
151
+ refetchOnMount: "always",
152
+ refetchOnWindowFocus: false,
153
+ refetchOnReconnect: false,
154
+ retry: false
155
+ });
156
+ }
157
+ /** Optional host asset resolution, scoped to the current stat result. */
158
+ function workspaceFileAssetQueryOptions(sourceKey, root, target, resolveFileAsset) {
159
+ return queryOptions({
160
+ queryKey: [
161
+ ...workspaceFileQueryKey(sourceKey, root, target.requestedPath),
162
+ "asset",
163
+ workspaceFileVersion(target)
164
+ ],
165
+ queryFn: async ({ signal }) => {
166
+ const resolvedAsset = await resolveFileAsset({
167
+ path: target.readPath,
168
+ requestedPath: target.requestedPath,
169
+ root: canonicalizeAbsoluteWorkspacePath(root) ?? root,
170
+ info: target.info,
171
+ signal
172
+ });
173
+ if (!resolvedAsset) return null;
174
+ const normalized = normalizeWorkspaceAsset(resolvedAsset, target.readPath, target.media, target.info);
175
+ if (!normalized) throw new Error("The host returned an asset without a supported image, PDF, audio, or video MIME type.");
176
+ return normalized;
177
+ },
178
+ staleTime: 0,
179
+ gcTime: ACTIVE_FILE_GC_TIME,
180
+ refetchOnMount: "always",
181
+ refetchOnWindowFocus: false,
182
+ refetchOnReconnect: false,
183
+ retry: false
184
+ });
185
+ }
186
+ /** Cached text read options, scoped to the validated stat result. */
187
+ function workspaceTextFileQueryOptions(source, sourceKey, root, target) {
188
+ return queryOptions({
189
+ queryKey: [
190
+ ...workspaceFileQueryKey(sourceKey, root, target.requestedPath),
191
+ "text",
192
+ workspaceFileVersion(target)
193
+ ],
194
+ queryFn: async ({ signal }) => {
195
+ const content = await source.readFile(target.readPath);
196
+ throwIfAborted(signal);
197
+ return content;
198
+ },
199
+ staleTime: Infinity
200
+ });
201
+ }
202
+ /** Active-file-only buffered asset options, scoped to the validated stat result. */
203
+ function workspaceBinaryFileQueryOptions(source, sourceKey, root, target, maxInlineAssetBytes) {
204
+ return queryOptions({
205
+ queryKey: [
206
+ ...workspaceFileQueryKey(sourceKey, root, target.requestedPath),
207
+ "bytes",
208
+ workspaceFileVersion(target),
209
+ { maxInlineAssetBytes }
210
+ ],
211
+ queryFn: async ({ signal }) => {
212
+ const asset = await readWorkspaceAssetBytes(source, target.readPath, target.info, maxInlineAssetBytes);
213
+ throwIfAborted(signal);
214
+ return asset ? normalizeWorkspaceAsset(asset, target.readPath, target.media, target.info) : null;
215
+ },
216
+ staleTime: 0,
217
+ gcTime: ACTIVE_FILE_GC_TIME,
218
+ refetchOnMount: "always",
219
+ refetchOnWindowFocus: false,
220
+ refetchOnReconnect: false,
221
+ retry: false
222
+ });
223
+ }
224
+ async function refreshWorkspaceFile(queryClient, { source, sourceKey, root, selectedPath, resolveFileAsset, maxInlineAssetBytes }) {
225
+ if (!selectedPath) return;
226
+ const target = await queryClient.fetchQuery({
227
+ ...workspaceFileStatQueryOptions(source, sourceKey, root, selectedPath),
228
+ staleTime: 0
229
+ });
230
+ if (resolveFileAsset) {
231
+ const options = workspaceFileAssetQueryOptions(sourceKey, root, target, resolveFileAsset);
232
+ if (!queryClient.getQueryState(options.queryKey)) return;
233
+ if (await queryClient.fetchQuery({
234
+ ...options,
235
+ staleTime: 0
236
+ })) return;
237
+ }
238
+ if (target.media) {
239
+ const options = workspaceBinaryFileQueryOptions(source, sourceKey, root, target, maxInlineAssetBytes);
240
+ if (queryClient.getQueryState(options.queryKey)) await queryClient.fetchQuery({
241
+ ...options,
242
+ staleTime: 0
343
243
  });
244
+ return;
245
+ }
246
+ const options = workspaceTextFileQueryOptions(source, sourceKey, root, target);
247
+ if (queryClient.getQueryState(options.queryKey)) await queryClient.fetchQuery({
248
+ ...options,
249
+ staleTime: 0
250
+ });
251
+ }
252
+ /**
253
+ * Headless state for browsing a Think workspace. TanStack Query owns remote
254
+ * directory, metadata, resolver, text, and byte lifecycles; the route owns
255
+ * selection, while this hook only keeps local tree expansion state.
256
+ */
257
+ function useWorkspace({ source, sourceKey, root = "/", selectedPath, onSelectedPathChange, resolveFileAsset, maxInlineAssetBytes = DEFAULT_MAX_INLINE_ASSET_BYTES }) {
258
+ const queryClient = useQueryClient();
259
+ const scopeKey = JSON.stringify([sourceKey, root]);
260
+ const [expandedPathsByScope, setExpandedPathsByScope] = React.useState({});
261
+ const expandedPaths = expandedPathsByScope[scopeKey] ?? EMPTY_PATHS;
262
+ const latestExpansionRef = React.useRef({
263
+ scopeKey,
264
+ paths: expandedPaths
265
+ });
266
+ const normalizedMaxInlineAssetBytes = Number.isFinite(maxInlineAssetBytes) && maxInlineAssetBytes >= 0 ? maxInlineAssetBytes : DEFAULT_MAX_INLINE_ASSET_BYTES;
267
+ const directoryPaths = React.useMemo(() => [.../* @__PURE__ */ new Set([root, ...expandedPaths])].sort(), [expandedPaths, root]);
268
+ const directoryQueries = useQueries({ queries: directoryPaths.map((path) => workspaceDirectoryQueryOptions(source, sourceKey, root, path)) });
269
+ const infoQuery = useQuery({
270
+ ...workspaceInfoQueryOptions(source, sourceKey, root),
271
+ enabled: "getWorkspaceInfo" in source && typeof source.getWorkspaceInfo === "function"
272
+ });
273
+ const statQuery = useQuery({
274
+ ...workspaceFileStatQueryOptions(source, sourceKey, root, selectedPath ?? root),
275
+ enabled: selectedPath !== null
276
+ });
277
+ const target = selectedPath === null ? void 0 : statQuery.data;
278
+ const statSettled = target !== void 0 && statQuery.isSuccess && !statQuery.isFetching;
279
+ const queryTarget = target ?? {
280
+ requestedPath: selectedPath ?? root,
281
+ readPath: selectedPath ?? root,
282
+ info: INACTIVE_FILE_INFO,
283
+ media: null
284
+ };
285
+ const assetQuery = useQuery({
286
+ ...workspaceFileAssetQueryOptions(sourceKey, root, queryTarget, resolveFileAsset ?? INACTIVE_FILE_ASSET_RESOLVER),
287
+ enabled: statSettled && resolveFileAsset !== void 0
288
+ });
289
+ const resolvedAsset = assetQuery.data ?? null;
290
+ const resolverSettled = !resolveFileAsset || assetQuery.isSuccess && !assetQuery.isFetching;
291
+ const textQuery = useQuery({
292
+ ...workspaceTextFileQueryOptions(source, sourceKey, root, queryTarget),
293
+ enabled: statSettled && resolverSettled && !resolvedAsset && !target.media
294
+ });
295
+ const binaryQuery = useQuery({
296
+ ...workspaceBinaryFileQueryOptions(source, sourceKey, root, queryTarget, normalizedMaxInlineAssetBytes),
297
+ enabled: statSettled && resolverSettled && !resolvedAsset && Boolean(target.media)
298
+ });
299
+ const entriesByDirectory = React.useMemo(() => {
300
+ const entries = {};
301
+ for (const [index, path] of directoryPaths.entries()) {
302
+ const data = directoryQueries[index]?.data;
303
+ if (data) entries[path] = data;
304
+ }
305
+ return entries;
306
+ }, [directoryPaths, directoryQueries]);
307
+ const entryByPath = React.useMemo(() => {
308
+ const entries = /* @__PURE__ */ new Map();
309
+ for (const directoryEntries of Object.values(entriesByDirectory)) for (const entry of directoryEntries) entries.set(entry.path, entry);
310
+ return entries;
311
+ }, [entriesByDirectory]);
312
+ const setExpandedPaths = React.useCallback((next) => {
313
+ latestExpansionRef.current = {
314
+ scopeKey,
315
+ paths: next
316
+ };
317
+ setExpandedPathsByScope((current) => ({
318
+ ...current,
319
+ [scopeKey]: next
320
+ }));
321
+ }, [scopeKey]);
322
+ const selectFile = React.useCallback((path) => onSelectedPathChange?.(path), [onSelectedPathChange]);
323
+ const selectedError = statQuery.error ?? assetQuery.error ?? textQuery.error ?? binaryQuery.error;
324
+ let selectedFile = null;
325
+ if (selectedPath && selectedError) selectedFile = {
326
+ path: selectedPath,
327
+ name: getWorkspaceBasename(selectedPath),
328
+ content: null,
329
+ asset: null,
330
+ info: target?.info ?? null,
331
+ error: toErrorMessage(selectedError)
332
+ };
333
+ else if (selectedPath && statSettled && target && resolverSettled) {
334
+ if (resolvedAsset) selectedFile = {
335
+ path: selectedPath,
336
+ name: getWorkspaceBasename(selectedPath),
337
+ content: null,
338
+ asset: resolvedAsset.asset,
339
+ info: target.info,
340
+ error: null
341
+ };
342
+ else if (target.media && binaryQuery.isSuccess && !binaryQuery.isFetching) selectedFile = {
343
+ path: selectedPath,
344
+ name: getWorkspaceBasename(selectedPath),
345
+ content: null,
346
+ asset: binaryQuery.data?.asset ?? null,
347
+ info: target.info,
348
+ error: null
349
+ };
350
+ else if (!target.media && textQuery.isSuccess) selectedFile = {
351
+ path: selectedPath,
352
+ name: getWorkspaceBasename(selectedPath),
353
+ content: textQuery.data,
354
+ asset: null,
355
+ info: target.info,
356
+ error: null
357
+ };
358
+ }
359
+ const loadingPaths = React.useMemo(() => {
360
+ const paths = /* @__PURE__ */ new Set();
361
+ for (const [index, path] of directoryPaths.entries()) if (directoryQueries[index]?.isFetching) paths.add(path);
362
+ if (selectedPath && [
363
+ statQuery,
364
+ assetQuery,
365
+ textQuery,
366
+ binaryQuery
367
+ ].some((query) => query.isFetching)) paths.add(selectedPath);
368
+ return paths;
344
369
  }, [
345
- cancelFileLoad,
346
- loadDirectory,
347
- loadInfo,
348
- root
370
+ assetQuery,
371
+ binaryQuery,
372
+ directoryPaths,
373
+ directoryQueries,
374
+ selectedPath,
375
+ statQuery,
376
+ textQuery
349
377
  ]);
350
- React.useEffect(() => () => {
351
- fileRequestRef.current?.controller.abort();
352
- }, []);
353
- const setExpandedPaths = React.useCallback((next) => {
354
- setExpandedPathsState((current) => {
355
- for (const path of next) if (!current.has(path)) loadDirectory(path);
356
- return next;
357
- });
358
- }, [loadDirectory]);
359
- const selectFile = React.useCallback((path) => {
360
- cancelFileLoad();
361
- selectedPathRef.current = path;
362
- setActiveAssetFile(null);
363
- setSelectedPath(path);
364
- if (path !== null) loadFile(path);
365
- }, [cancelFileLoad, loadFile]);
378
+ const rootDirectoryIndex = directoryPaths.indexOf(root);
379
+ const isLoading = Boolean(directoryQueries[rootDirectoryIndex]?.isFetching) || infoQuery.isFetching;
380
+ const error = [...new Set(directoryQueries.map((query) => query.error).filter((queryError) => queryError !== null).map(toErrorMessage))].join("; ") || null;
366
381
  const refresh = React.useCallback(() => {
367
382
  (async () => {
368
- const identity = sourceIdentityRef.current;
369
- if (identity.source !== source || identity.root !== root) return;
370
- const generation = identity.generation;
371
- const refreshRequestVersion = refreshRequestVersionRef.current + 1;
372
- refreshRequestVersionRef.current = refreshRequestVersion;
373
- const loadingOperationVersion = loadingOperationVersionRef.current + 1;
374
- loadingOperationVersionRef.current = loadingOperationVersion;
375
- const requestIsCurrent = () => generation === sourceIdentityRef.current.generation && refreshRequestVersionRef.current === refreshRequestVersion;
376
- setIsLoading(true);
377
- try {
378
- const directoryPaths = [.../* @__PURE__ */ new Set([root, ...expandedPaths])];
379
- const [refreshedListings] = await Promise.all([Promise.all(directoryPaths.map((path) => loadDirectory(path, { force: true }))), loadInfo()]);
380
- if (!requestIsCurrent()) return;
381
- const refreshedSelectedPath = selectedPathRef.current;
382
- if (refreshedSelectedPath) {
383
- const selectedDirectoryIndex = directoryPaths.indexOf(getWorkspaceParentPath(refreshedSelectedPath));
384
- const selectedDirectoryListing = refreshedListings[selectedDirectoryIndex];
385
- if (selectedDirectoryIndex >= 0 && (selectedDirectoryListing === null || selectedDirectoryListing === void 0)) return;
386
- await loadFile(refreshedSelectedPath, {
387
- force: true,
388
- refreshRequestVersion
383
+ const latestExpandedPaths = latestExpansionRef.current.scopeKey === scopeKey ? latestExpansionRef.current.paths : expandedPaths;
384
+ const refreshedDirectoryPaths = [.../* @__PURE__ */ new Set([root, ...latestExpandedPaths])].sort();
385
+ await queryClient.cancelQueries({ queryKey: workspaceQueryKey(sourceKey, root) });
386
+ const refreshedDirectories = await Promise.all(refreshedDirectoryPaths.map(async (path) => {
387
+ try {
388
+ await queryClient.fetchQuery({
389
+ ...workspaceDirectoryQueryOptions(source, sourceKey, root, path),
390
+ staleTime: 0
389
391
  });
392
+ return true;
393
+ } catch {
394
+ return false;
390
395
  }
391
- } finally {
392
- if (requestIsCurrent() && loadingOperationVersionRef.current === loadingOperationVersion) setIsLoading(false);
393
- }
394
- })();
396
+ }));
397
+ if ("getWorkspaceInfo" in source && typeof source.getWorkspaceInfo === "function") await queryClient.fetchQuery({
398
+ ...workspaceInfoQueryOptions(source, sourceKey, root),
399
+ staleTime: 0
400
+ }).catch(() => void 0);
401
+ if (refreshedDirectories.includes(false)) return;
402
+ await refreshWorkspaceFile(queryClient, {
403
+ source,
404
+ sourceKey,
405
+ root,
406
+ selectedPath,
407
+ resolveFileAsset,
408
+ maxInlineAssetBytes: normalizedMaxInlineAssetBytes
409
+ });
410
+ })().catch(() => {});
395
411
  }, [
396
412
  expandedPaths,
397
- loadDirectory,
398
- loadFile,
399
- loadInfo,
413
+ normalizedMaxInlineAssetBytes,
414
+ queryClient,
415
+ resolveFileAsset,
400
416
  root,
401
- source
417
+ scopeKey,
418
+ selectedPath,
419
+ source,
420
+ sourceKey
402
421
  ]);
403
- const stateIsCurrent = stateGeneration === sourceIdentityRef.current.generation;
404
- const directoryError = [...new Set(Object.values(directoryErrorsByPath))].join("; ") || null;
405
- const visibleSelectedPath = stateIsCurrent ? selectedPath : null;
406
- const selectedFile = visibleSelectedPath ? activeAssetFile?.path === visibleSelectedPath ? activeAssetFile : filesByPath[visibleSelectedPath] ?? null : null;
407
422
  return {
408
423
  root,
409
- entriesByDirectory: stateIsCurrent ? entriesByDirectory : EMPTY_ENTRIES_BY_DIRECTORY,
410
- entryByPath: stateIsCurrent ? entryByPath : EMPTY_ENTRY_BY_PATH,
411
- expandedPaths: stateIsCurrent ? expandedPaths : EMPTY_PATHS,
424
+ entriesByDirectory: Object.keys(entriesByDirectory).length > 0 ? entriesByDirectory : EMPTY_ENTRIES_BY_DIRECTORY,
425
+ entryByPath: entryByPath.size > 0 ? entryByPath : EMPTY_ENTRY_BY_PATH,
426
+ expandedPaths,
412
427
  setExpandedPaths,
413
- selectedPath: visibleSelectedPath,
428
+ selectedPath,
414
429
  selectFile,
415
430
  selectedFile,
416
- isLoading: !stateIsCurrent || isLoading,
417
- loadingPaths: stateIsCurrent ? loadingPaths : EMPTY_PATHS,
418
- error: stateIsCurrent ? directoryError : null,
419
- info: stateIsCurrent ? info : null,
431
+ isLoading,
432
+ loadingPaths: loadingPaths.size > 0 ? loadingPaths : EMPTY_PATHS,
433
+ error,
434
+ info: infoQuery.data ?? null,
420
435
  refresh
421
436
  };
422
437
  }
423
438
  //#endregion
424
- export { useWorkspace };
439
+ export { useWorkspace, workspaceBinaryFileQueryOptions, workspaceDirectoryQueryOptions, workspaceFileAssetQueryOptions, workspaceFileStatQueryOptions, workspaceInfoQueryOptions, workspaceQueryKey, workspaceTextFileQueryOptions };