@parallelworks/ui 0.18.0 → 0.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/README.md +86 -6
  2. package/dist/ai/adapter/memoryStore.d.ts +8 -0
  3. package/dist/ai/adapter/memoryStore.js +152 -0
  4. package/dist/ai/adapter/mock/index.d.ts +2 -0
  5. package/dist/ai/adapter/mock/index.js +3 -0
  6. package/dist/ai/adapter/mock/mockAdapter.d.ts +4 -0
  7. package/dist/ai/adapter/mock/mockAdapter.js +81 -0
  8. package/dist/ai/adapter/openai/createOpenAIStream.d.ts +9 -0
  9. package/dist/ai/adapter/openai/createOpenAIStream.js +33 -0
  10. package/dist/ai/adapter/openai/errors.d.ts +3 -0
  11. package/dist/ai/adapter/openai/errors.js +37 -0
  12. package/dist/ai/adapter/openai/index.d.ts +6 -0
  13. package/dist/ai/adapter/openai/index.js +6 -0
  14. package/dist/ai/adapter/openai/openaiAdapter.d.ts +9 -0
  15. package/dist/ai/adapter/openai/openaiAdapter.js +54 -0
  16. package/dist/ai/adapter/openai/responses.d.ts +4 -0
  17. package/dist/ai/adapter/openai/responses.js +108 -0
  18. package/dist/ai/adapter/openai/sse.d.ts +24 -0
  19. package/dist/ai/adapter/openai/sse.js +112 -0
  20. package/dist/ai/adapter/openai/wire.d.ts +40 -0
  21. package/dist/ai/adapter/types.d.ts +131 -0
  22. package/dist/ai/adapter/types.js +11 -0
  23. package/dist/ai/agent/classifier.d.ts +2 -0
  24. package/dist/ai/agent/classifier.js +12 -0
  25. package/dist/ai/agent/diff.d.ts +35 -0
  26. package/dist/ai/agent/diff.js +223 -0
  27. package/dist/ai/agent/diffHighlight.d.ts +6 -0
  28. package/dist/ai/agent/diffHighlight.js +101 -0
  29. package/dist/ai/agent/index.d.ts +6 -0
  30. package/dist/ai/agent/permissions.d.ts +11 -0
  31. package/dist/ai/agent/permissions.js +29 -0
  32. package/dist/ai/agent/toolfmt.d.ts +18 -0
  33. package/dist/ai/agent/toolfmt.js +383 -0
  34. package/dist/ai/agent/transcript.d.ts +38 -0
  35. package/dist/ai/agent/transcript.js +127 -0
  36. package/dist/ai/ai.css +325 -0
  37. package/dist/ai/components/AllocationSelector.d.ts +4 -0
  38. package/dist/ai/components/AllocationSelector.js +56 -0
  39. package/dist/ai/components/AttachmentManager.d.ts +1 -0
  40. package/dist/ai/components/AttachmentManager.js +144 -0
  41. package/dist/ai/components/AttachmentUpload.d.ts +24 -0
  42. package/dist/ai/components/AttachmentUpload.js +179 -0
  43. package/dist/ai/components/BlockedGroupBanner.d.ts +1 -0
  44. package/dist/ai/components/BlockedGroupBanner.js +29 -0
  45. package/dist/ai/components/BranchNavigator.d.ts +8 -0
  46. package/dist/ai/components/BranchNavigator.js +57 -0
  47. package/dist/ai/components/ChatEmptyState.d.ts +3 -0
  48. package/dist/ai/components/ChatEmptyState.js +171 -0
  49. package/dist/ai/components/ChatInput.d.ts +45 -0
  50. package/dist/ai/components/ChatInput.js +265 -0
  51. package/dist/ai/components/ChatLayout.d.ts +5 -0
  52. package/dist/ai/components/ChatLayout.js +15 -0
  53. package/dist/ai/components/ChatMessage.d.ts +24 -0
  54. package/dist/ai/components/ChatMessage.js +338 -0
  55. package/dist/ai/components/ChatMessageList.d.ts +35 -0
  56. package/dist/ai/components/ChatMessageList.js +301 -0
  57. package/dist/ai/components/ChatSidebar.d.ts +5 -0
  58. package/dist/ai/components/ChatSidebar.js +345 -0
  59. package/dist/ai/components/ChatThread.d.ts +3 -0
  60. package/dist/ai/components/ChatThread.js +198 -0
  61. package/dist/ai/components/ComposerChrome.d.ts +18 -0
  62. package/dist/ai/components/ComposerChrome.js +50 -0
  63. package/dist/ai/components/ComposerFrame.d.ts +16 -0
  64. package/dist/ai/components/ComposerFrame.js +33 -0
  65. package/dist/ai/components/DragOverlay.d.ts +5 -0
  66. package/dist/ai/components/DragOverlay.js +20 -0
  67. package/dist/ai/components/ModelSelector.d.ts +6 -0
  68. package/dist/ai/components/ModelSelector.js +343 -0
  69. package/dist/ai/components/ShareDialog.d.ts +11 -0
  70. package/dist/ai/components/ShareDialog.js +260 -0
  71. package/dist/ai/components/SlashMenu.d.ts +28 -0
  72. package/dist/ai/components/SlashMenu.js +91 -0
  73. package/dist/ai/components/agent/ActivityLine.d.ts +21 -0
  74. package/dist/ai/components/agent/ActivityLine.js +151 -0
  75. package/dist/ai/components/agent/AgentMessageParts.d.ts +54 -0
  76. package/dist/ai/components/agent/AgentMessageParts.js +721 -0
  77. package/dist/ai/components/agent/PermissionPicker.d.ts +11 -0
  78. package/dist/ai/components/agent/PermissionPicker.js +38 -0
  79. package/dist/ai/components/attachmentKeys.d.ts +4 -0
  80. package/dist/ai/components/attachmentKeys.js +10 -0
  81. package/dist/ai/core/ChatProvider.d.ts +66 -0
  82. package/dist/ai/core/ChatProvider.js +848 -0
  83. package/dist/ai/core/KeyboardShortcutsProvider.d.ts +5 -0
  84. package/dist/ai/core/KeyboardShortcutsProvider.js +9 -0
  85. package/dist/ai/core/chatReducer.d.ts +114 -0
  86. package/dist/ai/core/chatReducer.js +223 -0
  87. package/dist/ai/core/config.d.ts +47 -0
  88. package/dist/ai/core/config.js +45 -0
  89. package/dist/ai/core/events.d.ts +1 -0
  90. package/dist/ai/core/events.js +4 -0
  91. package/dist/ai/core/exportConversation.d.ts +4 -0
  92. package/dist/ai/core/exportConversation.js +42 -0
  93. package/dist/ai/core/greeting.d.ts +3 -0
  94. package/dist/ai/core/greeting.js +38 -0
  95. package/dist/ai/core/parts.d.ts +11 -0
  96. package/dist/ai/core/parts.js +84 -0
  97. package/dist/ai/core/useDragDrop.d.ts +14 -0
  98. package/dist/ai/core/useDragDrop.js +36 -0
  99. package/dist/ai/core/useKeyboardShortcuts.d.ts +12 -0
  100. package/dist/ai/core/useKeyboardShortcuts.js +77 -0
  101. package/dist/ai/core/useSSEStream.d.ts +34 -0
  102. package/dist/ai/core/useSSEStream.js +98 -0
  103. package/dist/ai/index.d.ts +40 -0
  104. package/dist/ai/index.js +44 -0
  105. package/dist/ai/strings.d.ts +167 -0
  106. package/dist/ai/strings.js +175 -0
  107. package/dist/ai/types.d.ts +236 -0
  108. package/dist/ai/ui/Avatar.d.ts +8 -0
  109. package/dist/ai/ui/Avatar.js +35 -0
  110. package/dist/ai/ui/Dropdown.d.ts +31 -0
  111. package/dist/ai/ui/Dropdown.js +110 -0
  112. package/dist/ai/ui/Markdown.d.ts +8 -0
  113. package/dist/ai/ui/Markdown.js +79 -0
  114. package/dist/ai/ui/Notice.d.ts +21 -0
  115. package/dist/ai/ui/Notice.js +77 -0
  116. package/dist/ai/ui/buttons.d.ts +1 -0
  117. package/dist/ai/ui/codeBreaks.d.ts +16 -0
  118. package/dist/ai/ui/codeBreaks.js +36 -0
  119. package/dist/ai/ui/prose.d.ts +1 -0
  120. package/dist/ai/ui/prose.js +13 -0
  121. package/dist/ai/ui/sidebar.d.ts +81 -0
  122. package/dist/ai/ui/sidebar.js +148 -0
  123. package/dist/ai/utils.d.ts +4 -0
  124. package/dist/ai/utils.js +23 -0
  125. package/dist/assets/{editor.worker-CuBRIwi-.js → editor.worker-BmHUIVG4.js} +194 -163
  126. package/dist/assets/{json.worker-8ytS02vz.js → json.worker-D8bJ92nw.js} +384 -338
  127. package/dist/assets/{yaml.worker-DJC-VUcv.js → yaml.worker-C4gyGAko.js} +15657 -13823
  128. package/dist/components/AddMenu.js +46 -0
  129. package/dist/components/Avatar.d.ts +1 -1
  130. package/dist/components/Avatar.js +46 -0
  131. package/dist/{chunks/BareModal-BtRiQezg.js → components/BareModal.js} +1 -1
  132. package/dist/components/Breadcrumbs.d.ts +1 -1
  133. package/dist/components/Breadcrumbs.js +83 -0
  134. package/dist/components/Button.js +83 -0
  135. package/dist/components/Callout.js +23 -0
  136. package/dist/components/Card.js +31 -0
  137. package/dist/components/CollapsiblePanel.js +77 -0
  138. package/dist/components/ConfirmModal.js +74 -0
  139. package/dist/components/CopyToClipboard.js +81 -0
  140. package/dist/{chunks/CreateModal-BY6DLmur.js → components/CreateModal.js} +10 -189
  141. package/dist/components/DescriptionList.js +42 -0
  142. package/dist/components/Dropdown.d.ts +1 -1
  143. package/dist/components/Dropdown.js +349 -0
  144. package/dist/components/EmptyState.d.ts +1 -1
  145. package/dist/components/EmptyState.js +27 -0
  146. package/dist/components/Filter.js +32 -0
  147. package/dist/components/FilterPill.js +13 -0
  148. package/dist/components/IconButton.js +34 -0
  149. package/dist/components/Indicator.d.ts +2 -2
  150. package/dist/{chunks/Indicator-hBSIxOPK.js → components/Indicator.js} +1 -1
  151. package/dist/components/Input.d.ts +1 -1
  152. package/dist/components/Input.js +88 -0
  153. package/dist/components/LetterBadge.d.ts +1 -1
  154. package/dist/components/LetterBadge.js +13 -0
  155. package/dist/components/Listbox.js +123 -0
  156. package/dist/{chunks/Loader-BXoXTZGc.js → components/Loader.js} +1 -1
  157. package/dist/components/Markdown.js +15 -0
  158. package/dist/components/MarkdownImpl.d.ts +1 -1
  159. package/dist/components/MultiSelect.js +171 -0
  160. package/dist/components/Overview.js +39 -0
  161. package/dist/components/PageHeader.js +194 -0
  162. package/dist/components/Pagination.js +35 -0
  163. package/dist/components/Provider.d.ts +16 -65
  164. package/dist/{chunks/Provider-Ghua9PkN.js → components/Provider.js} +54 -20
  165. package/dist/{chunks/RequiredMark-DfLdYbYZ.js → components/RequiredMark.js} +1 -1
  166. package/dist/components/SectionHeader.js +11 -0
  167. package/dist/components/SettingModeOption.js +30 -0
  168. package/dist/components/SettingRow.d.ts +1 -1
  169. package/dist/components/SettingRow.js +35 -0
  170. package/dist/components/SettingsCard.js +31 -0
  171. package/dist/components/SettingsGroup.d.ts +1 -1
  172. package/dist/components/SettingsGroup.js +17 -0
  173. package/dist/components/Sort.js +42 -0
  174. package/dist/components/StatusBadge.js +63 -0
  175. package/dist/components/SwitchToggle.js +59 -0
  176. package/dist/{chunks/SwitchToggleSmall-FcsaYSTs.js → components/SwitchToggleSmall.js} +1 -1
  177. package/dist/{chunks/Table-4OHjdKdO.js → components/Table.js} +7 -5
  178. package/dist/components/Toggle.js +20 -0
  179. package/dist/{chunks/Tooltip-Crxo_eU_.js → components/Tooltip.js} +6 -4
  180. package/dist/{chunks/StatusBadge-C1Blx_cW.js → components/dropdownUtils.js} +2 -63
  181. package/dist/components/focus.d.ts +2 -0
  182. package/dist/components/focus.js +7 -0
  183. package/dist/components/ghostButton.js +7 -0
  184. package/dist/components/inputClasses.js +4 -0
  185. package/dist/components/keys.d.ts +12 -0
  186. package/dist/components/keys.js +27 -0
  187. package/dist/components/relativeTime.js +32 -0
  188. package/dist/{chunks/useCssIsDark-DHr05dG2.js → components/useCssIsDark.js} +1 -1
  189. package/dist/duration.d.ts +3 -0
  190. package/dist/duration.js +17 -0
  191. package/dist/editor/Editor.js +13 -0
  192. package/dist/editor/EditorField.js +53 -0
  193. package/dist/editor/FormCodePanel.js +173 -0
  194. package/dist/editor/Monaco.d.ts +1 -20
  195. package/dist/editor/Monaco.js +112 -0
  196. package/dist/editor/index.d.ts +2 -1
  197. package/dist/editor/index.js +7 -2
  198. package/dist/editor/themes.js +91 -0
  199. package/dist/editor/workers.js +29 -0
  200. package/dist/editor/yaml.d.ts +5 -0
  201. package/dist/editor/yaml.js +15 -0
  202. package/dist/engine.d.ts +98 -0
  203. package/dist/file-explorer/FileExplorer.d.ts +11 -2
  204. package/dist/file-explorer/FileExplorer.js +1402 -0
  205. package/dist/file-explorer/FileExplorerContext.d.ts +1 -1
  206. package/dist/file-explorer/FileExplorerContext.js +370 -0
  207. package/dist/file-explorer/FilePreview/CodePreviewEditor.d.ts +1 -1
  208. package/dist/{chunks/CodePreviewEditor-4lx3kE-w.js → file-explorer/FilePreview/CodePreviewEditor.js} +3 -2
  209. package/dist/file-explorer/FilePreview/Inline.js +45 -0
  210. package/dist/file-explorer/FilePreview/StreamedBadge.js +16 -0
  211. package/dist/file-explorer/FilePreview/Viewer.js +526 -0
  212. package/dist/file-explorer/FilePreview/index.js +266 -0
  213. package/dist/file-explorer/FilePreview/parse.js +63 -0
  214. package/dist/file-explorer/FilePreview/previewCache.js +98 -0
  215. package/dist/file-explorer/FilePreview/previewType.d.ts +1 -1
  216. package/dist/file-explorer/FilePreview/previewType.js +151 -0
  217. package/dist/file-explorer/FilePreview/readCappedBytes.js +196 -0
  218. package/dist/file-explorer/FilePreview/useObjectBlobUrl.js +95 -0
  219. package/dist/file-explorer/FilePreview/useObjectText.js +109 -0
  220. package/dist/file-explorer/FilePreview/usePresignedUrl.js +73 -0
  221. package/dist/file-explorer/FileRow.d.ts +1 -1
  222. package/dist/file-explorer/FileRow.js +165 -0
  223. package/dist/file-explorer/FileRowsWindow.js +92 -0
  224. package/dist/file-explorer/FileTable.js +172 -0
  225. package/dist/file-explorer/FileTableHeaders.js +49 -0
  226. package/dist/file-explorer/LoadMoreRow.js +46 -0
  227. package/dist/file-explorer/TreeView.js +376 -0
  228. package/dist/file-explorer/helpers.d.ts +4 -4
  229. package/dist/file-explorer/helpers.js +537 -0
  230. package/dist/file-explorer/index.d.ts +3 -3
  231. package/dist/file-explorer/index.js +7 -5705
  232. package/dist/file-explorer/lib/batch.js +39 -0
  233. package/dist/file-explorer/lib/errors.js +9 -0
  234. package/dist/file-explorer/lib/paging.js +124 -0
  235. package/dist/file-explorer/lib/types.d.ts +6 -1
  236. package/dist/file-explorer/lib/utils.d.ts +1 -3
  237. package/dist/file-explorer/lib/utils.js +322 -0
  238. package/dist/file-explorer/toasts.js +400 -0
  239. package/dist/file-explorer/treeRows.js +73 -0
  240. package/dist/file-explorer/useNearEnd.d.ts +1 -1
  241. package/dist/file-explorer/useNearEnd.js +27 -0
  242. package/dist/form/FieldWrapper.d.ts +2 -2
  243. package/dist/form/FieldWrapper.js +54 -0
  244. package/dist/form/Fields/BooleanField.js +51 -0
  245. package/dist/form/Fields/CheckboxGroupField.js +72 -0
  246. package/dist/form/Fields/ColorField.js +33 -0
  247. package/dist/form/Fields/DropdownField.js +49 -0
  248. package/dist/form/Fields/DurationField.js +130 -0
  249. package/dist/form/Fields/LabelField.js +19 -0
  250. package/dist/form/Fields/MultiDropdownField.js +40 -0
  251. package/dist/form/Fields/NumberField.js +51 -0
  252. package/dist/form/Fields/ObjectField.js +54 -0
  253. package/dist/form/Fields/RadioField.js +49 -0
  254. package/dist/form/Fields/RangeField.js +58 -0
  255. package/dist/form/Fields/ResourceOptionIcon.d.ts +1 -1
  256. package/dist/form/Fields/ResourceOptionIcon.js +21 -0
  257. package/dist/form/Fields/StepField.js +6 -0
  258. package/dist/form/Fields/StringField.js +37 -0
  259. package/dist/form/Fields/TextAreaField.js +31 -0
  260. package/dist/form/Fields/durationValidity.js +11 -0
  261. package/dist/form/Form.d.ts +4 -21
  262. package/dist/form/Form.js +643 -0
  263. package/dist/form/SpecialTypes/DropdownWrapper.js +30 -0
  264. package/dist/form/SpecialTypes/FormikCustomDropdown.js +122 -0
  265. package/dist/form/SpecialTypes/FormikCustomInput.js +111 -0
  266. package/dist/form/SpecialTypes/FormikMultiSelectDropdown.js +31 -0
  267. package/dist/form/SpecialTypes/FormikNumericInput.js +60 -0
  268. package/dist/form/Wizard/WizardContainer.js +138 -0
  269. package/dist/form/Wizard/WizardNavigation.js +92 -0
  270. package/dist/form/Wizard/WizardStepContent.js +35 -0
  271. package/dist/form/Wizard/WizardStepIndicator.js +108 -0
  272. package/dist/form/Wizard/useWizardState.js +118 -0
  273. package/dist/form/Wizard/utils.js +34 -0
  274. package/dist/form/fieldContext.js +26 -0
  275. package/dist/form/fieldRegistry.js +50 -0
  276. package/dist/form/index.d.ts +11 -12
  277. package/dist/form/index.js +18 -2445
  278. package/dist/form/lib.d.ts +6 -1
  279. package/dist/{chunks/FieldWrapper-Bef01EWO.js → form/lib.js} +5 -104
  280. package/dist/form/types/fieldComponentTypes.d.ts +3 -2
  281. package/dist/form/types/fieldTypes.d.ts +6 -20
  282. package/dist/form/useParsedOpts.d.ts +1 -1
  283. package/dist/form/useParsedOpts.js +62 -0
  284. package/dist/form/usePrevious.js +11 -0
  285. package/dist/form/utils/checkShowIfObject.js +14 -0
  286. package/dist/form/utils/{slurmDuration.d.ts → duration.d.ts} +2 -2
  287. package/dist/form/utils/duration.js +69 -0
  288. package/dist/form/utils/getParentValue.js +23 -0
  289. package/dist/form/utils/getPlaceholder.js +9 -0
  290. package/dist/form/utils/getValueUsingPath.js +23 -0
  291. package/dist/form/utils/secondaryField.js +22 -0
  292. package/dist/graph/AnnotationBanner.js +141 -0
  293. package/dist/graph/Collapse.js +41 -0
  294. package/dist/{workflow/index.js → graph/DependencyGraph.js} +76 -1163
  295. package/dist/graph/JobSummary.js +104 -0
  296. package/dist/{workflow → graph}/MatrixGroup.d.ts +2 -2
  297. package/dist/graph/MatrixGroup.js +107 -0
  298. package/dist/graph/Reveal.js +57 -0
  299. package/dist/graph/TreeView.js +711 -0
  300. package/dist/{workflow → graph}/index.d.ts +1 -1
  301. package/dist/graph/index.js +2 -0
  302. package/dist/{workflow → graph}/types.d.ts +3 -3
  303. package/dist/graph/types.js +6 -0
  304. package/dist/icons.d.ts +20 -21
  305. package/dist/index.d.ts +38 -40
  306. package/dist/index.js +47 -599
  307. package/dist/list/ActionToolbar.js +184 -0
  308. package/dist/list/HoverCard.js +73 -0
  309. package/dist/list/ListPage.js +145 -0
  310. package/dist/list/ListPager.js +59 -0
  311. package/dist/list/ListTable.d.ts +1 -1
  312. package/dist/list/ListTable.js +163 -0
  313. package/dist/list/ListViewControls.d.ts +2 -2
  314. package/dist/list/ListViewControls.js +372 -0
  315. package/dist/list/RowContextMenu.js +350 -0
  316. package/dist/list/UserHoverCard.js +117 -0
  317. package/dist/list/index.d.ts +9 -9
  318. package/dist/list/index.js +11 -2
  319. package/dist/list/listSearch.js +137 -0
  320. package/dist/list/listView.js +210 -0
  321. package/dist/list/textEntry.js +10 -0
  322. package/dist/logviewer/LogViewer.d.ts +1 -1
  323. package/dist/logviewer/LogViewer.js +750 -0
  324. package/dist/logviewer/index.d.ts +1 -0
  325. package/dist/logviewer/index.js +3 -742
  326. package/dist/logviewer/segments.d.ts +9 -0
  327. package/dist/logviewer/segments.js +80 -0
  328. package/dist/styles/fonts.css +4 -4
  329. package/dist/styles/theme.css +6 -4
  330. package/dist/styles.css +1 -1
  331. package/dist/theme/index.js +2 -2
  332. package/package.json +38 -14
  333. package/LICENSE +0 -202
  334. package/dist/chunks/Monaco-C1POOdVv.js +0 -1046
  335. package/dist/chunks/PageHeader-l49p1nM9.js +0 -690
  336. package/dist/chunks/SwitchToggle-CHPP8uZQ.js +0 -755
  337. package/dist/chunks/editor-9_uVtUyy.js +0 -347
  338. package/dist/chunks/list-qrojZZNv.js +0 -1411
  339. package/dist/editor/usesGitlab.d.ts +0 -97
  340. package/dist/form/Fields/BucketReadOnlyField.d.ts +0 -7
  341. package/dist/form/types/workflow-schema.d.ts +0 -1145
  342. package/dist/form/utils/pwResolver.d.ts +0 -18
  343. package/dist/{chunks/MarkdownImpl-Bq4QhrtA.js → components/MarkdownImpl.js} +1 -1
  344. /package/dist/{workflow → graph}/AnnotationBanner.d.ts +0 -0
  345. /package/dist/{workflow → graph}/Collapse.d.ts +0 -0
  346. /package/dist/{workflow → graph}/DependencyGraph.d.ts +0 -0
  347. /package/dist/{workflow → graph}/JobSummary.d.ts +0 -0
  348. /package/dist/{workflow → graph}/Reveal.d.ts +0 -0
  349. /package/dist/{workflow → graph}/TreeView.d.ts +0 -0
@@ -0,0 +1,39 @@
1
+ //#region src/file-explorer/lib/batch.ts
2
+ async function* paginate(fetchPage, nextCursor) {
3
+ const seen = /* @__PURE__ */ new Set();
4
+ let cursor;
5
+ while (true) {
6
+ const page = await fetchPage(cursor);
7
+ yield page;
8
+ cursor = nextCursor(page);
9
+ if (!cursor || seen.has(cursor)) return;
10
+ seen.add(cursor);
11
+ }
12
+ }
13
+ function chunk(items, size) {
14
+ const chunks = [];
15
+ for (let i = 0; i < items.length; i += size) chunks.push(items.slice(i, i + size));
16
+ return chunks;
17
+ }
18
+ async function mapWithConcurrency(items, limit, worker) {
19
+ const results = new Array(items.length);
20
+ const queue = items.entries();
21
+ const run = async () => {
22
+ for (const [index, item] of queue) try {
23
+ results[index] = {
24
+ status: "fulfilled",
25
+ value: await worker(item)
26
+ };
27
+ } catch (reason) {
28
+ results[index] = {
29
+ status: "rejected",
30
+ reason
31
+ };
32
+ }
33
+ };
34
+ const workers = Array.from({ length: Math.min(limit, items.length) }, () => run());
35
+ await Promise.all(workers);
36
+ return results;
37
+ }
38
+ //#endregion
39
+ export { chunk, mapWithConcurrency, paginate };
@@ -0,0 +1,9 @@
1
+ //#region src/file-explorer/lib/errors.ts
2
+ var CorsError = class extends Error {
3
+ constructor(message) {
4
+ super(message || "CORS issue detected.");
5
+ this.name = "CorsError";
6
+ }
7
+ };
8
+ //#endregion
9
+ export { CorsError };
@@ -0,0 +1,124 @@
1
+ import { ensureTrailingSlash, getNodeName } from "./utils.js";
2
+ //#region src/file-explorer/lib/paging.ts
3
+ /** Both providers already cap an unqualified list at 1,000, so stating it leaves
4
+ * single-page directories byte-identical. */
5
+ var LIST_PAGE_SIZE = 1e3;
6
+ function isListed(listings, path) {
7
+ return (listings.get(path)?.pagesLoaded ?? 0) > 0;
8
+ }
9
+ /** True even while a request is in flight, so the sentinel stays put. */
10
+ function hasMore(listings, path) {
11
+ return !!listings.get(path)?.cursor;
12
+ }
13
+ /** A failed page needs an explicit retry, so it stops auto-loading here. */
14
+ function canLoadMore(listings, path) {
15
+ const listing = listings.get(path);
16
+ return !!listing?.cursor && !listing.loadingMore && !listing.error;
17
+ }
18
+ /** Auto-load stops at the cap; past it the user asks for each page. */
19
+ function canAutoLoadMore(listings, path) {
20
+ return canLoadMore(listings, path) && (listings.get(path)?.pagesLoaded ?? 0) < 5;
21
+ }
22
+ function isLoadingMore(listings, path) {
23
+ return listings.get(path)?.loadingMore === true;
24
+ }
25
+ function loadMoreError(listings, path) {
26
+ return listings.get(path)?.error;
27
+ }
28
+ function beginLoadingMore(listings, path) {
29
+ const listing = listings.get(path);
30
+ if (!listing) return listings;
31
+ return new Map(listings).set(path, {
32
+ ...listing,
33
+ loadingMore: true,
34
+ error: void 0
35
+ });
36
+ }
37
+ function advanceListing(listings, path, page) {
38
+ const listing = listings.get(path);
39
+ return new Map(listings).set(path, {
40
+ cursor: page.cursor,
41
+ pagesLoaded: (listing?.pagesLoaded ?? 0) + 1,
42
+ loadingMore: false,
43
+ entries: [...listing?.entries ?? [], ...page.entries]
44
+ });
45
+ }
46
+ /** Subfolders the page no longer names lose their records, or a re-created folder
47
+ * would show old contents; the rest keep theirs, since a refresh lists them
48
+ * alongside this one and a parent landing later must not undo a child's page. */
49
+ function replaceListing(listings, path, page) {
50
+ const prefix = ensureTrailingSlash(path);
51
+ const subfolders = new Set(page.entries.filter((entry) => entry.type === "directory").map(getNodeName));
52
+ const next = new Map(listings);
53
+ next.delete(path);
54
+ for (const key of listings.keys()) {
55
+ if (!key.startsWith(prefix)) continue;
56
+ if (!subfolders.has(key.slice(prefix.length).split("/")[0] ?? "")) next.delete(key);
57
+ }
58
+ return advanceListing(next, path, page);
59
+ }
60
+ /** `pagesLoaded` stays put, so a failed first page still reads as unlisted. */
61
+ function recordListingError(listings, path, error) {
62
+ const listing = listings.get(path);
63
+ return new Map(listings).set(path, {
64
+ cursor: listing?.cursor,
65
+ pagesLoaded: listing?.pagesLoaded ?? 0,
66
+ loadingMore: false,
67
+ error,
68
+ entries: listing?.entries ?? []
69
+ });
70
+ }
71
+ /** Keeps the cursor and pages, so a retry resumes paging instead of starting over. */
72
+ function clearListingError(listings, path) {
73
+ const listing = listings.get(path);
74
+ if (!listing) return listings;
75
+ return new Map(listings).set(path, {
76
+ ...listing,
77
+ error: void 0
78
+ });
79
+ }
80
+ function clearListingsUnder(listings, path) {
81
+ const prefix = ensureTrailingSlash(path);
82
+ const next = new Map(listings);
83
+ for (const key of listings.keys()) if (key === path || key.startsWith(prefix)) next.delete(key);
84
+ return next;
85
+ }
86
+ /** Tree paths whose children should keep arrival order, since sorting them would
87
+ * reshuffle rows under the user mid-scroll. */
88
+ function incompletePaths(listings) {
89
+ const paths = /* @__PURE__ */ new Set();
90
+ for (const [path, listing] of listings) if (listing.cursor) paths.add(path);
91
+ return paths;
92
+ }
93
+ /** What a deep link needs next. Pure so the walk is table-testable. */
94
+ function nextHydrationStep({ targetResolved, ancestors, isListableDir, listings, inFlight, pagesPulled }) {
95
+ for (const path of ancestors) {
96
+ if (!isListableDir(path)) continue;
97
+ if (inFlight.has(path)) return { kind: "done" };
98
+ if (!listings.has(path)) return {
99
+ kind: "fetch",
100
+ path
101
+ };
102
+ }
103
+ if (targetResolved) return { kind: "done" };
104
+ const deepest = [...ancestors].reverse().find(isListableDir);
105
+ if (!deepest) return { kind: "done" };
106
+ if (!hasMore(listings, deepest)) return {
107
+ kind: "stuck",
108
+ path: deepest
109
+ };
110
+ if (loadMoreError(listings, deepest)) return {
111
+ kind: "stuck",
112
+ path: deepest
113
+ };
114
+ if (pagesPulled >= 20) return {
115
+ kind: "stuck",
116
+ path: deepest
117
+ };
118
+ return isLoadingMore(listings, deepest) ? { kind: "done" } : {
119
+ kind: "more",
120
+ path: deepest
121
+ };
122
+ }
123
+ //#endregion
124
+ export { LIST_PAGE_SIZE, advanceListing, beginLoadingMore, canAutoLoadMore, clearListingError, clearListingsUnder, hasMore, incompletePaths, isListed, isLoadingMore, loadMoreError, nextHydrationStep, recordListingError, replaceListing };
@@ -15,8 +15,13 @@ export type TStorage = {
15
15
  canUpload?: boolean | undefined;
16
16
  canShare?: boolean | undefined;
17
17
  canManageAccess?: boolean | undefined;
18
- supportsPwUri?: boolean | undefined;
19
18
  };
19
+ /** A file the host is asked to name or download: its storage, key and name. */
20
+ export interface ExplorerObject {
21
+ storage: TStorage;
22
+ key: string;
23
+ name: string;
24
+ }
20
25
  export type TStorageObject = {
21
26
  path: string;
22
27
  type: 'file' | 'directory';
@@ -1,5 +1,5 @@
1
1
  import type { IFileExplorerClient } from './fileExplorer.js';
2
- import type { TStorage, TStorageObject, TreeMap, TreeNode, UploadNode } from './types.js';
2
+ import type { TreeMap, TreeNode, TStorage, TStorageObject, UploadNode } from './types.js';
3
3
  export declare function formatFileSize(bytes: number): string;
4
4
  export declare function getFileExtension(filename: string): string | null;
5
5
  export declare function getNodeName(node: TStorageObject): string;
@@ -33,8 +33,6 @@ export declare function attachmentDisposition(filename: string): string;
33
33
  export declare function getDirectoryPrefixFromNode(node: TreeNode): string;
34
34
  export declare function pruneNodesInsideSelectedDirectories(nodes: TreeNode[]): TreeNode[];
35
35
  export declare function collectObjectKeysToDelete(nodes: TreeNode[], listKeysUnderPrefix: (prefix: string) => Promise<string[]>): Promise<string[]>;
36
- export declare function getPwUri(username: string, pwName: string, key: string): string;
37
- export declare function getCspUri(csp: string, cspBucketName: string, key: string): string | null;
38
36
  export declare function getUriScheme(uri: string): string;
39
37
  export declare function removeLeadingSlash(path: string): string;
40
38
  export declare function removeLeadingAndTrailingSlashes(path: string): string;
@@ -0,0 +1,322 @@
1
+ //#region src/file-explorer/lib/utils.ts
2
+ function formatFileSize(bytes) {
3
+ if (bytes === 0) return "0 B";
4
+ const k = 1024;
5
+ const sizes = [
6
+ "B",
7
+ "KB",
8
+ "MB",
9
+ "GB",
10
+ "TB"
11
+ ];
12
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
13
+ return Number.parseFloat((bytes / k ** i).toFixed(2)) + " " + sizes[i];
14
+ }
15
+ function getFileExtension(filename) {
16
+ return filename.match(/\.([a-zA-Z0-9]+)$/)?.[1]?.toLowerCase() ?? null;
17
+ }
18
+ function getNodeName(node) {
19
+ const parts = removeTrailingSlash(node.path || "").split("/");
20
+ return parts[parts.length - 1] ?? "";
21
+ }
22
+ function toNode(entry, storage, storagePath, storageName) {
23
+ const relativePath = removeLeadingSlash(entry.path);
24
+ const isDirectory = entry.type === "directory";
25
+ return {
26
+ name: getNodeName(entry),
27
+ path: isDirectory ? ensureTrailingSlash(`${storagePath}${removeTrailingSlash(relativePath)}`) : `${storagePath}${relativePath}`,
28
+ relativePath: entry.key || (isDirectory ? entry.path : relativePath),
29
+ type: entry.type,
30
+ size: entry.size,
31
+ created: entry.created,
32
+ modified: entry.modified,
33
+ contentType: entry.contentType,
34
+ hash: entry.hash,
35
+ storageClass: entry.storageClass,
36
+ storageId: storage.id,
37
+ storageName
38
+ };
39
+ }
40
+ function compareNodes(a, b) {
41
+ if (a.type !== b.type) return a.type === "directory" ? -1 : 1;
42
+ return (a.displayName || a.name).localeCompare(b.displayName || b.name);
43
+ }
44
+ function extendsEntries(next, previous) {
45
+ return next.length >= previous.length && previous.every((entry, i) => next[i] === entry);
46
+ }
47
+ function childrenOf(dir, sorted) {
48
+ if (sorted) {
49
+ dir.sorted ??= [...dir.directories, ...dir.files].sort(compareNodes);
50
+ return dir.sorted;
51
+ }
52
+ dir.unsorted ??= [...dir.directories, ...dir.files];
53
+ return dir.unsorted;
54
+ }
55
+ /** One accumulator per listed directory, so a landed page costs the page and not
56
+ * the tree. One builder per explorer instance. */
57
+ function createTreeBuilder() {
58
+ const directories = /* @__PURE__ */ new Map();
59
+ let last = null;
60
+ function unchanged(storages, options) {
61
+ if (!last || last.storages !== storages || last.options.forceUserHierarchy !== options.forceUserHierarchy || last.options.unsortedParents !== options.unsortedParents) return false;
62
+ const before = last.options.listings;
63
+ if (options.listings.size !== before.size) return false;
64
+ for (const [dirPath, listing] of options.listings) if (before.get(dirPath)?.entries !== listing.entries) return false;
65
+ return true;
66
+ }
67
+ function nodesFor(dirPath, storage, storagePath, storageName, entries) {
68
+ const cached = directories.get(dirPath);
69
+ const reusable = cached?.storageName === storageName ? cached : void 0;
70
+ if (reusable && reusable.entries === entries) return reusable;
71
+ let dir;
72
+ if (reusable && extendsEntries(entries, reusable.entries)) dir = reusable;
73
+ else {
74
+ dir = {
75
+ entries: [],
76
+ storageName,
77
+ directories: [],
78
+ files: []
79
+ };
80
+ directories.set(dirPath, dir);
81
+ }
82
+ for (let i = dir.entries.length; i < entries.length; i++) {
83
+ const node = toNode(entries[i], storage, storagePath, storageName);
84
+ if (node.path === dirPath) continue;
85
+ if (node.type === "directory") dir.directories.push(node);
86
+ else dir.files.push(node);
87
+ }
88
+ dir.entries = entries;
89
+ dir.unsorted = void 0;
90
+ dir.sorted = void 0;
91
+ return dir;
92
+ }
93
+ function addStorage(storage, storagePath, options, tree) {
94
+ const storageName = storage.bucketName || storage.name;
95
+ const root = {
96
+ name: storage.name,
97
+ displayName: storage.displayName,
98
+ path: storagePath,
99
+ relativePath: "",
100
+ type: "directory",
101
+ created: storage.created,
102
+ modified: storage.modified,
103
+ storageId: storage.id,
104
+ storageName,
105
+ storageNodeIcon: storage.type,
106
+ storageImageUrl: storage.imageUrl,
107
+ storageType: storage.type,
108
+ root: true
109
+ };
110
+ tree.treeMap[storagePath] = root;
111
+ for (const [dirPath, listing] of options.listings) {
112
+ if (!dirPath.startsWith(storagePath)) continue;
113
+ const children = childrenOf(nodesFor(dirPath, storage, storagePath, storageName, listing.entries), !options.unsortedParents?.has(dirPath));
114
+ if (children.length === 0) continue;
115
+ for (const node of children) tree.treeMap[node.path] = node;
116
+ tree.parentToChildrenMap[dirPath] = children;
117
+ }
118
+ return root;
119
+ }
120
+ return (storages, options) => {
121
+ if (last && unchanged(storages, options)) return last.tree;
122
+ const tree = {
123
+ treeMap: {},
124
+ parentToChildrenMap: {},
125
+ rootNodes: []
126
+ };
127
+ if (storages.length === 1 && !options.forceUserHierarchy) {
128
+ const storage = storages[0];
129
+ const storagePath = ensureTrailingSlash(storage.user ? `${storage.user}/${storage.name}` : storage.name);
130
+ tree.rootNodes.push(addStorage(storage, storagePath, options, tree));
131
+ } else {
132
+ const userGroups = {};
133
+ for (const storage of storages) {
134
+ const username = storage.user ?? "";
135
+ if (!userGroups[username]) userGroups[username] = [];
136
+ userGroups[username].push(storage);
137
+ }
138
+ for (const username of Object.keys(userGroups)) {
139
+ const userPath = ensureTrailingSlash(username);
140
+ const userNode = {
141
+ name: username,
142
+ path: userPath,
143
+ type: "directory",
144
+ displayName: username
145
+ };
146
+ tree.treeMap[userPath] = userNode;
147
+ tree.rootNodes.push(userNode);
148
+ const storageRoots = (userGroups[username] ?? []).map((storage) => addStorage(storage, ensureTrailingSlash(`${userPath}${removeLeadingAndTrailingSlashes(storage.name)}`), options, tree));
149
+ tree.parentToChildrenMap[userPath] = storageRoots.sort(compareNodes);
150
+ }
151
+ }
152
+ for (const dirPath of directories.keys()) if (!options.listings.has(dirPath)) directories.delete(dirPath);
153
+ last = {
154
+ storages,
155
+ options,
156
+ tree
157
+ };
158
+ return tree;
159
+ };
160
+ }
161
+ function getNodeChildren(parentToChildrenMap, parentPath) {
162
+ return parentToChildrenMap[parentPath.endsWith("/") ? parentPath : parentPath + "/"] || [];
163
+ }
164
+ function getParentPath(currentPath) {
165
+ return ensureTrailingSlash(removeLastPathSegment(currentPath));
166
+ }
167
+ function getDirectoryNameError(name, siblings) {
168
+ if (name === "." || name === "..") return "reserved";
169
+ if (name.includes("/") || name.includes("\\")) return "separator";
170
+ if (siblings.some((node) => node.name === name)) return "exists";
171
+ return null;
172
+ }
173
+ function getDirectoryObjectPath(parentNode, directoryName) {
174
+ const parentPath = parentNode.root ? "" : removeLeadingAndTrailingSlashes(parentNode.relativePath ?? "");
175
+ return parentPath ? `${parentPath}/${directoryName}/` : `${directoryName}/`;
176
+ }
177
+ async function getUploadNodesFromDataTransferItems(items) {
178
+ const uploadNodes = [];
179
+ let totalSize = 0;
180
+ async function traverse(entry, path = "") {
181
+ return new Promise((resolve, reject) => {
182
+ if (entry.isFile) entry.file((file) => {
183
+ uploadNodes.push({
184
+ name: file.name,
185
+ file,
186
+ relativePath: path ? path + file.name : file.name
187
+ });
188
+ totalSize += file.size;
189
+ resolve();
190
+ }, reject);
191
+ else if (entry.isDirectory) entry.createReader().readEntries(async (entries) => {
192
+ const newPath = path ? path + entry.name + "/" : entry.name + "/";
193
+ if (entries.length === 0) uploadNodes.push({
194
+ name: entry.name,
195
+ file: new Blob(),
196
+ relativePath: newPath
197
+ });
198
+ else for (const entry of entries) await traverse(entry, newPath);
199
+ resolve();
200
+ }, reject);
201
+ else resolve();
202
+ });
203
+ }
204
+ const entries = [];
205
+ for (let i = 0; i < items.length; i++) {
206
+ const entry = items[i]?.webkitGetAsEntry?.();
207
+ if (entry) entries.push(entry);
208
+ }
209
+ for (const entry of entries) await traverse(entry);
210
+ return {
211
+ uploadNodes,
212
+ totalSize
213
+ };
214
+ }
215
+ function calculateUploadNodesTotalSize(uploadNodes) {
216
+ return uploadNodes.reduce((total, node) => {
217
+ return total + (node.file?.size || 0);
218
+ }, 0);
219
+ }
220
+ function getObjectKeyFromNode(node) {
221
+ return node.relativePath || node.path.split("/").filter(Boolean).slice(1).join("/");
222
+ }
223
+ function attachmentDisposition(filename) {
224
+ return `attachment; filename="${filename.replace(/[^\x20-\x7e]|["\\]/g, "_")}"; filename*=UTF-8''${encodeURIComponent(filename).replace(/['()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`)}`;
225
+ }
226
+ function getDirectoryPrefixFromNode(node) {
227
+ const key = getObjectKeyFromNode(node);
228
+ if (!key) throw new Error(`Cannot resolve an object prefix for ${node.path}`);
229
+ return ensureTrailingSlash(key);
230
+ }
231
+ function pruneNodesInsideSelectedDirectories(nodes) {
232
+ const directoryPaths = nodes.filter((node) => node.type === "directory").map((node) => ensureTrailingSlash(node.path));
233
+ return nodes.filter((node) => !directoryPaths.some((directoryPath) => node.path !== directoryPath && node.path.startsWith(directoryPath)));
234
+ }
235
+ async function collectObjectKeysToDelete(nodes, listKeysUnderPrefix) {
236
+ const keys = /* @__PURE__ */ new Set();
237
+ for (const node of nodes) {
238
+ if (node.type !== "directory") {
239
+ keys.add(getObjectKeyFromNode(node));
240
+ continue;
241
+ }
242
+ const prefix = getDirectoryPrefixFromNode(node);
243
+ const found = await listKeysUnderPrefix(prefix);
244
+ for (const key of found.filter((key) => key.startsWith(prefix))) keys.add(key);
245
+ }
246
+ return Array.from(keys);
247
+ }
248
+ function getUriScheme(uri) {
249
+ return uri.match(/^([a-z0-9+.-]+):\/\//i)?.[1] ?? "";
250
+ }
251
+ function removeLeadingSlash(path) {
252
+ return path.replace(/^\/+/, "");
253
+ }
254
+ function removeTrailingSlash(path) {
255
+ return path.replace(/\/$/, "");
256
+ }
257
+ function removeLeadingAndTrailingSlashes(path) {
258
+ return path.replace(/^\/+|\/+$/g, "");
259
+ }
260
+ function removeLastPathSegment(path) {
261
+ return path.replace(/\/[^/]+\/?$/, "");
262
+ }
263
+ function ensureTrailingSlash(path) {
264
+ return path.endsWith("/") ? path : path + "/";
265
+ }
266
+ function isClientValid(client) {
267
+ if (!client?.getExpiresAt) return false;
268
+ const expiresAt = client.getExpiresAt();
269
+ return expiresAt && expiresAt > /* @__PURE__ */ new Date();
270
+ }
271
+ function getUploadSessionETA(totalLoadedBytes, totalSizeBytes, lastProgressTime, lastProgressBytes) {
272
+ const now = Date.now();
273
+ const MAX_ETA_SECONDS = 86400;
274
+ if (!lastProgressTime || !lastProgressBytes) return {
275
+ lastProgressTime: now,
276
+ lastProgressBytes: totalLoadedBytes,
277
+ shouldUpdateETA: false
278
+ };
279
+ const timeDiff = now - lastProgressTime;
280
+ const bytesDiff = totalLoadedBytes - lastProgressBytes;
281
+ if (timeDiff < 1e3) return {
282
+ lastProgressTime,
283
+ lastProgressBytes,
284
+ shouldUpdateETA: false
285
+ };
286
+ if (bytesDiff > 0 && timeDiff > 0) {
287
+ const bytesPerSecond = bytesDiff / timeDiff * 1e3;
288
+ const remainingBytes = totalSizeBytes - totalLoadedBytes;
289
+ if (remainingBytes <= 0) return {
290
+ estimatedSecondsLeft: 0,
291
+ lastProgressTime: now,
292
+ lastProgressBytes: totalLoadedBytes,
293
+ shouldUpdateETA: true
294
+ };
295
+ let eta = Math.ceil(remainingBytes / bytesPerSecond);
296
+ eta = Math.max(1, Math.min(eta, MAX_ETA_SECONDS));
297
+ return {
298
+ estimatedSecondsLeft: eta,
299
+ lastProgressTime: now,
300
+ lastProgressBytes: totalLoadedBytes,
301
+ shouldUpdateETA: true
302
+ };
303
+ }
304
+ return {
305
+ lastProgressTime,
306
+ lastProgressBytes,
307
+ shouldUpdateETA: false
308
+ };
309
+ }
310
+ function formatETA(seconds) {
311
+ if (seconds <= 0) return "Almost done";
312
+ if (seconds < 5) return "Few seconds";
313
+ if (seconds < 60) return `~ ${seconds}s`;
314
+ if (seconds < 3600) {
315
+ const mins = Math.floor(seconds / 60);
316
+ const secs = seconds % 60;
317
+ return secs > 0 ? `~ ${mins}m ${secs}s` : `~ ${mins}m`;
318
+ }
319
+ return `~ ${Math.floor(seconds / 3600)}h ${Math.ceil(seconds % 3600 / 60)}m`;
320
+ }
321
+ //#endregion
322
+ export { attachmentDisposition, calculateUploadNodesTotalSize, collectObjectKeysToDelete, createTreeBuilder, ensureTrailingSlash, formatETA, formatFileSize, getDirectoryNameError, getDirectoryObjectPath, getDirectoryPrefixFromNode, getFileExtension, getNodeChildren, getNodeName, getObjectKeyFromNode, getParentPath, getUploadNodesFromDataTransferItems, getUploadSessionETA, getUriScheme, isClientValid, pruneNodesInsideSelectedDirectories, removeLeadingAndTrailingSlashes, removeLeadingSlash };