@arbidocs/react 0.5.111 → 0.5.112

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 (983) hide show
  1. package/dist/account/client.js +96 -0
  2. package/dist/account/client.js.map +7 -0
  3. package/dist/account/delete.js +70 -0
  4. package/dist/account/delete.js.map +7 -0
  5. package/dist/account/didit.js +34 -0
  6. package/dist/account/didit.js.map +7 -0
  7. package/dist/account/dismissed-tips.js +33 -0
  8. package/dist/account/dismissed-tips.js.map +7 -0
  9. package/dist/account/email.js +84 -0
  10. package/dist/account/email.js.map +7 -0
  11. package/dist/account/entitlements.js +47 -0
  12. package/dist/account/entitlements.js.map +7 -0
  13. package/dist/account/identity.js +270 -0
  14. package/dist/account/identity.js.map +7 -0
  15. package/dist/account/index.js +93 -0
  16. package/dist/account/index.js.map +7 -0
  17. package/dist/account/notifications.js +59 -0
  18. package/dist/account/notifications.js.map +7 -0
  19. package/dist/account/password.js +103 -0
  20. package/dist/account/password.js.map +7 -0
  21. package/dist/account/profile.js +116 -0
  22. package/dist/account/profile.js.map +7 -0
  23. package/dist/account/recovery.js +13 -0
  24. package/dist/account/recovery.js.map +7 -0
  25. package/dist/account/relevance.js +82 -0
  26. package/dist/account/relevance.js.map +7 -0
  27. package/dist/account/sessions.js +37 -0
  28. package/dist/account/sessions.js.map +7 -0
  29. package/dist/account/settings.js +39 -0
  30. package/dist/account/settings.js.map +7 -0
  31. package/dist/account/table-views.js +16 -0
  32. package/dist/account/table-views.js.map +7 -0
  33. package/dist/ai/AiAnswer.js +83 -0
  34. package/dist/ai/AiAnswer.js.map +7 -0
  35. package/dist/ai/AiMarkdown.js +40 -0
  36. package/dist/ai/AiMarkdown.js.map +7 -0
  37. package/dist/ai/ArtifactCanvas.js +193 -0
  38. package/dist/ai/ArtifactCanvas.js.map +7 -0
  39. package/dist/ai/CitationRenderer.js +413 -0
  40. package/dist/ai/CitationRenderer.js.map +7 -0
  41. package/dist/{chunk-WL2Y2T47.js → ai/MarkdownRenderer.js} +35 -101
  42. package/dist/ai/MarkdownRenderer.js.map +7 -0
  43. package/dist/ai/MessageArtifactCard.js +75 -0
  44. package/dist/ai/MessageArtifactCard.js.map +7 -0
  45. package/dist/ai/PassageCard.js +79 -0
  46. package/dist/ai/PassageCard.js.map +7 -0
  47. package/dist/ai/engine.js +110 -0
  48. package/dist/ai/engine.js.map +7 -0
  49. package/dist/ai/index.js +63 -0
  50. package/dist/ai/index.js.map +7 -0
  51. package/dist/ai/markdown-base-components.js +37 -0
  52. package/dist/ai/markdown-base-components.js.map +7 -0
  53. package/dist/ai/markdown-streaming-context.js +6 -0
  54. package/dist/ai/markdown-streaming-context.js.map +7 -0
  55. package/dist/{chunk-VSCU7K4V.js → ai/normalize-citations.js} +12 -19
  56. package/dist/ai/normalize-citations.js.map +7 -0
  57. package/dist/ai/redline.js +41 -0
  58. package/dist/ai/redline.js.map +7 -0
  59. package/dist/ai/split-markdown-blocks.js +40 -0
  60. package/dist/ai/split-markdown-blocks.js.map +7 -0
  61. package/dist/{chunk-UW2SGTI5.js → ai/stored-markdown.js} +41 -93
  62. package/dist/ai/stored-markdown.js.map +7 -0
  63. package/dist/annotations/AnnotationPageOverlay.js +807 -0
  64. package/dist/annotations/AnnotationPageOverlay.js.map +7 -0
  65. package/dist/annotations/AnnotationToolbar.js +398 -0
  66. package/dist/annotations/AnnotationToolbar.js.map +7 -0
  67. package/dist/annotations/FreezeDialog.js +170 -0
  68. package/dist/annotations/FreezeDialog.js.map +7 -0
  69. package/dist/annotations/ProductionDialog.js +354 -0
  70. package/dist/annotations/ProductionDialog.js.map +7 -0
  71. package/dist/annotations/controller.js +49 -0
  72. package/dist/annotations/controller.js.map +7 -0
  73. package/dist/annotations/freeze/browser.js +21 -0
  74. package/dist/annotations/freeze/browser.js.map +7 -0
  75. package/dist/annotations/freeze/bundle.js +201 -0
  76. package/dist/annotations/freeze/bundle.js.map +7 -0
  77. package/dist/annotations/freeze/coords.js +37 -0
  78. package/dist/annotations/freeze/coords.js.map +7 -0
  79. package/dist/annotations/freeze/freeze.js +261 -0
  80. package/dist/annotations/freeze/freeze.js.map +7 -0
  81. package/dist/annotations/freeze/hash.js +28 -0
  82. package/dist/annotations/freeze/hash.js.map +7 -0
  83. package/dist/annotations/freeze/index-page.js +78 -0
  84. package/dist/annotations/freeze/index-page.js.map +7 -0
  85. package/dist/annotations/freeze/index.js +28 -22
  86. package/dist/annotations/freeze/index.js.map +7 -1
  87. package/dist/annotations/freeze/raster.js +208 -0
  88. package/dist/annotations/freeze/raster.js.map +7 -0
  89. package/dist/annotations/freeze/stamp.js +117 -0
  90. package/dist/annotations/freeze/stamp.js.map +7 -0
  91. package/dist/annotations/freeze/types.js +14 -0
  92. package/dist/annotations/freeze/types.js.map +7 -0
  93. package/dist/annotations/freeze/vector.js +283 -0
  94. package/dist/annotations/freeze/vector.js.map +7 -0
  95. package/dist/annotations/geometry.js +81 -0
  96. package/dist/annotations/geometry.js.map +7 -0
  97. package/dist/annotations/index.js +125 -6
  98. package/dist/annotations/index.js.map +7 -1
  99. package/dist/annotations/merge.js +53 -0
  100. package/dist/annotations/merge.js.map +7 -0
  101. package/dist/{chunk-T3USOSVN.js → annotations/model.js} +23 -16
  102. package/dist/annotations/model.js.map +7 -0
  103. package/dist/annotations/overlay-geometry.js +41 -0
  104. package/dist/annotations/overlay-geometry.js.map +7 -0
  105. package/dist/annotations/redaction-log.js +33 -0
  106. package/dist/annotations/redaction-log.js.map +7 -0
  107. package/dist/annotations/selection-marks.js +122 -0
  108. package/dist/annotations/selection-marks.js.map +7 -0
  109. package/dist/annotations/state.js +140 -0
  110. package/dist/annotations/state.js.map +7 -0
  111. package/dist/annotations/store.js +49 -0
  112. package/dist/annotations/store.js.map +7 -0
  113. package/dist/annotations/useAnnotationLayer.js +306 -0
  114. package/dist/annotations/useAnnotationLayer.js.map +7 -0
  115. package/dist/annotations/useAnnotationShortcuts.js +31 -0
  116. package/dist/annotations/useAnnotationShortcuts.js.map +7 -0
  117. package/dist/annotations/useTextSelectionMarks.js +100 -0
  118. package/dist/annotations/useTextSelectionMarks.js.map +7 -0
  119. package/dist/artifacts/artifact-kind.js +19 -0
  120. package/dist/artifacts/artifact-kind.js.map +7 -0
  121. package/dist/artifacts/index.js +89 -571
  122. package/dist/artifacts/index.js.map +7 -1
  123. package/dist/{chunk-WUTL62MC.js → artifacts/normalize-markdown.js} +12 -14
  124. package/dist/artifacts/normalize-markdown.js.map +7 -0
  125. package/dist/artifacts/redline-core.js +12 -3
  126. package/dist/artifacts/redline-core.js.map +7 -1
  127. package/dist/{chunk-74N436VK.js → artifacts/redline-diff.js} +10 -9
  128. package/dist/artifacts/redline-diff.js.map +7 -0
  129. package/dist/artifacts/redline-engine.js +14 -0
  130. package/dist/artifacts/redline-engine.js.map +7 -0
  131. package/dist/artifacts/renderArtifactMarkdown.js +9 -0
  132. package/dist/artifacts/renderArtifactMarkdown.js.map +7 -0
  133. package/dist/artifacts/useArtifactEditSession.js +183 -0
  134. package/dist/artifacts/useArtifactEditSession.js.map +7 -0
  135. package/dist/artifacts/useArtifactSession.js +173 -0
  136. package/dist/artifacts/useArtifactSession.js.map +7 -0
  137. package/dist/artifacts/useArtifactSource.js +16 -0
  138. package/dist/artifacts/useArtifactSource.js.map +7 -0
  139. package/dist/artifacts/useArtifactText.js +78 -0
  140. package/dist/artifacts/useArtifactText.js.map +7 -0
  141. package/dist/artifacts/useRedline.js +65 -0
  142. package/dist/artifacts/useRedline.js.map +7 -0
  143. package/dist/artifacts/useStreamedArtifact.js +74 -0
  144. package/dist/artifacts/useStreamedArtifact.js.map +7 -0
  145. package/dist/artifacts/versions.js +68 -0
  146. package/dist/artifacts/versions.js.map +7 -0
  147. package/dist/billing.js +200 -0
  148. package/dist/billing.js.map +7 -0
  149. package/dist/boot-timeout.js +19 -0
  150. package/dist/boot-timeout.js.map +7 -0
  151. package/dist/calendar/accounts.js +213 -0
  152. package/dist/calendar/accounts.js.map +7 -0
  153. package/dist/calendar/hooks.js +409 -0
  154. package/dist/calendar/hooks.js.map +7 -0
  155. package/dist/calendar/index.js +31 -0
  156. package/dist/calendar/index.js.map +7 -0
  157. package/dist/calendar/keys.js +5 -0
  158. package/dist/calendar/keys.js.map +7 -0
  159. package/dist/calendar/offline/outbox.js +231 -0
  160. package/dist/calendar/offline/outbox.js.map +7 -0
  161. package/dist/calendar/offline/runtime.js +109 -0
  162. package/dist/calendar/offline/runtime.js.map +7 -0
  163. package/dist/calendar/offline/support.js +41 -0
  164. package/dist/calendar/offline/support.js.map +7 -0
  165. package/dist/calendar/support.js +34 -0
  166. package/dist/calendar/support.js.map +7 -0
  167. package/dist/calls/actions.js +226 -0
  168. package/dist/calls/actions.js.map +7 -0
  169. package/dist/calls/events.js +138 -0
  170. package/dist/calls/events.js.map +7 -0
  171. package/dist/calls/gate.js +19 -0
  172. package/dist/calls/gate.js.map +7 -0
  173. package/dist/calls/hooks.js +115 -0
  174. package/dist/calls/hooks.js.map +7 -0
  175. package/dist/calls/in-call-chat.js +132 -0
  176. package/dist/calls/in-call-chat.js.map +7 -0
  177. package/dist/calls/index.js +24 -0
  178. package/dist/calls/index.js.map +7 -0
  179. package/dist/calls/keys.js +17 -0
  180. package/dist/calls/keys.js.map +7 -0
  181. package/dist/calls/livekit/index.js +6 -958
  182. package/dist/calls/livekit/index.js.map +7 -1
  183. package/dist/calls/livekit/room.js +98 -0
  184. package/dist/calls/livekit/room.js.map +7 -0
  185. package/dist/calls/livekit/useCallRecorder.js +219 -0
  186. package/dist/calls/livekit/useCallRecorder.js.map +7 -0
  187. package/dist/calls/livekit/useCallTranscriber.js +309 -0
  188. package/dist/calls/livekit/useCallTranscriber.js.map +7 -0
  189. package/dist/calls/livekit/useHostMuteNotice.js +29 -0
  190. package/dist/calls/livekit/useHostMuteNotice.js.map +7 -0
  191. package/dist/calls/livekit/useInCallChat.js +161 -0
  192. package/dist/calls/livekit/useInCallChat.js.map +7 -0
  193. package/dist/calls/livekit/useWebinar.js +239 -0
  194. package/dist/calls/livekit/useWebinar.js.map +7 -0
  195. package/dist/calls/meeting-chat.js +149 -0
  196. package/dist/calls/meeting-chat.js.map +7 -0
  197. package/dist/calls/moderation.js +50 -0
  198. package/dist/calls/moderation.js.map +7 -0
  199. package/dist/calls/open-meeting-chat.js +29 -0
  200. package/dist/calls/open-meeting-chat.js.map +7 -0
  201. package/dist/calls/read-only.js +24 -0
  202. package/dist/calls/read-only.js.map +7 -0
  203. package/dist/calls/recording-media.js +218 -0
  204. package/dist/calls/recording-media.js.map +7 -0
  205. package/dist/calls/recording-playback.js +260 -0
  206. package/dist/calls/recording-playback.js.map +7 -0
  207. package/dist/calls/recording.js +268 -0
  208. package/dist/calls/recording.js.map +7 -0
  209. package/dist/calls/save-to-thread.js +80 -0
  210. package/dist/calls/save-to-thread.js.map +7 -0
  211. package/dist/calls/session.js +134 -0
  212. package/dist/calls/session.js.map +7 -0
  213. package/dist/calls/transcript-format.js +147 -0
  214. package/dist/calls/transcript-format.js.map +7 -0
  215. package/dist/calls/transcription.js +101 -0
  216. package/dist/calls/transcription.js.map +7 -0
  217. package/dist/calls/webinar.js +71 -0
  218. package/dist/calls/webinar.js.map +7 -0
  219. package/dist/charge-watch.js +71 -0
  220. package/dist/charge-watch.js.map +7 -0
  221. package/dist/chat/ChatBubble.js +146 -0
  222. package/dist/chat/ChatBubble.js.map +7 -0
  223. package/dist/chat/ConversationScope.js +30 -0
  224. package/dist/chat/ConversationScope.js.map +7 -0
  225. package/dist/chat/active-config.js +20 -0
  226. package/dist/chat/active-config.js.map +7 -0
  227. package/dist/chat/agent-chat-owner.js +25 -0
  228. package/dist/chat/agent-chat-owner.js.map +7 -0
  229. package/dist/chat/chat-artifacts.js +64 -0
  230. package/dist/chat/chat-artifacts.js.map +7 -0
  231. package/dist/chat/citations.js +32 -0
  232. package/dist/chat/citations.js.map +7 -0
  233. package/dist/chat/config-model.js +10 -0
  234. package/dist/chat/config-model.js.map +7 -0
  235. package/dist/chat/conversation-cache.js +676 -0
  236. package/dist/chat/conversation-cache.js.map +7 -0
  237. package/dist/chat/conversation-events.js +57 -0
  238. package/dist/chat/conversation-events.js.map +7 -0
  239. package/dist/chat/conversation-mentions.js +58 -0
  240. package/dist/chat/conversation-mentions.js.map +7 -0
  241. package/dist/chat/conversation-workspace.js +58 -0
  242. package/dist/chat/conversation-workspace.js.map +7 -0
  243. package/dist/chat/mentions.js +116 -0
  244. package/dist/chat/mentions.js.map +7 -0
  245. package/dist/chat/open-document.js +106 -0
  246. package/dist/chat/open-document.js.map +7 -0
  247. package/dist/chat/orphaned.js +44 -0
  248. package/dist/chat/orphaned.js.map +7 -0
  249. package/dist/chat/pendingFirstTurn.js +30 -0
  250. package/dist/chat/pendingFirstTurn.js.map +7 -0
  251. package/dist/chat/reply-target.js +12 -0
  252. package/dist/chat/reply-target.js.map +7 -0
  253. package/dist/chat/run-finished.js +28 -0
  254. package/dist/chat/run-finished.js.map +7 -0
  255. package/dist/chat/run-state.js +91 -0
  256. package/dist/chat/run-state.js.map +7 -0
  257. package/dist/chat/stream-handlers.js +419 -0
  258. package/dist/chat/stream-handlers.js.map +7 -0
  259. package/dist/chat/thread-binding.js +76 -0
  260. package/dist/chat/thread-binding.js.map +7 -0
  261. package/dist/chat/thread-document.js +53 -0
  262. package/dist/chat/thread-document.js.map +7 -0
  263. package/dist/chat/turn-control.js +79 -0
  264. package/dist/chat/turn-control.js.map +7 -0
  265. package/dist/chat/useAgentRunControl.js +36 -0
  266. package/dist/chat/useAgentRunControl.js.map +7 -0
  267. package/dist/chat/useAnswerAgentQuestion.js +19 -0
  268. package/dist/chat/useAnswerAgentQuestion.js.map +7 -0
  269. package/dist/chat/useAskAgain.js +32 -0
  270. package/dist/chat/useAskAgain.js.map +7 -0
  271. package/dist/chat/useAutoSendDraft.js +17 -0
  272. package/dist/chat/useAutoSendDraft.js.map +7 -0
  273. package/dist/chat/useBranchNavigation.js +97 -0
  274. package/dist/chat/useBranchNavigation.js.map +7 -0
  275. package/dist/chat/useConnectRunStream.js +169 -0
  276. package/dist/chat/useConnectRunStream.js.map +7 -0
  277. package/dist/chat/useConversation.js +431 -0
  278. package/dist/chat/useConversation.js.map +7 -0
  279. package/dist/chat/useConversationActions.js +662 -0
  280. package/dist/chat/useConversationActions.js.map +7 -0
  281. package/dist/chat/useConversationData.js +143 -0
  282. package/dist/chat/useConversationData.js.map +7 -0
  283. package/dist/chat/useConversationDocuments.js +41 -0
  284. package/dist/chat/useConversationDocuments.js.map +7 -0
  285. package/dist/chat/useConversationSettings.js +78 -0
  286. package/dist/chat/useConversationSettings.js.map +7 -0
  287. package/dist/chat/useConversationTurn.js +31 -0
  288. package/dist/chat/useConversationTurn.js.map +7 -0
  289. package/dist/chat/useConversationWorkspace.js +12 -0
  290. package/dist/chat/useConversationWorkspace.js.map +7 -0
  291. package/dist/chat/useDeleteMessage.js +15 -0
  292. package/dist/chat/useDeleteMessage.js.map +7 -0
  293. package/dist/chat/useDocumentAutoAdd.js +73 -0
  294. package/dist/chat/useDocumentAutoAdd.js.map +7 -0
  295. package/dist/chat/useMessageTimer.js +39 -0
  296. package/dist/chat/useMessageTimer.js.map +7 -0
  297. package/dist/chat/useThinkingContent.js +67 -0
  298. package/dist/chat/useThinkingContent.js.map +7 -0
  299. package/dist/chat/useThreadDocument.js +61 -0
  300. package/dist/chat/useThreadDocument.js.map +7 -0
  301. package/dist/chat/workflow-run-titles.js +50 -0
  302. package/dist/chat/workflow-run-titles.js.map +7 -0
  303. package/dist/{chunk-Z3W4XFWB.cjs → chunk-C72FSQUE.cjs} +3 -3
  304. package/dist/{chunk-Z3W4XFWB.cjs.map → chunk-C72FSQUE.cjs.map} +1 -1
  305. package/dist/{chunk-LBAG7KL7.cjs → chunk-FQVNZCTD.cjs} +3 -3
  306. package/dist/{chunk-LBAG7KL7.cjs.map → chunk-FQVNZCTD.cjs.map} +1 -1
  307. package/dist/{chunk-DI5KSVKY.cjs → chunk-UDDJIUHJ.cjs} +3 -3
  308. package/dist/{chunk-DI5KSVKY.cjs.map → chunk-UDDJIUHJ.cjs.map} +1 -1
  309. package/dist/config/config-hooks.js +209 -0
  310. package/dist/config/config-hooks.js.map +7 -0
  311. package/dist/connectivity.js +72 -0
  312. package/dist/connectivity.js.map +7 -0
  313. package/dist/connectors/hooks.js +263 -0
  314. package/dist/connectors/hooks.js.map +7 -0
  315. package/dist/connectors/index.js +28 -0
  316. package/dist/connectors/index.js.map +7 -0
  317. package/dist/contacts.js +100 -0
  318. package/dist/contacts.js.map +7 -0
  319. package/dist/conversation-list.js +65 -0
  320. package/dist/conversation-list.js.map +7 -0
  321. package/dist/databases.js +195 -0
  322. package/dist/databases.js.map +7 -0
  323. package/dist/datasets/aggregate.js +281 -0
  324. package/dist/datasets/aggregate.js.map +7 -0
  325. package/dist/datasets/index.js +122 -0
  326. package/dist/datasets/index.js.map +7 -0
  327. package/dist/datasets/members.js +27 -0
  328. package/dist/datasets/members.js.map +7 -0
  329. package/dist/datasets/panel.js +44 -0
  330. package/dist/datasets/panel.js.map +7 -0
  331. package/dist/datasets/registry.js +47 -0
  332. package/dist/datasets/registry.js.map +7 -0
  333. package/dist/datasets/rows-source.js +44 -0
  334. package/dist/datasets/rows-source.js.map +7 -0
  335. package/dist/datasets/sources/activity.js +83 -0
  336. package/dist/datasets/sources/activity.js.map +7 -0
  337. package/dist/datasets/sources/conversations.js +74 -0
  338. package/dist/datasets/sources/conversations.js.map +7 -0
  339. package/dist/datasets/sources/database.js +209 -0
  340. package/dist/datasets/sources/database.js.map +7 -0
  341. package/dist/datasets/sources/documents.js +93 -0
  342. package/dist/datasets/sources/documents.js.map +7 -0
  343. package/dist/datasets/sources/facts.js +56 -0
  344. package/dist/datasets/sources/facts.js.map +7 -0
  345. package/dist/datasets/sources/projects.js +117 -0
  346. package/dist/datasets/sources/projects.js.map +7 -0
  347. package/dist/datasets/sources/tags.js +67 -0
  348. package/dist/datasets/sources/tags.js.map +7 -0
  349. package/dist/datasets/sources/usage.js +268 -0
  350. package/dist/datasets/sources/usage.js.map +7 -0
  351. package/dist/datasets/sources/workflows.js +91 -0
  352. package/dist/datasets/sources/workflows.js.map +7 -0
  353. package/dist/datasets/sources/workspaces.js +67 -0
  354. package/dist/datasets/sources/workspaces.js.map +7 -0
  355. package/dist/datasets/store.js +194 -0
  356. package/dist/datasets/store.js.map +7 -0
  357. package/dist/datasets/types.js +14 -0
  358. package/dist/datasets/types.js.map +7 -0
  359. package/dist/directmessages/ConversationList.js +148 -0
  360. package/dist/directmessages/ConversationList.js.map +7 -0
  361. package/dist/directmessages/DateSeparator.js +8 -0
  362. package/dist/directmessages/DateSeparator.js.map +7 -0
  363. package/dist/directmessages/DmAvatar.js +29 -0
  364. package/dist/directmessages/DmAvatar.js.map +7 -0
  365. package/dist/directmessages/DmComposer.js +201 -0
  366. package/dist/directmessages/DmComposer.js.map +7 -0
  367. package/dist/directmessages/arrivals.js +29 -0
  368. package/dist/directmessages/arrivals.js.map +7 -0
  369. package/dist/directmessages/chat-cache.js +192 -0
  370. package/dist/directmessages/chat-cache.js.map +7 -0
  371. package/dist/directmessages/grouping.js +26 -0
  372. package/dist/directmessages/grouping.js.map +7 -0
  373. package/dist/directmessages/index.js +81 -0
  374. package/dist/directmessages/index.js.map +7 -0
  375. package/dist/directmessages/useChats.js +266 -0
  376. package/dist/directmessages/useChats.js.map +7 -0
  377. package/dist/directmessages/utils.js +23 -0
  378. package/dist/directmessages/utils.js.map +7 -0
  379. package/dist/document-tools/can-annotate.js +7 -0
  380. package/dist/document-tools/can-annotate.js.map +7 -0
  381. package/dist/document-tools/core.cjs +80 -80
  382. package/dist/document-tools/core.js +218 -12
  383. package/dist/document-tools/core.js.map +7 -1
  384. package/dist/document-tools/document-pdf.js +76 -0
  385. package/dist/document-tools/document-pdf.js.map +7 -0
  386. package/dist/document-tools/environment.js +136 -0
  387. package/dist/document-tools/environment.js.map +7 -0
  388. package/dist/document-tools/file-shares.js +112 -0
  389. package/dist/document-tools/file-shares.js.map +7 -0
  390. package/dist/document-tools/frozen-copy.js +27 -0
  391. package/dist/document-tools/frozen-copy.js.map +7 -0
  392. package/dist/document-tools/index.cjs +80 -80
  393. package/dist/document-tools/index.js +26 -148
  394. package/dist/document-tools/index.js.map +7 -1
  395. package/dist/document-tools/markup-download.js +51 -0
  396. package/dist/document-tools/markup-download.js.map +7 -0
  397. package/dist/document-tools/markup-store.js +138 -0
  398. package/dist/document-tools/markup-store.js.map +7 -0
  399. package/dist/document-tools/markup-transfer.js +88 -0
  400. package/dist/document-tools/markup-transfer.js.map +7 -0
  401. package/dist/document-tools/production.js +147 -0
  402. package/dist/document-tools/production.js.map +7 -0
  403. package/dist/document-tools/saved-signature.js +90 -0
  404. package/dist/document-tools/saved-signature.js.map +7 -0
  405. package/dist/document-tools/signature-requests.js +310 -0
  406. package/dist/document-tools/signature-requests.js.map +7 -0
  407. package/dist/document-tools/signing.js +127 -0
  408. package/dist/document-tools/signing.js.map +7 -0
  409. package/dist/document-tools/useDocumentBytes.js +38 -0
  410. package/dist/document-tools/useDocumentBytes.js.map +7 -0
  411. package/dist/document-tools/useDocumentMarkup.js +154 -0
  412. package/dist/document-tools/useDocumentMarkup.js.map +7 -0
  413. package/dist/document-tools/useIsOnline.js +13 -0
  414. package/dist/document-tools/useIsOnline.js.map +7 -0
  415. package/dist/document-tools/verification.js +60 -0
  416. package/dist/document-tools/verification.js.map +7 -0
  417. package/dist/documents/DocumentReview.js +220 -0
  418. package/dist/documents/DocumentReview.js.map +7 -0
  419. package/dist/documents/DraftTitleControls.js +41 -0
  420. package/dist/documents/DraftTitleControls.js.map +7 -0
  421. package/dist/documents/InlineMicButton.js +90 -0
  422. package/dist/documents/InlineMicButton.js.map +7 -0
  423. package/dist/documents/MicRecordingOverlay.js +29 -0
  424. package/dist/documents/MicRecordingOverlay.js.map +7 -0
  425. package/dist/documents/MicWaveformIndicator.js +68 -0
  426. package/dist/documents/MicWaveformIndicator.js.map +7 -0
  427. package/dist/documents/PhotoCapture.js +120 -0
  428. package/dist/documents/PhotoCapture.js.map +7 -0
  429. package/dist/documents/VideoCapture.js +129 -0
  430. package/dist/documents/VideoCapture.js.map +7 -0
  431. package/dist/documents/VoiceNoteRecorder.js +166 -0
  432. package/dist/documents/VoiceNoteRecorder.js.map +7 -0
  433. package/dist/documents/audio-segmenter.js +63 -0
  434. package/dist/documents/audio-segmenter.js.map +7 -0
  435. package/dist/documents/capture-frame.js +21 -0
  436. package/dist/documents/capture-frame.js.map +7 -0
  437. package/dist/documents/chunked-recorder.js +190 -0
  438. package/dist/documents/chunked-recorder.js.map +7 -0
  439. package/dist/documents/document-download.js +53 -0
  440. package/dist/documents/document-download.js.map +7 -0
  441. package/dist/documents/document-fields.js +109 -0
  442. package/dist/documents/document-fields.js.map +7 -0
  443. package/dist/documents/documents-cache.js +110 -0
  444. package/dist/documents/documents-cache.js.map +7 -0
  445. package/dist/documents/documents-data.js +128 -0
  446. package/dist/documents/documents-data.js.map +7 -0
  447. package/dist/documents/documents-loader.js +113 -0
  448. package/dist/documents/documents-loader.js.map +7 -0
  449. package/dist/documents/documents-writes.js +448 -0
  450. package/dist/documents/documents-writes.js.map +7 -0
  451. package/dist/documents/format-elapsed.js +10 -0
  452. package/dist/documents/format-elapsed.js.map +7 -0
  453. package/dist/documents/has-video-track.js +26 -0
  454. package/dist/documents/has-video-track.js.map +7 -0
  455. package/dist/documents/index.js +266 -0
  456. package/dist/documents/index.js.map +7 -0
  457. package/dist/documents/media-error.js +18 -0
  458. package/dist/documents/media-error.js.map +7 -0
  459. package/dist/documents/offline-documents.js +160 -0
  460. package/dist/documents/offline-documents.js.map +7 -0
  461. package/dist/documents/pending-sync.js +210 -0
  462. package/dist/documents/pending-sync.js.map +7 -0
  463. package/dist/documents/processing-live.js +122 -0
  464. package/dist/documents/processing-live.js.map +7 -0
  465. package/dist/documents/processing-order.js +59 -0
  466. package/dist/documents/processing-order.js.map +7 -0
  467. package/dist/documents/processing-settle.js +21 -0
  468. package/dist/documents/processing-settle.js.map +7 -0
  469. package/dist/documents/related-documents.js +133 -0
  470. package/dist/documents/related-documents.js.map +7 -0
  471. package/dist/documents/support.js +29 -0
  472. package/dist/documents/support.js.map +7 -0
  473. package/dist/documents/upload-files.js +169 -0
  474. package/dist/documents/upload-files.js.map +7 -0
  475. package/dist/documents/useAudioRecorder.js +315 -0
  476. package/dist/documents/useAudioRecorder.js.map +7 -0
  477. package/dist/documents/useCameraStream.js +35 -0
  478. package/dist/documents/useCameraStream.js.map +7 -0
  479. package/dist/documents/useDocumentThumbnails.js +71 -0
  480. package/dist/documents/useDocumentThumbnails.js.map +7 -0
  481. package/dist/documents/useDownloadDocuments.js +90 -0
  482. package/dist/documents/useDownloadDocuments.js.map +7 -0
  483. package/dist/documents/usePassageQuotes.js +37 -0
  484. package/dist/documents/usePassageQuotes.js.map +7 -0
  485. package/dist/documents/useUploadFiles.js +165 -0
  486. package/dist/documents/useUploadFiles.js.map +7 -0
  487. package/dist/documents/useUploadFromUrls.js +63 -0
  488. package/dist/documents/useUploadFromUrls.js.map +7 -0
  489. package/dist/documents/useVideoRecorder.js +62 -0
  490. package/dist/documents/useVideoRecorder.js.map +7 -0
  491. package/dist/entities/AgentMarkers.js +61 -0
  492. package/dist/entities/AgentMarkers.js.map +7 -0
  493. package/dist/entities/DocumentEntity.js +125 -0
  494. package/dist/entities/DocumentEntity.js.map +7 -0
  495. package/dist/entities/EntityPill.js +250 -0
  496. package/dist/entities/EntityPill.js.map +7 -0
  497. package/dist/entities/ProjectEntity.js +61 -0
  498. package/dist/entities/ProjectEntity.js.map +7 -0
  499. package/dist/entities/ShieldIcon.js +49 -0
  500. package/dist/entities/ShieldIcon.js.map +7 -0
  501. package/dist/entities/TagEntity.js +79 -0
  502. package/dist/entities/TagEntity.js.map +7 -0
  503. package/dist/entities/ThreadVisibilityIcon.js +15 -0
  504. package/dist/entities/ThreadVisibilityIcon.js.map +7 -0
  505. package/dist/entities/UserEntity.js +211 -0
  506. package/dist/entities/UserEntity.js.map +7 -0
  507. package/dist/entities/VerifiedBadge.js +19 -0
  508. package/dist/entities/VerifiedBadge.js.map +7 -0
  509. package/dist/entities/agent-avatar-colors.js +26 -0
  510. package/dist/entities/agent-avatar-colors.js.map +7 -0
  511. package/dist/entities/colors.js +64 -0
  512. package/dist/entities/colors.js.map +7 -0
  513. package/dist/entities/file-type.js +151 -0
  514. package/dist/entities/file-type.js.map +7 -0
  515. package/dist/entities/index.js +100 -0
  516. package/dist/entities/index.js.map +7 -0
  517. package/dist/entities/media-type.js +61 -0
  518. package/dist/entities/media-type.js.map +7 -0
  519. package/dist/entities/registry.js +385 -0
  520. package/dist/entities/registry.js.map +7 -0
  521. package/dist/entities/status.js +43 -0
  522. package/dist/entities/status.js.map +7 -0
  523. package/dist/entities/tag-kinds.js +23 -0
  524. package/dist/entities/tag-kinds.js.map +7 -0
  525. package/dist/entities/tag-types.js +44 -0
  526. package/dist/entities/tag-types.js.map +7 -0
  527. package/dist/entities/vocabulary.js +12 -0
  528. package/dist/entities/vocabulary.js.map +7 -0
  529. package/dist/entity-extraction.js +25 -0
  530. package/dist/entity-extraction.js.map +7 -0
  531. package/dist/facts-search.js +57 -0
  532. package/dist/facts-search.js.map +7 -0
  533. package/dist/facts.js +69 -0
  534. package/dist/facts.js.map +7 -0
  535. package/dist/hooks.js +320 -0
  536. package/dist/hooks.js.map +7 -0
  537. package/dist/host/ArbiHost.js +24 -0
  538. package/dist/host/ArbiHost.js.map +7 -0
  539. package/dist/host/assistant-copy.js +54 -0
  540. package/dist/host/assistant-copy.js.map +7 -0
  541. package/dist/host/config.js +9 -0
  542. package/dist/host/config.js.map +7 -0
  543. package/dist/host/context.js +10 -0
  544. package/dist/host/context.js.map +7 -0
  545. package/dist/host/features.js +144 -0
  546. package/dist/host/features.js.map +7 -0
  547. package/dist/host/index.js +12 -0
  548. package/dist/host/index.js.map +7 -0
  549. package/dist/{chunk-DPYBZDJB.js → host/merge.js} +7 -7
  550. package/dist/host/merge.js.map +7 -0
  551. package/dist/house-template.js +40 -0
  552. package/dist/house-template.js.map +7 -0
  553. package/dist/icons/AppleIcon.js +25 -0
  554. package/dist/icons/AppleIcon.js.map +7 -0
  555. package/dist/icons/ArbiBotHeadIcon.js +46 -0
  556. package/dist/icons/ArbiBotHeadIcon.js.map +7 -0
  557. package/dist/icons/ArbiIcon.js +24 -0
  558. package/dist/icons/ArbiIcon.js.map +7 -0
  559. package/dist/icons/AudIcon.js +56 -0
  560. package/dist/icons/AudIcon.js.map +7 -0
  561. package/dist/icons/ClaudeIcon.js +28 -0
  562. package/dist/icons/ClaudeIcon.js.map +7 -0
  563. package/dist/icons/DocIcon.js +56 -0
  564. package/dist/icons/DocIcon.js.map +7 -0
  565. package/dist/icons/EmlIcon.js +57 -0
  566. package/dist/icons/EmlIcon.js.map +7 -0
  567. package/dist/icons/FireworksIcon.js +47 -0
  568. package/dist/icons/FireworksIcon.js.map +7 -0
  569. package/dist/icons/GeminiIcon.js +37 -0
  570. package/dist/icons/GeminiIcon.js.map +7 -0
  571. package/dist/icons/GitHubIcon.js +32 -0
  572. package/dist/icons/GitHubIcon.js.map +7 -0
  573. package/dist/icons/GoogleIcon.js +53 -0
  574. package/dist/icons/GoogleIcon.js.map +7 -0
  575. package/dist/icons/HtmlIcon.js +56 -0
  576. package/dist/icons/HtmlIcon.js.map +7 -0
  577. package/dist/icons/ImgIcon.js +56 -0
  578. package/dist/icons/ImgIcon.js.map +7 -0
  579. package/dist/icons/LinkedInIcon.js +25 -0
  580. package/dist/icons/LinkedInIcon.js.map +7 -0
  581. package/dist/icons/OpenAIIcon.js +28 -0
  582. package/dist/icons/OpenAIIcon.js.map +7 -0
  583. package/dist/icons/PdfIcon.js +56 -0
  584. package/dist/icons/PdfIcon.js.map +7 -0
  585. package/dist/icons/ProviderIcon.js +42 -0
  586. package/dist/icons/ProviderIcon.js.map +7 -0
  587. package/dist/icons/TxtIcon.js +56 -0
  588. package/dist/icons/TxtIcon.js.map +7 -0
  589. package/dist/icons/VidIcon.js +56 -0
  590. package/dist/icons/VidIcon.js.map +7 -0
  591. package/dist/icons/XlsIcon.js +56 -0
  592. package/dist/icons/XlsIcon.js.map +7 -0
  593. package/dist/icons/arbi-mark.js +5 -0
  594. package/dist/icons/arbi-mark.js.map +7 -0
  595. package/dist/icons/colors.js +31 -0
  596. package/dist/icons/colors.js.map +7 -0
  597. package/dist/icons/file-type.js +105 -0
  598. package/dist/icons/file-type.js.map +7 -0
  599. package/dist/icons/index.js +55 -0
  600. package/dist/icons/index.js.map +7 -0
  601. package/dist/imagecrop/ImageCropModal.js +56 -0
  602. package/dist/imagecrop/ImageCropModal.js.map +7 -0
  603. package/dist/imagecrop/ImageCropper.js +100 -0
  604. package/dist/imagecrop/ImageCropper.js.map +7 -0
  605. package/dist/imagecrop/cropImage.js +43 -0
  606. package/dist/imagecrop/cropImage.js.map +7 -0
  607. package/dist/imagecrop/index.js +13 -0
  608. package/dist/imagecrop/index.js.map +7 -0
  609. package/dist/index.cjs +282 -282
  610. package/dist/index.js +702 -17116
  611. package/dist/index.js.map +7 -1
  612. package/dist/{chunk-SSXFVWCT.js → lazy-chunk.js} +8 -8
  613. package/dist/lazy-chunk.js.map +7 -0
  614. package/dist/lib/collision-padding.js +13 -0
  615. package/dist/lib/collision-padding.js.map +7 -0
  616. package/dist/lib/format-friendly-date.js +55 -0
  617. package/dist/lib/format-friendly-date.js.map +7 -0
  618. package/dist/lib/format-relative-time.js +52 -0
  619. package/dist/lib/format-relative-time.js.map +7 -0
  620. package/dist/lib/markdown-to-text.js +35 -0
  621. package/dist/lib/markdown-to-text.js.map +7 -0
  622. package/dist/lib/toast-interaction.js +9 -0
  623. package/dist/lib/toast-interaction.js.map +7 -0
  624. package/dist/lib/utils.js +9 -0
  625. package/dist/lib/utils.js.map +7 -0
  626. package/dist/mail/client.js +103 -0
  627. package/dist/mail/client.js.map +7 -0
  628. package/dist/mail/document-attachment.js +38 -0
  629. package/dist/mail/document-attachment.js.map +7 -0
  630. package/dist/mail/filing.js +132 -0
  631. package/dist/mail/filing.js.map +7 -0
  632. package/dist/mail/hooks.js +393 -0
  633. package/dist/mail/hooks.js.map +7 -0
  634. package/dist/mail/index.js +120 -0
  635. package/dist/mail/index.js.map +7 -0
  636. package/dist/mail/offline/changes.js +258 -0
  637. package/dist/mail/offline/changes.js.map +7 -0
  638. package/dist/mail/offline/confirm-sign-out.js +37 -0
  639. package/dist/mail/offline/confirm-sign-out.js.map +7 -0
  640. package/dist/mail/offline/crypto.js +26 -0
  641. package/dist/mail/offline/crypto.js.map +7 -0
  642. package/dist/mail/offline/drafts.js +69 -0
  643. package/dist/mail/offline/drafts.js.map +7 -0
  644. package/dist/mail/offline/hooks.js +104 -0
  645. package/dist/mail/offline/hooks.js.map +7 -0
  646. package/dist/mail/offline/index.js +48 -0
  647. package/dist/mail/offline/index.js.map +7 -0
  648. package/dist/mail/offline/live.js +233 -0
  649. package/dist/mail/offline/live.js.map +7 -0
  650. package/dist/mail/offline/mailbox.js +191 -0
  651. package/dist/mail/offline/mailbox.js.map +7 -0
  652. package/dist/mail/offline/outbox.js +167 -0
  653. package/dist/mail/offline/outbox.js.map +7 -0
  654. package/dist/mail/offline/reads.js +159 -0
  655. package/dist/mail/offline/reads.js.map +7 -0
  656. package/dist/mail/offline/runtime.js +100 -0
  657. package/dist/mail/offline/runtime.js.map +7 -0
  658. package/dist/mail/offline/settings.js +84 -0
  659. package/dist/mail/offline/settings.js.map +7 -0
  660. package/dist/mail/offline/store.js +29 -0
  661. package/dist/mail/offline/store.js.map +7 -0
  662. package/dist/mail/offline/sync.js +251 -0
  663. package/dist/mail/offline/sync.js.map +7 -0
  664. package/dist/mail/offline/wipe.js +19 -0
  665. package/dist/mail/offline/wipe.js.map +7 -0
  666. package/dist/mail/thread-keys.js +53 -0
  667. package/dist/mail/thread-keys.js.map +7 -0
  668. package/dist/mail/threads.js +71 -0
  669. package/dist/mail/threads.js.map +7 -0
  670. package/dist/mail/useMailClient.js +42 -0
  671. package/dist/mail/useMailClient.js.map +7 -0
  672. package/dist/model-connections.js +58 -0
  673. package/dist/model-connections.js.map +7 -0
  674. package/dist/notifications/ActivityFeed.js +70 -0
  675. package/dist/notifications/ActivityFeed.js.map +7 -0
  676. package/dist/notifications/NotificationBell.js +200 -0
  677. package/dist/notifications/NotificationBell.js.map +7 -0
  678. package/dist/notifications/Toaster.js +24 -0
  679. package/dist/notifications/Toaster.js.map +7 -0
  680. package/dist/notifications/activity-types.js +65 -0
  681. package/dist/notifications/activity-types.js.map +7 -0
  682. package/dist/notifications/bell.js +24 -0
  683. package/dist/notifications/bell.js.map +7 -0
  684. package/dist/notifications/calendar-notifications.js +79 -0
  685. package/dist/notifications/calendar-notifications.js.map +7 -0
  686. package/dist/notifications/index.js +108 -0
  687. package/dist/notifications/index.js.map +7 -0
  688. package/dist/notifications/live.js +28 -0
  689. package/dist/notifications/live.js.map +7 -0
  690. package/dist/notifications/notification-types.js +127 -0
  691. package/dist/notifications/notification-types.js.map +7 -0
  692. package/dist/{chunk-BF5KW5ZI.js → notifications/notify-store.js} +24 -74
  693. package/dist/notifications/notify-store.js.map +7 -0
  694. package/dist/notifications/server-notifications.js +452 -0
  695. package/dist/notifications/server-notifications.js.map +7 -0
  696. package/dist/notifications/useNotifications.js +34 -0
  697. package/dist/notifications/useNotifications.js.map +7 -0
  698. package/dist/offline-store/network.js +11 -0
  699. package/dist/offline-store/network.js.map +7 -0
  700. package/dist/offline-store/store.js +136 -0
  701. package/dist/offline-store/store.js.map +7 -0
  702. package/dist/offline-store/wipe.js +8 -0
  703. package/dist/offline-store/wipe.js.map +7 -0
  704. package/dist/offline.js +58 -0
  705. package/dist/offline.js.map +7 -0
  706. package/dist/people.js +122 -0
  707. package/dist/people.js.map +7 -0
  708. package/dist/projects.js +30 -0
  709. package/dist/projects.js.map +7 -0
  710. package/dist/query-client.js +63 -0
  711. package/dist/query-client.js.map +7 -0
  712. package/dist/{chunk-ZM6N7YZH.js → query-keys.js} +18 -31
  713. package/dist/query-keys.js.map +7 -0
  714. package/dist/query-persist.js +66 -0
  715. package/dist/query-persist.js.map +7 -0
  716. package/dist/queued-writes.js +59 -0
  717. package/dist/queued-writes.js.map +7 -0
  718. package/dist/remote-control.js +67 -0
  719. package/dist/remote-control.js.map +7 -0
  720. package/dist/search/index.js +23 -0
  721. package/dist/search/index.js.map +7 -0
  722. package/dist/search/session.js +58 -0
  723. package/dist/search/session.js.map +7 -0
  724. package/dist/search/useSemanticSearch.js +82 -0
  725. package/dist/search/useSemanticSearch.js.map +7 -0
  726. package/dist/session/chat.js +512 -0
  727. package/dist/session/chat.js.map +7 -0
  728. package/dist/session/documents.js +196 -0
  729. package/dist/session/documents.js.map +7 -0
  730. package/dist/session/drafts.js +103 -0
  731. package/dist/session/drafts.js.map +7 -0
  732. package/dist/session/index.js +123 -0
  733. package/dist/session/index.js.map +7 -0
  734. package/dist/session/layout.js +339 -0
  735. package/dist/session/layout.js.map +7 -0
  736. package/dist/session/persist.js +106 -0
  737. package/dist/session/persist.js.map +7 -0
  738. package/dist/session/session-hooks.js +53 -0
  739. package/dist/session/session-hooks.js.map +7 -0
  740. package/dist/session/signed-in.js +36 -0
  741. package/dist/session/signed-in.js.map +7 -0
  742. package/dist/session/store.js +166 -0
  743. package/dist/session/store.js.map +7 -0
  744. package/dist/session/thread-tabs.js +121 -0
  745. package/dist/session/thread-tabs.js.map +7 -0
  746. package/dist/session/ui-state-storage.js +76 -0
  747. package/dist/session/ui-state-storage.js.map +7 -0
  748. package/dist/session/workspace.js +77 -0
  749. package/dist/session/workspace.js.map +7 -0
  750. package/dist/shell/index.cjs +37 -37
  751. package/dist/shell/index.js +43 -10
  752. package/dist/shell/index.js.map +7 -1
  753. package/dist/skill-pack.js +111 -0
  754. package/dist/skill-pack.js.map +7 -0
  755. package/dist/storage.js +186 -0
  756. package/dist/storage.js.map +7 -0
  757. package/dist/support/index.js +35 -0
  758. package/dist/support/index.js.map +7 -0
  759. package/dist/tags.js +204 -0
  760. package/dist/tags.js.map +7 -0
  761. package/dist/ui/DebouncedInput.js +109 -0
  762. package/dist/ui/DebouncedInput.js.map +7 -0
  763. package/dist/ui/DictateContext.js +8 -0
  764. package/dist/ui/DictateContext.js.map +7 -0
  765. package/dist/ui/IconToggle.js +79 -0
  766. package/dist/ui/IconToggle.js.map +7 -0
  767. package/dist/ui/VerifiedToggle.js +38 -0
  768. package/dist/ui/VerifiedToggle.js.map +7 -0
  769. package/dist/ui/VisibilityToggle.js +103 -0
  770. package/dist/ui/VisibilityToggle.js.map +7 -0
  771. package/dist/ui/avatar.js +40 -0
  772. package/dist/ui/avatar.js.map +7 -0
  773. package/dist/ui/badge.js +28 -0
  774. package/dist/ui/badge.js.map +7 -0
  775. package/dist/ui/button.js +48 -0
  776. package/dist/ui/button.js.map +7 -0
  777. package/dist/ui/card.js +90 -0
  778. package/dist/ui/card.js.map +7 -0
  779. package/dist/ui/checkbox.js +22 -0
  780. package/dist/ui/checkbox.js.map +7 -0
  781. package/dist/ui/collapsible.js +10 -0
  782. package/dist/ui/collapsible.js.map +7 -0
  783. package/dist/ui/command.js +103 -0
  784. package/dist/ui/command.js.map +7 -0
  785. package/dist/{chunk-YNNAJJ5Z.js → ui/dialog.js} +30 -68
  786. package/dist/ui/dialog.js.map +7 -0
  787. package/dist/{chunk-47CCGUWR.js → ui/dropdown-menu.js} +40 -45
  788. package/dist/ui/dropdown-menu.js.map +7 -0
  789. package/dist/ui/hover-card.js +36 -0
  790. package/dist/ui/hover-card.js.map +7 -0
  791. package/dist/ui/index.cjs +154 -154
  792. package/dist/ui/index.js +290 -10
  793. package/dist/ui/index.js.map +7 -1
  794. package/dist/ui/input.js +65 -0
  795. package/dist/ui/input.js.map +7 -0
  796. package/dist/ui/label.js +16 -0
  797. package/dist/ui/label.js.map +7 -0
  798. package/dist/ui/mark-menu.js +300 -0
  799. package/dist/ui/mark-menu.js.map +7 -0
  800. package/dist/ui/popover.js +40 -0
  801. package/dist/ui/popover.js.map +7 -0
  802. package/dist/ui/portal-container.js +17 -0
  803. package/dist/ui/portal-container.js.map +7 -0
  804. package/dist/ui/progress.js +24 -0
  805. package/dist/ui/progress.js.map +7 -0
  806. package/dist/ui/radio-group.js +29 -0
  807. package/dist/ui/radio-group.js.map +7 -0
  808. package/dist/ui/scroll-area.js +39 -0
  809. package/dist/ui/scroll-area.js.map +7 -0
  810. package/dist/ui/select.js +130 -0
  811. package/dist/ui/select.js.map +7 -0
  812. package/dist/ui/separator.js +23 -0
  813. package/dist/ui/separator.js.map +7 -0
  814. package/dist/ui/slider.js +23 -0
  815. package/dist/ui/slider.js.map +7 -0
  816. package/dist/ui/switch.js +28 -0
  817. package/dist/ui/switch.js.map +7 -0
  818. package/dist/ui/table.js +75 -0
  819. package/dist/ui/table.js.map +7 -0
  820. package/dist/ui/tabs.js +48 -0
  821. package/dist/ui/tabs.js.map +7 -0
  822. package/dist/ui/textarea.js +63 -0
  823. package/dist/ui/textarea.js.map +7 -0
  824. package/dist/ui/toggle-group.js +43 -0
  825. package/dist/ui/toggle-group.js.map +7 -0
  826. package/dist/ui/toggle.js +40 -0
  827. package/dist/ui/toggle.js.map +7 -0
  828. package/dist/ui/tooltip.js +215 -0
  829. package/dist/ui/tooltip.js.map +7 -0
  830. package/dist/usage-metered.js +8 -0
  831. package/dist/usage-metered.js.map +7 -0
  832. package/dist/useArbi.js +16 -0
  833. package/dist/useArbi.js.map +7 -0
  834. package/dist/useInstallSkillPack.js +81 -0
  835. package/dist/useInstallSkillPack.js.map +7 -0
  836. package/dist/usermenu/UserMenu.js +188 -0
  837. package/dist/usermenu/UserMenu.js.map +7 -0
  838. package/dist/usermenu/index.js +5 -0
  839. package/dist/usermenu/index.js.map +7 -0
  840. package/dist/users/index.js +15 -0
  841. package/dist/users/index.js.map +7 -0
  842. package/dist/users/user-display.js +60 -0
  843. package/dist/users/user-display.js.map +7 -0
  844. package/dist/viewers/AudioViewer.js +23 -0
  845. package/dist/viewers/AudioViewer.js.map +7 -0
  846. package/dist/viewers/DocxViewer.js +81 -0
  847. package/dist/viewers/DocxViewer.js.map +7 -0
  848. package/dist/viewers/ImageViewer.js +31 -0
  849. package/dist/viewers/ImageViewer.js.map +7 -0
  850. package/dist/viewers/PdfViewer.js +19 -3
  851. package/dist/viewers/PdfViewer.js.map +7 -1
  852. package/dist/{PdfViewerImpl-TEBYF2QI.js → viewers/PdfViewerImpl.js} +25 -19
  853. package/dist/viewers/PdfViewerImpl.js.map +7 -0
  854. package/dist/viewers/VideoViewer.js +31 -0
  855. package/dist/viewers/VideoViewer.js.map +7 -0
  856. package/dist/viewers/XlsxViewer.js +102 -0
  857. package/dist/viewers/XlsxViewer.js.map +7 -0
  858. package/dist/viewers/index.js +61 -271
  859. package/dist/viewers/index.js.map +7 -1
  860. package/dist/viewers/page-scroll.js +59 -0
  861. package/dist/viewers/page-scroll.js.map +7 -0
  862. package/dist/viewers/pdf-viewer-constants.js +9 -0
  863. package/dist/viewers/pdf-viewer-constants.js.map +7 -0
  864. package/dist/{chunk-PTOP7OHG.js → viewers/pdfjs-polyfills.js} +5 -6
  865. package/dist/viewers/pdfjs-polyfills.js.map +7 -0
  866. package/dist/viewers/selection-runs.js +38 -0
  867. package/dist/viewers/selection-runs.js.map +7 -0
  868. package/dist/viewers/usePageIntersectionObserver.js +68 -0
  869. package/dist/viewers/usePageIntersectionObserver.js.map +7 -0
  870. package/dist/viewers/useProcessedChunks.js +58 -0
  871. package/dist/viewers/useProcessedChunks.js.map +7 -0
  872. package/dist/viewers/viewer-zoom.js +163 -0
  873. package/dist/viewers/viewer-zoom.js.map +7 -0
  874. package/dist/websocket/ArbiWebSocketProvider.js +207 -0
  875. package/dist/websocket/ArbiWebSocketProvider.js.map +7 -0
  876. package/dist/websocket/context.js +14 -0
  877. package/dist/websocket/context.js.map +7 -0
  878. package/dist/websocket/hooks.js +30 -0
  879. package/dist/websocket/hooks.js.map +7 -0
  880. package/dist/websocket/index.js +22 -0
  881. package/dist/websocket/index.js.map +7 -0
  882. package/dist/websocket/live-updates.js +38 -0
  883. package/dist/websocket/live-updates.js.map +7 -0
  884. package/dist/websocket/reconnect.js +13 -0
  885. package/dist/websocket/reconnect.js.map +7 -0
  886. package/dist/websocket/store.js +58 -0
  887. package/dist/websocket/store.js.map +7 -0
  888. package/dist/workforce.js +607 -0
  889. package/dist/workforce.js.map +7 -0
  890. package/dist/workspaces/access-request.js +35 -0
  891. package/dist/workspaces/access-request.js.map +7 -0
  892. package/dist/workspaces/archive.js +59 -0
  893. package/dist/workspaces/archive.js.map +7 -0
  894. package/dist/workspaces/current.js +20 -0
  895. package/dist/workspaces/current.js.map +7 -0
  896. package/dist/workspaces/delete-workspaces.js +15 -0
  897. package/dist/workspaces/delete-workspaces.js.map +7 -0
  898. package/dist/workspaces/export-archive.js +40 -0
  899. package/dist/workspaces/export-archive.js.map +7 -0
  900. package/dist/workspaces/index.js +99 -0
  901. package/dist/workspaces/index.js.map +7 -0
  902. package/dist/workspaces/settings.js +45 -0
  903. package/dist/workspaces/settings.js.map +7 -0
  904. package/dist/workspaces/shell-workspaces.js +49 -0
  905. package/dist/workspaces/shell-workspaces.js.map +7 -0
  906. package/dist/workspaces/switch.js +234 -0
  907. package/dist/workspaces/switch.js.map +7 -0
  908. package/dist/workspaces/transfer.js +170 -0
  909. package/dist/workspaces/transfer.js.map +7 -0
  910. package/dist/workspaces/useShellWorkspaces.js +86 -0
  911. package/dist/workspaces/useShellWorkspaces.js.map +7 -0
  912. package/dist/workspaces/workspace-users.js +65 -0
  913. package/dist/workspaces/workspace-users.js.map +7 -0
  914. package/package.json +4 -4
  915. package/dist/PdfViewerImpl-TEBYF2QI.js.map +0 -1
  916. package/dist/PdfViewerImpl.d-B28hLEuj.d.cts +0 -62
  917. package/dist/ProductionDialog.d-CpzslFn0.d.cts +0 -51
  918. package/dist/annotations/freeze/index.d.cts +0 -205
  919. package/dist/annotations/index.d.cts +0 -360
  920. package/dist/artifacts/index.d.cts +0 -476
  921. package/dist/artifacts/redline-core.d.cts +0 -39
  922. package/dist/bundle-YNOX7VIL.js +0 -5
  923. package/dist/bundle-YNOX7VIL.js.map +0 -1
  924. package/dist/bundle.d-BnCSbHy2.d.cts +0 -85
  925. package/dist/calls/livekit/index.d.cts +0 -280
  926. package/dist/chunk-47CCGUWR.js.map +0 -1
  927. package/dist/chunk-4FL3X3LA.js +0 -2057
  928. package/dist/chunk-4FL3X3LA.js.map +0 -1
  929. package/dist/chunk-6QNBSXCE.js +0 -271
  930. package/dist/chunk-6QNBSXCE.js.map +0 -1
  931. package/dist/chunk-74N436VK.js.map +0 -1
  932. package/dist/chunk-APZZQZ6P.js +0 -147
  933. package/dist/chunk-APZZQZ6P.js.map +0 -1
  934. package/dist/chunk-BF5KW5ZI.js.map +0 -1
  935. package/dist/chunk-DPYBZDJB.js.map +0 -1
  936. package/dist/chunk-DZKRL5H3.js +0 -2766
  937. package/dist/chunk-DZKRL5H3.js.map +0 -1
  938. package/dist/chunk-HDCRPPBW.js +0 -75
  939. package/dist/chunk-HDCRPPBW.js.map +0 -1
  940. package/dist/chunk-L2IPPTVC.js +0 -20
  941. package/dist/chunk-L2IPPTVC.js.map +0 -1
  942. package/dist/chunk-LSU4UPS5.js +0 -1011
  943. package/dist/chunk-LSU4UPS5.js.map +0 -1
  944. package/dist/chunk-NIKPG4PW.js +0 -1128
  945. package/dist/chunk-NIKPG4PW.js.map +0 -1
  946. package/dist/chunk-NNAJLY6B.js +0 -4974
  947. package/dist/chunk-NNAJLY6B.js.map +0 -1
  948. package/dist/chunk-OYPKKHXY.js +0 -559
  949. package/dist/chunk-OYPKKHXY.js.map +0 -1
  950. package/dist/chunk-PTOP7OHG.js.map +0 -1
  951. package/dist/chunk-QMY2JKBI.js +0 -246
  952. package/dist/chunk-QMY2JKBI.js.map +0 -1
  953. package/dist/chunk-SN5YV6FF.js +0 -11
  954. package/dist/chunk-SN5YV6FF.js.map +0 -1
  955. package/dist/chunk-SSXFVWCT.js.map +0 -1
  956. package/dist/chunk-T3USOSVN.js.map +0 -1
  957. package/dist/chunk-T4CLW3DN.js +0 -2560
  958. package/dist/chunk-T4CLW3DN.js.map +0 -1
  959. package/dist/chunk-UW2SGTI5.js.map +0 -1
  960. package/dist/chunk-VSCU7K4V.js.map +0 -1
  961. package/dist/chunk-WL2Y2T47.js.map +0 -1
  962. package/dist/chunk-WUTL62MC.js.map +0 -1
  963. package/dist/chunk-XWPLOFDN.js +0 -644
  964. package/dist/chunk-XWPLOFDN.js.map +0 -1
  965. package/dist/chunk-Y3MTRA7D.js +0 -97
  966. package/dist/chunk-Y3MTRA7D.js.map +0 -1
  967. package/dist/chunk-YNNAJJ5Z.js.map +0 -1
  968. package/dist/chunk-ZM6N7YZH.js.map +0 -1
  969. package/dist/document-tools/core.d.cts +0 -883
  970. package/dist/document-tools/index.d.cts +0 -90
  971. package/dist/index.d-LArLnpI8.d.cts +0 -2036
  972. package/dist/index.d-oR5FKZpJ.d.cts +0 -579
  973. package/dist/index.d.cts +0 -15923
  974. package/dist/lazy-chunk.d-B6YDLMKI.d.cts +0 -31
  975. package/dist/model.d-CNtRWKVK.d.cts +0 -110
  976. package/dist/query-keys.d-B1Am9tIF.d.cts +0 -337
  977. package/dist/shell/index.d.cts +0 -6
  978. package/dist/store.d-GADDvC7w.d.cts +0 -35
  979. package/dist/stored-markdown.d-Bp18vrbr.d.cts +0 -125
  980. package/dist/ui/index.d.cts +0 -26
  981. package/dist/useAudioRecorder.d-B9rlMI_E.d.cts +0 -778
  982. package/dist/viewers/PdfViewer.d.cts +0 -9
  983. package/dist/viewers/index.d.cts +0 -262
@@ -0,0 +1,210 @@
1
+ import { useCallback, useMemo, useState } from "react";
2
+ import {
3
+ partialMatchKey,
4
+ useMutationState,
5
+ useQueryClient
6
+ } from "@tanstack/react-query";
7
+ import { create } from "zustand";
8
+ import { arbiMutationKeys } from "../query-keys.js";
9
+ import { isReplayableArbiMutation } from "../offline.js";
10
+ import { useTags } from "../hooks.js";
11
+ import { getDocumentTitle } from "../entities/index.js";
12
+ import { useDocuments } from "./documents-data.js";
13
+ import {
14
+ rollbackOptimisticDocumentEdit
15
+ } from "./documents-writes.js";
16
+ import { QUEUED_WRITE_BLOCKED_MESSAGE, isBlockedOnWorkspace } from "../queued-writes.js";
17
+ const META_LABELS = {
18
+ title: "Title",
19
+ doc_date: "Date",
20
+ doc_nature: "Type",
21
+ doc_author: "Author",
22
+ doc_subject: "Abstract"
23
+ };
24
+ const KIND_BY_KEY = [
25
+ [arbiMutationKeys.updateDocuments(), "fields"],
26
+ [arbiMutationKeys.assignDocTags(), "assignTag"],
27
+ [arbiMutationKeys.removeDocTags(), "removeTag"],
28
+ [arbiMutationKeys.updateDocTag(), "noteTag"],
29
+ [arbiMutationKeys.createTag(), "createTag"]
30
+ ];
31
+ function kindOf(mutationKey) {
32
+ return mutationKey ? KIND_BY_KEY.find(([key]) => partialMatchKey(mutationKey, key))?.[1] : void 0;
33
+ }
34
+ function statusOf(isPaused, status, blocked = false) {
35
+ if (status === "error") return "error";
36
+ return isPaused || blocked ? "queued" : "syncing";
37
+ }
38
+ function docIdsFromVariables(kind, variables) {
39
+ if (kind === "fields")
40
+ return (variables?.documents ?? []).map(
41
+ (d) => d.external_id
42
+ );
43
+ if (kind === "assignTag" || kind === "removeTag")
44
+ return variables?.docIds ?? [];
45
+ if (kind === "noteTag") {
46
+ const docId = variables?.docId;
47
+ return docId ? [docId] : [];
48
+ }
49
+ return [];
50
+ }
51
+ function prevDocsFrom(context) {
52
+ const edit = context;
53
+ if (!edit?.optimistic) return /* @__PURE__ */ new Map();
54
+ return new Map(edit.previous.map((doc) => [doc.external_id, doc]));
55
+ }
56
+ function describeDocEdit(variables, context) {
57
+ const first = variables?.documents?.[0];
58
+ if (!first) return "Edited document";
59
+ const prevDocs = prevDocsFrom(context);
60
+ if ("folder" in first) {
61
+ const folder = first.folder ?? null;
62
+ return folder ? `Moved to ${folder}` : "Removed from folder";
63
+ }
64
+ if ("shared" in first) return first.shared ? "Shared in chat" : "Removed from chat";
65
+ if ("labels" in first) return "Changed labels";
66
+ if ("doc_metadata" in first) {
67
+ const nextMeta = first.doc_metadata ?? {};
68
+ const prevMeta = prevDocs.get(first.external_id)?.doc_metadata ?? {};
69
+ const changed = [];
70
+ for (const [key, label] of Object.entries(META_LABELS)) {
71
+ const next = nextMeta[key] ?? "";
72
+ const prev = prevMeta[key] ?? "";
73
+ if (String(next) === String(prev)) continue;
74
+ changed.push(next ? `${label} \u2192 \u201C${String(next)}\u201D` : `${label} cleared`);
75
+ }
76
+ if (changed.length > 0) return changed.join(", ");
77
+ return "Edited details";
78
+ }
79
+ return "Edited document";
80
+ }
81
+ const TAG_VERBS = {
82
+ assignTag: "Applied",
83
+ removeTag: "Removed",
84
+ noteTag: "Edited the note on"
85
+ };
86
+ function describeChange(raw, tagNameById) {
87
+ const { kind, variables, context } = raw;
88
+ const verb = TAG_VERBS[kind];
89
+ if (verb) {
90
+ const tagId = variables?.tagId;
91
+ const tagName = tagId ? tagNameById.get(tagId) : void 0;
92
+ return tagName ? `${verb} tag \u201C${tagName}\u201D` : `${verb} a tag`;
93
+ }
94
+ if (kind === "createTag") {
95
+ const name = variables?.name;
96
+ return name ? `Created tag \u201C${name}\u201D` : "Created a tag";
97
+ }
98
+ return describeDocEdit(variables, context);
99
+ }
100
+ function buildPendingSyncItem(raw, docNameById, tagNameById) {
101
+ const docIds = docIdsFromVariables(raw.kind, raw.variables);
102
+ const names = docIds.map((id) => docNameById.get(id)).filter(Boolean);
103
+ const document = raw.kind === "createTag" ? "Workspace labels" : names.length > 0 ? names.join(", ") : docIds.length > 1 ? `${docIds.length} documents` : "A document";
104
+ return {
105
+ mutationId: raw.mutationId,
106
+ document,
107
+ change: describeChange(raw, tagNameById),
108
+ status: raw.status,
109
+ at: raw.at,
110
+ docIds,
111
+ ...raw.blocked ? { notice: QUEUED_WRITE_BLOCKED_MESSAGE } : {}
112
+ };
113
+ }
114
+ const PENDING_SYNC_PREDICATE = (m) => (
115
+ // Only real offline EDITS belong in the queue. An incidental paused mutation
116
+ // (e.g. POST /v1/workspace/{id}/open fired on an offline cold-boot) is not a
117
+ // user "change" and must not show as a phantom pending item.
118
+ //
119
+ // Gated on offline: a mutation only `isPaused` when React Query holds it back
120
+ // for being offline, so this is the natural "offline mode" gate. We
121
+ // deliberately do NOT count a plain in-flight (`status === 'pending'`) edit —
122
+ // that's just a normal ONLINE save mid-request, and counting it made rows
123
+ // flash "pending/syncing" while fully online. `error` is kept so a failed
124
+ // sync stays visible to review/undo.
125
+ // A write held back because its workspace can't be opened (tried again meanwhile) is waiting too.
126
+ isReplayableArbiMutation(m.options.mutationKey) && (m.state.isPaused || m.state.status === "error" || isBlockedOnWorkspace(m))
127
+ );
128
+ function usePendingSyncItems() {
129
+ const { data: documents } = useDocuments();
130
+ const { data: tags } = useTags();
131
+ const raw = useMutationState({
132
+ filters: { predicate: PENDING_SYNC_PREDICATE },
133
+ select: (m) => ({
134
+ mutationId: m.mutationId,
135
+ kind: kindOf(m.options.mutationKey) ?? "fields",
136
+ variables: m.state.variables,
137
+ context: m.state.context,
138
+ status: statusOf(m.state.isPaused, m.state.status, isBlockedOnWorkspace(m)),
139
+ at: m.state.submittedAt,
140
+ blocked: isBlockedOnWorkspace(m)
141
+ })
142
+ });
143
+ return useMemo(() => {
144
+ const docNameById = /* @__PURE__ */ new Map();
145
+ for (const doc of documents ?? [])
146
+ docNameById.set(doc.external_id, getDocumentTitle(doc, doc.file_name ?? ""));
147
+ const tagNameById = /* @__PURE__ */ new Map();
148
+ for (const tag of tags ?? []) tagNameById.set(tag.external_id, tag.name);
149
+ return raw.map((r) => buildPendingSyncItem(r, docNameById, tagNameById));
150
+ }, [raw, documents, tags]);
151
+ }
152
+ function usePendingSyncCounts() {
153
+ const statuses = useMutationState({
154
+ filters: { predicate: PENDING_SYNC_PREDICATE },
155
+ select: (m) => m.state.status === "error" ? "error" : "pending"
156
+ });
157
+ return useMemo(
158
+ () => ({ pending: statuses.length, failed: statuses.filter((s) => s === "error").length }),
159
+ [statuses]
160
+ );
161
+ }
162
+ function useCancelManyPendingSync() {
163
+ const queryClient = useQueryClient();
164
+ return useCallback(
165
+ (mutationIds) => {
166
+ const wanted = new Set(mutationIds);
167
+ const cache = queryClient.getMutationCache();
168
+ const undoable = cache.getAll().filter((m) => wanted.has(m.mutationId) && (m.state.isPaused || m.state.status === "error")).sort((a, b) => b.state.submittedAt - a.state.submittedAt);
169
+ for (const mutation of undoable) {
170
+ rollbackOptimisticDocumentEdit(queryClient, mutation.state.context);
171
+ cache.remove(mutation);
172
+ }
173
+ },
174
+ [queryClient]
175
+ );
176
+ }
177
+ const usePendingDocIds = create(() => ({ ids: /* @__PURE__ */ new Set() }));
178
+ const watched = /* @__PURE__ */ new WeakSet();
179
+ function sameSet(a, b) {
180
+ if (a.size !== b.size) return false;
181
+ for (const v of a) if (!b.has(v)) return false;
182
+ return true;
183
+ }
184
+ function watchPendingDocIds(queryClient) {
185
+ if (watched.has(queryClient)) return;
186
+ watched.add(queryClient);
187
+ const cache = queryClient.getMutationCache();
188
+ const update = () => {
189
+ const ids = new Set(
190
+ cache.findAll({ predicate: PENDING_SYNC_PREDICATE }).flatMap((m) => docIdsFromVariables(kindOf(m.options.mutationKey), m.state.variables))
191
+ );
192
+ if (!sameSet(usePendingDocIds.getState().ids, ids)) usePendingDocIds.setState({ ids });
193
+ };
194
+ update();
195
+ cache.subscribe(update);
196
+ }
197
+ function useDocumentPendingSync(docId) {
198
+ const queryClient = useQueryClient();
199
+ useState(() => watchPendingDocIds(queryClient));
200
+ return usePendingDocIds((s) => docId ? s.ids.has(docId) : false);
201
+ }
202
+ export {
203
+ PENDING_SYNC_PREDICATE,
204
+ buildPendingSyncItem,
205
+ useCancelManyPendingSync,
206
+ useDocumentPendingSync,
207
+ usePendingSyncCounts,
208
+ usePendingSyncItems
209
+ };
210
+ //# sourceMappingURL=pending-sync.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/documents/pending-sync.ts"],
4
+ "sourcesContent": ["/**\n * Changes made offline that wait to sync: the documents' writes held back by React Query while\n * offline (paused mutations, persisted by the host's query persister) or that failed when they\n * were replayed. What changed and where (`usePendingSyncItems`), how many (`usePendingSyncCounts`),\n * whether a document has one (`useDocumentPendingSync`), and undoing them before they reach the\n * server (`useCancelManyPendingSync`). These only read the mutation cache (plus the explicit\n * undo), so they never change how online writes behave.\n */\n\nimport { useCallback, useMemo, useState } from 'react'\nimport {\n partialMatchKey,\n useMutationState,\n useQueryClient,\n type Mutation,\n type MutationKey,\n type QueryClient,\n} from '@tanstack/react-query'\nimport { create } from 'zustand'\nimport { arbiMutationKeys } from '../query-keys'\nimport { isReplayableArbiMutation } from '../offline'\nimport { useTags } from '../hooks'\nimport { getDocumentTitle } from '../entities'\nimport { useDocuments } from './documents-data'\nimport {\n rollbackOptimisticDocumentEdit,\n type AssignDocTagsInput,\n type OptimisticDocumentEdit,\n type UpdateDocTagInput,\n type UpdateDocumentsInput,\n} from './documents-writes'\nimport type { CreateTagInput } from '../tags'\nimport type { WorkspaceDocument } from './documents-cache'\nimport { QUEUED_WRITE_BLOCKED_MESSAGE, isBlockedOnWorkspace } from '../queued-writes'\n\ntype PendingStatus = 'queued' | 'syncing' | 'error'\n\nexport interface PendingSyncItem {\n mutationId: number\n /** Affected document name(s) \u2014 resolved, e.g. \"Exhibit R-007\". */\n document: string\n /** The exact change, in plain words \u2014 e.g. \"Moved to Contracts\", \"Title \u2192 \\\"X\\\"\". */\n change: string\n status: PendingStatus\n /** When the change was made (ms epoch). */\n at: number\n docIds: string[]\n /** Why it is held back, when it is: its workspace can't be opened, so it was not sent. */\n notice?: string\n}\n\n/** Doc-metadata sub-fields the table can edit, with their display labels. */\nconst META_LABELS: Record<string, string> = {\n title: 'Title',\n doc_date: 'Date',\n doc_nature: 'Type',\n doc_author: 'Author',\n doc_subject: 'Abstract',\n}\n\n/** Which queued write a pending change is. */\ntype PendingKind = 'fields' | 'assignTag' | 'removeTag' | 'noteTag' | 'createTag'\n\nconst KIND_BY_KEY: ReadonlyArray<readonly [MutationKey, PendingKind]> = [\n [arbiMutationKeys.updateDocuments(), 'fields'],\n [arbiMutationKeys.assignDocTags(), 'assignTag'],\n [arbiMutationKeys.removeDocTags(), 'removeTag'],\n [arbiMutationKeys.updateDocTag(), 'noteTag'],\n [arbiMutationKeys.createTag(), 'createTag'],\n]\n\nfunction kindOf(mutationKey: MutationKey | undefined): PendingKind | undefined {\n return mutationKey\n ? KIND_BY_KEY.find(([key]) => partialMatchKey(mutationKey, key))?.[1]\n : undefined\n}\n\n/** The raw projection pulled out of each pending mutation, before enrichment. */\nexport interface RawPending {\n mutationId: number\n kind: PendingKind\n variables: unknown\n context: unknown\n status: PendingStatus\n at: number\n /** Not sent because its workspace can't be opened (retried, then kept). */\n blocked?: boolean\n}\n\nfunction statusOf(isPaused: boolean, status: string, blocked = false): PendingStatus {\n if (status === 'error') return 'error'\n return isPaused || blocked ? 'queued' : 'syncing'\n}\n\n/** Pull the affected document ext_ids out of a mutation's input. */\nfunction docIdsFromVariables(kind: PendingKind | undefined, variables: unknown): string[] {\n if (kind === 'fields')\n return ((variables as UpdateDocumentsInput | undefined)?.documents ?? []).map(\n (d) => d.external_id\n )\n if (kind === 'assignTag' || kind === 'removeTag')\n return (variables as AssignDocTagsInput | undefined)?.docIds ?? []\n if (kind === 'noteTag') {\n const docId = (variables as UpdateDocTagInput | undefined)?.docId\n return docId ? [docId] : []\n }\n return []\n}\n\n/** Map of docId \u2192 the pre-edit document, from a mutation's rollback snapshot. */\nfunction prevDocsFrom(context: unknown): Map<string, WorkspaceDocument> {\n const edit = context as OptimisticDocumentEdit | undefined\n if (!edit?.optimistic) return new Map()\n return new Map(edit.previous.map((doc) => [doc.external_id, doc]))\n}\n\n/** Describe a single document-field edit by diffing the new values vs the snapshot. */\nfunction describeDocEdit(variables: unknown, context: unknown): string {\n const first = (variables as UpdateDocumentsInput | undefined)?.documents?.[0] as\n Record<string, unknown> | undefined\n if (!first) return 'Edited document'\n const prevDocs = prevDocsFrom(context)\n\n // Top-level fields carry the value directly.\n if ('folder' in first) {\n const folder = (first.folder as string | null) ?? null\n return folder ? `Moved to ${folder}` : 'Removed from folder'\n }\n if ('shared' in first) return first.shared ? 'Shared in chat' : 'Removed from chat'\n if ('labels' in first) return 'Changed labels'\n\n // doc_metadata edits: diff against the pre-edit snapshot to name the field(s).\n if ('doc_metadata' in first) {\n const nextMeta = (first.doc_metadata ?? {}) as Record<string, unknown>\n const prevMeta = (prevDocs.get(first.external_id as string)?.doc_metadata ?? {}) as Record<\n string,\n unknown\n >\n const changed: string[] = []\n for (const [key, label] of Object.entries(META_LABELS)) {\n const next = nextMeta[key] ?? ''\n const prev = prevMeta[key] ?? ''\n if (String(next) === String(prev)) continue\n changed.push(next ? `${label} \u2192 \u201C${String(next)}\u201D` : `${label} cleared`)\n }\n if (changed.length > 0) return changed.join(', ')\n return 'Edited details'\n }\n return 'Edited document'\n}\n\nconst TAG_VERBS: Partial<Record<PendingKind, string>> = {\n assignTag: 'Applied',\n removeTag: 'Removed',\n noteTag: 'Edited the note on',\n}\n\n/** A human change summary for one pending mutation. */\nfunction describeChange(raw: RawPending, tagNameById: Map<string, string>): string {\n const { kind, variables, context } = raw\n const verb = TAG_VERBS[kind]\n if (verb) {\n const tagId = (variables as { tagId?: string } | undefined)?.tagId\n const tagName = tagId ? tagNameById.get(tagId) : undefined\n return tagName ? `${verb} tag \u201C${tagName}\u201D` : `${verb} a tag`\n }\n if (kind === 'createTag') {\n const name = (variables as CreateTagInput | undefined)?.name\n return name ? `Created tag \u201C${name}\u201D` : 'Created a tag'\n }\n return describeDocEdit(variables, context)\n}\n\n/**\n * Pure enrichment: turn one raw pending mutation into a display item, resolving\n * the document name(s) and change summary from the supplied maps. Exported for\n * direct unit testing (the bug-prone part is name/change resolution, not the\n * thin useMutationState wiring around it).\n */\nexport function buildPendingSyncItem(\n raw: RawPending,\n docNameById: Map<string, string>,\n tagNameById: Map<string, string>\n): PendingSyncItem {\n const docIds = docIdsFromVariables(raw.kind, raw.variables)\n const names = docIds.map((id) => docNameById.get(id)).filter(Boolean) as string[]\n const document =\n raw.kind === 'createTag'\n ? 'Workspace labels'\n : names.length > 0\n ? names.join(', ')\n : docIds.length > 1\n ? `${docIds.length} documents`\n : 'A document'\n return {\n mutationId: raw.mutationId,\n document,\n change: describeChange(raw, tagNameById),\n status: raw.status,\n at: raw.at,\n docIds,\n ...(raw.blocked ? { notice: QUEUED_WRITE_BLOCKED_MESSAGE } : {}),\n }\n}\n\nexport const PENDING_SYNC_PREDICATE = (m: Mutation): boolean =>\n // Only real offline EDITS belong in the queue. An incidental paused mutation\n // (e.g. POST /v1/workspace/{id}/open fired on an offline cold-boot) is not a\n // user \"change\" and must not show as a phantom pending item.\n //\n // Gated on offline: a mutation only `isPaused` when React Query holds it back\n // for being offline, so this is the natural \"offline mode\" gate. We\n // deliberately do NOT count a plain in-flight (`status === 'pending'`) edit \u2014\n // that's just a normal ONLINE save mid-request, and counting it made rows\n // flash \"pending/syncing\" while fully online. `error` is kept so a failed\n // sync stays visible to review/undo.\n // A write held back because its workspace can't be opened (tried again meanwhile) is waiting too.\n isReplayableArbiMutation(m.options.mutationKey) &&\n (m.state.isPaused || m.state.status === 'error' || isBlockedOnWorkspace(m))\n\n/**\n * Full, enriched list of unsynced writes for the offline-changes modal \u2014 newest\n * last, each with a resolved document name, the exact change, and a timestamp.\n * Resolves names from the live document + tag caches (reactively, so they fill\n * in as those load \u2014 unlike a one-shot cache read).\n */\nexport function usePendingSyncItems(): PendingSyncItem[] {\n const { data: documents } = useDocuments()\n const { data: tags } = useTags()\n\n const raw = useMutationState<RawPending>({\n filters: { predicate: PENDING_SYNC_PREDICATE },\n select: (m) => ({\n mutationId: m.mutationId,\n kind: kindOf(m.options.mutationKey) ?? 'fields',\n variables: m.state.variables,\n context: m.state.context,\n status: statusOf(m.state.isPaused, m.state.status, isBlockedOnWorkspace(m)),\n at: m.state.submittedAt,\n blocked: isBlockedOnWorkspace(m),\n }),\n })\n\n return useMemo(() => {\n const docNameById = new Map<string, string>()\n for (const doc of documents ?? [])\n docNameById.set(doc.external_id, getDocumentTitle(doc, doc.file_name ?? ''))\n const tagNameById = new Map<string, string>()\n for (const tag of tags ?? []) tagNameById.set(tag.external_id, tag.name)\n\n return raw.map((r) => buildPendingSyncItem(r, docNameById, tagNameById))\n }, [raw, documents, tags])\n}\n\n/** Cheap counts for the sidebar badge \u2014 no name resolution. */\nexport function usePendingSyncCounts(): { pending: number; failed: number } {\n const statuses = useMutationState({\n filters: { predicate: PENDING_SYNC_PREDICATE },\n select: (m) => (m.state.status === 'error' ? 'error' : 'pending'),\n })\n return useMemo(\n () => ({ pending: statuses.length, failed: statuses.filter((s) => s === 'error').length }),\n [statuses]\n )\n}\n\n/**\n * Cancel many changes at once. Rolls back newest-first so layered edits to the\n * same doc restore in LIFO order (matching how they'd replay). Only undoable\n * (queued/failed) mutations are touched \u2014 anything already syncing is left alone.\n */\nexport function useCancelManyPendingSync(): (mutationIds: number[]) => void {\n const queryClient = useQueryClient()\n return useCallback(\n (mutationIds) => {\n const wanted = new Set(mutationIds)\n const cache = queryClient.getMutationCache()\n const undoable = cache\n .getAll()\n .filter((m) => wanted.has(m.mutationId) && (m.state.isPaused || m.state.status === 'error'))\n .sort((a, b) => b.state.submittedAt - a.state.submittedAt)\n for (const mutation of undoable) {\n rollbackOptimisticDocumentEdit(queryClient, mutation.state.context)\n cache.remove(mutation)\n }\n },\n [queryClient]\n )\n}\n\n/** The documents with a change waiting to sync, kept from one watch of each query client. */\nconst usePendingDocIds = create<{ ids: ReadonlySet<string> }>(() => ({ ids: new Set() }))\nconst watched = new WeakSet<QueryClient>()\n\nfunction sameSet(a: ReadonlySet<string>, b: ReadonlySet<string>): boolean {\n if (a.size !== b.size) return false\n for (const v of a) if (!b.has(v)) return false\n return true\n}\n\n/**\n * Watch a query client's mutation cache once, keeping the set of documents with a pending change:\n * a grid of thousands of status cells then reads one cheap boolean each instead of subscribing to\n * the mutation cache thousands of times.\n */\nfunction watchPendingDocIds(queryClient: QueryClient): void {\n if (watched.has(queryClient)) return\n watched.add(queryClient)\n const cache = queryClient.getMutationCache()\n const update = () => {\n const ids = new Set(\n cache\n .findAll({ predicate: PENDING_SYNC_PREDICATE })\n .flatMap((m) => docIdsFromVariables(kindOf(m.options.mutationKey), m.state.variables))\n )\n if (!sameSet(usePendingDocIds.getState().ids, ids)) usePendingDocIds.setState({ ids })\n }\n update()\n cache.subscribe(update)\n}\n\n/** Whether a document has a change waiting to sync (a cheap boolean, for per-row status). */\nexport function useDocumentPendingSync(docId: string | null | undefined): boolean {\n const queryClient = useQueryClient()\n useState(() => watchPendingDocIds(queryClient))\n return usePendingDocIds((s) => (docId ? s.ids.has(docId) : false))\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,122 @@
1
+ import { useEffect, useMemo, useState } from "react";
2
+ import { useQueryClient } from "@tanstack/react-query";
3
+ import { useArbi } from "../useArbi.js";
4
+ import { useArbiWsStore } from "../websocket/store.js";
5
+ import { getCachedDocuments, patchDocuments } from "./documents-cache.js";
6
+ import { refreshDocuments } from "./documents-data.js";
7
+ import { subscribeDocumentReads } from "./processing-settle.js";
8
+ import { FINISHED_DOCUMENT_STATUSES, IN_FLIGHT_DOCUMENT_STATUSES } from "./processing-order.js";
9
+ const STALE_TASK_MS = 6 * 60 * 60 * 1e3;
10
+ const ORPHAN_TASK_MS = 15 * 60 * 1e3;
11
+ const SNAPSHOT_MS = 500;
12
+ function applyTaskEvent(queryClient, arbi, message, me) {
13
+ const workspaceId = message.workspace_ext_id;
14
+ if (!workspaceId) return;
15
+ if (FINISHED_DOCUMENT_STATUSES.has(message.status)) {
16
+ void refreshDocuments(queryClient, arbi, [message.doc_ext_id]);
17
+ return;
18
+ }
19
+ const cached = getCachedDocuments(queryClient, workspaceId);
20
+ if (!cached || cached.some((d) => d.external_id === message.doc_ext_id)) return;
21
+ const now = (/* @__PURE__ */ new Date()).toISOString();
22
+ const placeholder = {
23
+ external_id: message.doc_ext_id,
24
+ workspace_ext_id: workspaceId,
25
+ file_name: message.file_name ?? "Uploading\u2026",
26
+ status: message.status,
27
+ folder: message.folder ?? null,
28
+ wp_type: "source",
29
+ shared: false,
30
+ created_by_ext_id: me ?? void 0,
31
+ doc_metadata: {},
32
+ doctags: [],
33
+ created_at: now,
34
+ updated_at: now
35
+ };
36
+ patchDocuments(
37
+ queryClient,
38
+ (old) => old.some((d) => d.external_id === message.doc_ext_id) ? old : [...old, placeholder],
39
+ workspaceId
40
+ );
41
+ }
42
+ function useWorkspaceProcessing(workspaceId) {
43
+ const queryClient = useQueryClient();
44
+ const arbi = useArbi();
45
+ const [snapshot, setSnapshot] = useState(() => useArbiWsStore.getState().tasks);
46
+ useEffect(() => {
47
+ let timer = null;
48
+ const unsubscribe = useArbiWsStore.subscribe((state, previous) => {
49
+ if (state.tasks === previous.tasks || timer) return;
50
+ timer = setTimeout(() => {
51
+ timer = null;
52
+ setSnapshot(useArbiWsStore.getState().tasks);
53
+ }, SNAPSHOT_MS);
54
+ });
55
+ return () => {
56
+ unsubscribe();
57
+ if (timer) clearTimeout(timer);
58
+ };
59
+ }, []);
60
+ useEffect(() => {
61
+ if (!workspaceId) return;
62
+ const store = useArbiWsStore.getState();
63
+ const documents = getCachedDocuments(queryClient, workspaceId) ?? [];
64
+ store.settleTasks(documents);
65
+ const listed = new Set(documents.map((d) => d.external_id));
66
+ const now = Date.now();
67
+ for (const task of Object.values(useArbiWsStore.getState().tasks)) {
68
+ if (task.workspace_ext_id !== workspaceId || !IN_FLIGHT_DOCUMENT_STATUSES.has(task.status))
69
+ continue;
70
+ const since = task.startTime ?? task.endTime;
71
+ const age = since == null ? null : now - since;
72
+ const stale = age != null && age > STALE_TASK_MS;
73
+ const orphan = documents.length > 0 && !listed.has(task.doc_ext_id) && age != null && age > ORPHAN_TASK_MS;
74
+ if (stale || orphan) store.clearTask(task.doc_ext_id);
75
+ }
76
+ }, [workspaceId, queryClient]);
77
+ useEffect(() => {
78
+ if (!workspaceId) return;
79
+ const unsubscribeReads = subscribeDocumentReads(
80
+ queryClient,
81
+ (rows) => useArbiWsStore.getState().settleTasks(rows)
82
+ );
83
+ const recheck = async () => {
84
+ const ids = Object.values(useArbiWsStore.getState().tasks).filter(
85
+ (t) => t.workspace_ext_id === workspaceId && IN_FLIGHT_DOCUMENT_STATUSES.has(t.status)
86
+ ).map((t) => t.doc_ext_id);
87
+ if (ids.length) await refreshDocuments(queryClient, arbi, ids);
88
+ };
89
+ let wasConnected = useArbiWsStore.getState().status === "connected";
90
+ const unsubscribeStatus = useArbiWsStore.subscribe((state) => {
91
+ const connected = state.status === "connected";
92
+ if (connected && !wasConnected) void recheck();
93
+ wasConnected = connected;
94
+ });
95
+ return () => {
96
+ unsubscribeReads();
97
+ unsubscribeStatus();
98
+ };
99
+ }, [workspaceId, queryClient, arbi]);
100
+ return useMemo(() => {
101
+ const allTasks = workspaceId ? Object.values(snapshot).filter((t) => t.workspace_ext_id === workspaceId).sort((a, b) => a.doc_ext_id.localeCompare(b.doc_ext_id)) : [];
102
+ const count = (statuses) => allTasks.filter(
103
+ (t) => Array.isArray(statuses) ? statuses.includes(t.status) : statuses.has(t.status)
104
+ ).length;
105
+ const { clearTask, clearFinishedTasks } = useArbiWsStore.getState();
106
+ return {
107
+ tasks: Object.fromEntries(allTasks.map((t) => [t.doc_ext_id, t])),
108
+ allTasks,
109
+ processingCount: count(IN_FLIGHT_DOCUMENT_STATUSES),
110
+ completedCount: count(["completed", "low-content"]),
111
+ failedCount: count(["failed"]),
112
+ skippedCount: count(["skipped"]),
113
+ clearTask,
114
+ clearFinishedTasks
115
+ };
116
+ }, [workspaceId, snapshot]);
117
+ }
118
+ export {
119
+ applyTaskEvent,
120
+ useWorkspaceProcessing
121
+ };
122
+ //# sourceMappingURL=processing-live.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/documents/processing-live.ts"],
4
+ "sourcesContent": ["/**\n * A workspace's documents in processing, live: what every site's file views show while uploads\n * and re-processing run.\n *\n * - `applyTaskEvent` (the provider runs it on each taken `task_update`): an upload appears as a\n * row the moment it is queued (a light placeholder, so the table and the gallery show it with\n * its live progress), and a finished document replaces its row with the one read afresh.\n * - `useWorkspaceProcessing(workspaceId)`: the workspace's processing rows and their counts\n * (a snapshot every half second, so a batch upload does not re-render on every event), kept\n * honest: stale or orphaned rows are dropped when the workspace opens, rows a document read says\n * finished are settled, and the in-flight ones are re-checked when the connection comes back.\n */\n\nimport { useEffect, useMemo, useState } from 'react'\nimport { useQueryClient, type QueryClient } from '@tanstack/react-query'\nimport type { Arbi } from '@arbidocs/sdk/browser'\nimport type { WsTaskUpdateMessage } from '@arbidocs/client'\nimport { useArbi } from '../useArbi'\nimport { useArbiWsStore, type LiveTask } from '../websocket/store'\nimport { getCachedDocuments, patchDocuments } from './documents-cache'\nimport { refreshDocuments } from './documents-data'\nimport { subscribeDocumentReads } from './processing-settle'\nimport { FINISHED_DOCUMENT_STATUSES, IN_FLIGHT_DOCUMENT_STATUSES } from './processing-order'\nimport type { WorkspaceDocument } from './documents-cache'\n\n/** A row in flight longer than this is a zombie (its completion was lost): no real run takes it. */\nconst STALE_TASK_MS = 6 * 60 * 60 * 1000\n/** A row whose document is missing from a read list is an orphan only after this long. */\nconst ORPHAN_TASK_MS = 15 * 60 * 1000\n/** How often the workspace's rows are re-read into views while processing runs. */\nconst SNAPSHOT_MS = 500\n\n/** Apply one taken `task_update` to the documents list (`me`: who uploads, i.e. this user). */\nexport function applyTaskEvent(\n queryClient: QueryClient,\n arbi: Arbi,\n message: WsTaskUpdateMessage & { folder?: string | null },\n me: string | null | undefined\n): void {\n const workspaceId = message.workspace_ext_id\n if (!workspaceId) return\n if (FINISHED_DOCUMENT_STATUSES.has(message.status)) {\n // The finished document replaces its placeholder row and its own entry.\n void refreshDocuments(queryClient, arbi, [message.doc_ext_id])\n return\n }\n // Only once the list has been read: a placeholder must not stand in for the first read.\n const cached = getCachedDocuments(queryClient, workspaceId)\n if (!cached || cached.some((d) => d.external_id === message.doc_ext_id)) return\n const now = new Date().toISOString()\n // The fields the read document will carry, so the row passes the list's filters meanwhile.\n const placeholder = {\n external_id: message.doc_ext_id,\n workspace_ext_id: workspaceId,\n file_name: message.file_name ?? 'Uploading\u2026',\n status: message.status,\n folder: message.folder ?? null,\n wp_type: 'source',\n shared: false,\n created_by_ext_id: me ?? undefined,\n doc_metadata: {},\n doctags: [],\n created_at: now,\n updated_at: now,\n } as unknown as WorkspaceDocument\n patchDocuments(\n queryClient,\n (old) => (old.some((d) => d.external_id === message.doc_ext_id) ? old : [...old, placeholder]),\n workspaceId\n )\n}\n\n/** The workspace's processing rows (in the order of their document ids) and their counts. */\nexport interface WorkspaceProcessing {\n tasks: Record<string, LiveTask>\n allTasks: LiveTask[]\n processingCount: number\n completedCount: number\n failedCount: number\n skippedCount: number\n clearTask: (docId: string) => void\n clearFinishedTasks: () => void\n}\n\nexport function useWorkspaceProcessing(workspaceId: string | undefined): WorkspaceProcessing {\n const queryClient = useQueryClient()\n const arbi = useArbi()\n const [snapshot, setSnapshot] = useState(() => useArbiWsStore.getState().tasks)\n\n useEffect(() => {\n let timer: ReturnType<typeof setTimeout> | null = null\n const unsubscribe = useArbiWsStore.subscribe((state, previous) => {\n if (state.tasks === previous.tasks || timer) return\n timer = setTimeout(() => {\n timer = null\n setSnapshot(useArbiWsStore.getState().tasks)\n }, SNAPSHOT_MS)\n })\n return () => {\n unsubscribe()\n if (timer) clearTimeout(timer)\n }\n }, [])\n\n // When the workspace opens: settle what its list says finished, and drop zombie rows (in flight\n // for hours) and orphans (their document is gone from the read list).\n useEffect(() => {\n if (!workspaceId) return\n const store = useArbiWsStore.getState()\n const documents = getCachedDocuments(queryClient, workspaceId) ?? []\n store.settleTasks(documents)\n const listed = new Set(documents.map((d) => d.external_id))\n const now = Date.now()\n for (const task of Object.values(useArbiWsStore.getState().tasks)) {\n if (task.workspace_ext_id !== workspaceId || !IN_FLIGHT_DOCUMENT_STATUSES.has(task.status))\n continue\n const since = task.startTime ?? task.endTime\n const age = since == null ? null : now - since\n const stale = age != null && age > STALE_TASK_MS\n const orphan =\n documents.length > 0 && !listed.has(task.doc_ext_id) && age != null && age > ORPHAN_TASK_MS\n if (stale || orphan) store.clearTask(task.doc_ext_id)\n }\n }, [workspaceId, queryClient])\n\n // Afterwards: every documents read settles the rows it shows finished, and a connection that\n // comes back re-checks the in-flight ones (the events it missed are gone for good).\n useEffect(() => {\n if (!workspaceId) return\n const unsubscribeReads = subscribeDocumentReads(queryClient, (rows) =>\n useArbiWsStore.getState().settleTasks(rows)\n )\n const recheck = async () => {\n const ids = Object.values(useArbiWsStore.getState().tasks)\n .filter(\n (t) => t.workspace_ext_id === workspaceId && IN_FLIGHT_DOCUMENT_STATUSES.has(t.status)\n )\n .map((t) => t.doc_ext_id)\n if (ids.length) await refreshDocuments(queryClient, arbi, ids)\n }\n let wasConnected = useArbiWsStore.getState().status === 'connected'\n const unsubscribeStatus = useArbiWsStore.subscribe((state) => {\n const connected = state.status === 'connected'\n if (connected && !wasConnected) void recheck()\n wasConnected = connected\n })\n return () => {\n unsubscribeReads()\n unsubscribeStatus()\n }\n }, [workspaceId, queryClient, arbi])\n\n return useMemo(() => {\n const allTasks = workspaceId\n ? Object.values(snapshot)\n .filter((t) => t.workspace_ext_id === workspaceId)\n .sort((a, b) => a.doc_ext_id.localeCompare(b.doc_ext_id))\n : []\n const count = (statuses: ReadonlySet<string> | string[]) =>\n allTasks.filter((t) =>\n Array.isArray(statuses) ? statuses.includes(t.status) : statuses.has(t.status)\n ).length\n const { clearTask, clearFinishedTasks } = useArbiWsStore.getState()\n return {\n tasks: Object.fromEntries(allTasks.map((t) => [t.doc_ext_id, t])),\n allTasks,\n processingCount: count(IN_FLIGHT_DOCUMENT_STATUSES),\n completedCount: count(['completed', 'low-content']),\n failedCount: count(['failed']),\n skippedCount: count(['skipped']),\n clearTask,\n clearFinishedTasks,\n }\n }, [workspaceId, snapshot])\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,59 @@
1
+ const FINISHED_DOCUMENT_STATUSES = /* @__PURE__ */ new Set([
2
+ "completed",
3
+ "low-content",
4
+ "failed",
5
+ "skipped",
6
+ "empty"
7
+ ]);
8
+ const IN_FLIGHT_DOCUMENT_STATUSES = /* @__PURE__ */ new Set([
9
+ "uploading",
10
+ "queued",
11
+ "parsing",
12
+ "encrypting",
13
+ "indexing",
14
+ "analysing"
15
+ ]);
16
+ function ordered(value) {
17
+ return typeof value === "number";
18
+ }
19
+ function isStaleTaskUpdate(held, next) {
20
+ return !!held && ordered(held.seq) && ordered(next.seq) && next.seq <= held.seq;
21
+ }
22
+ function isRowNewer(row, task) {
23
+ if (!ordered(row.status_seq) || !ordered(task.seq)) return void 0;
24
+ return row.status_seq > task.seq;
25
+ }
26
+ function resolveDocumentStatus(row, task) {
27
+ const rowStatus = (row.status ?? "").toLowerCase();
28
+ const live = task?.status;
29
+ if (!task || !live) return rowStatus;
30
+ const rowNewer = isRowNewer(row, task);
31
+ if (rowNewer !== void 0) return rowNewer ? rowStatus || live : live;
32
+ if (IN_FLIGHT_DOCUMENT_STATUSES.has(live)) return live;
33
+ if (FINISHED_DOCUMENT_STATUSES.has(rowStatus)) return rowStatus;
34
+ return live;
35
+ }
36
+ function settledByRows(tasks, rows) {
37
+ const inFlight = /* @__PURE__ */ new Map();
38
+ for (const task of Object.values(tasks))
39
+ if (IN_FLIGHT_DOCUMENT_STATUSES.has(task.status)) inFlight.set(task.doc_ext_id, task);
40
+ if (!inFlight.size) return [];
41
+ const settled = [];
42
+ for (const row of rows) {
43
+ const task = inFlight.get(row.external_id);
44
+ if (!task) continue;
45
+ const rowStatus = (row.status ?? "").toLowerCase();
46
+ if (!FINISHED_DOCUMENT_STATUSES.has(rowStatus) || isRowNewer(row, task) === false) continue;
47
+ settled.push({ ...task, status: rowStatus, seq: row.status_seq ?? task.seq });
48
+ }
49
+ return settled;
50
+ }
51
+ export {
52
+ FINISHED_DOCUMENT_STATUSES,
53
+ IN_FLIGHT_DOCUMENT_STATUSES,
54
+ isRowNewer,
55
+ isStaleTaskUpdate,
56
+ resolveDocumentStatus,
57
+ settledByRows
58
+ };
59
+ //# sourceMappingURL=processing-order.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/documents/processing-order.ts"],
4
+ "sourcesContent": ["/**\n * Which is newer: a document's live processing status or its row as last read?\n *\n * Every `task_update` carries `seq`, taken by the server from one sequence for all documents and\n * all of its instances, so a higher seq is a later event however the events arrive. A document row\n * carries `status_seq`: the seq of the last time its processing ended (a finished status written or\n * broadcast). The two compare:\n * - an event at or below the seq of the one already held is stale (overtaken), and is dropped;\n * - a row whose `status_seq` is above the live status's seq finished after it: the live status is\n * over (its final event was lost), and the row wins;\n * - a live status above the row's `status_seq` is newer than the row: the document is being\n * processed again (AI fields being filled) although the row still says it finished.\n *\n * Without the seqs (an optimistic \"queued\" set here, a server before them) the older rule stands:\n * a live in-flight status wins, then a finished row, then whatever was heard live.\n */\n\n/** Statuses after which a document's processing is over (`low-content`: indexed, little text). */\nexport const FINISHED_DOCUMENT_STATUSES: ReadonlySet<string> = new Set([\n 'completed',\n 'low-content',\n 'failed',\n 'skipped',\n 'empty',\n])\n\n/** A live processing status and its order (`task_update.seq`). */\nexport interface SequencedTask {\n status: string\n seq?: number | null\n}\n\n/** A document row's status and the order of its last finished status (`status_seq`). */\nexport interface SequencedRow {\n status?: string | null\n status_seq?: number | null\n}\n\n/** Statuses of a document still being processed. */\nexport const IN_FLIGHT_DOCUMENT_STATUSES: ReadonlySet<string> = new Set([\n 'uploading',\n 'queued',\n 'parsing',\n 'encrypting',\n 'indexing',\n 'analysing',\n])\n\nfunction ordered(value: number | null | undefined): value is number {\n return typeof value === 'number'\n}\n\n/** Whether `next` is older than (or the same event as) the live status already held. */\nexport function isStaleTaskUpdate(held: SequencedTask | undefined, next: SequencedTask): boolean {\n return !!held && ordered(held.seq) && ordered(next.seq) && next.seq <= held.seq\n}\n\n/**\n * Whether the row is newer than the live status: `true` / `false` when both are ordered, `undefined`\n * when they cannot be compared.\n */\nexport function isRowNewer(row: SequencedRow, task: SequencedTask): boolean | undefined {\n if (!ordered(row.status_seq) || !ordered(task.seq)) return undefined\n return row.status_seq > task.seq\n}\n\n/** The status a document shows now: its row's, or the live one when that is newer. */\nexport function resolveDocumentStatus(row: SequencedRow, task: SequencedTask | undefined): string {\n const rowStatus = (row.status ?? '').toLowerCase()\n const live = task?.status\n if (!task || !live) return rowStatus\n const rowNewer = isRowNewer(row, task)\n if (rowNewer !== undefined) return rowNewer ? rowStatus || live : live\n if (IN_FLIGHT_DOCUMENT_STATUSES.has(live)) return live\n if (FINISHED_DOCUMENT_STATUSES.has(rowStatus)) return rowStatus\n return live\n}\n\n/**\n * The live statuses a read of `rows` ends: each in-flight one whose row has since finished. Ordered,\n * the row must be newer (so a reprocess the row predates keeps its progress); unordered, a finished\n * row is enough (the older rule). Returns each such task with the row's status and order. Cheap when\n * nothing is in flight (it runs on every read of a list).\n */\nexport function settledByRows<T extends SequencedTask & { doc_ext_id: string }>(\n tasks: Readonly<Record<string, T>>,\n rows: ReadonlyArray<SequencedRow & { external_id: string }>\n): T[] {\n const inFlight = new Map<string, T>()\n for (const task of Object.values(tasks))\n if (IN_FLIGHT_DOCUMENT_STATUSES.has(task.status)) inFlight.set(task.doc_ext_id, task)\n if (!inFlight.size) return []\n const settled: T[] = []\n for (const row of rows) {\n const task = inFlight.get(row.external_id)\n if (!task) continue\n const rowStatus = (row.status ?? '').toLowerCase()\n if (!FINISHED_DOCUMENT_STATUSES.has(rowStatus) || isRowNewer(row, task) === false) continue\n settled.push({ ...task, status: rowStatus, seq: row.status_seq ?? task.seq })\n }\n return settled\n}\n"],
5
+ "mappings": "AAkBO,MAAM,6BAAkD,oBAAI,IAAI;AAAA,EACrE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAeM,MAAM,8BAAmD,oBAAI,IAAI;AAAA,EACtE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,SAAS,QAAQ,OAAmD;AAClE,SAAO,OAAO,UAAU;AAC1B;AAGO,SAAS,kBAAkB,MAAiC,MAA8B;AAC/F,SAAO,CAAC,CAAC,QAAQ,QAAQ,KAAK,GAAG,KAAK,QAAQ,KAAK,GAAG,KAAK,KAAK,OAAO,KAAK;AAC9E;AAMO,SAAS,WAAW,KAAmB,MAA0C;AACtF,MAAI,CAAC,QAAQ,IAAI,UAAU,KAAK,CAAC,QAAQ,KAAK,GAAG,EAAG,QAAO;AAC3D,SAAO,IAAI,aAAa,KAAK;AAC/B;AAGO,SAAS,sBAAsB,KAAmB,MAAyC;AAChG,QAAM,aAAa,IAAI,UAAU,IAAI,YAAY;AACjD,QAAM,OAAO,MAAM;AACnB,MAAI,CAAC,QAAQ,CAAC,KAAM,QAAO;AAC3B,QAAM,WAAW,WAAW,KAAK,IAAI;AACrC,MAAI,aAAa,OAAW,QAAO,WAAW,aAAa,OAAO;AAClE,MAAI,4BAA4B,IAAI,IAAI,EAAG,QAAO;AAClD,MAAI,2BAA2B,IAAI,SAAS,EAAG,QAAO;AACtD,SAAO;AACT;AAQO,SAAS,cACd,OACA,MACK;AACL,QAAM,WAAW,oBAAI,IAAe;AACpC,aAAW,QAAQ,OAAO,OAAO,KAAK;AACpC,QAAI,4BAA4B,IAAI,KAAK,MAAM,EAAG,UAAS,IAAI,KAAK,YAAY,IAAI;AACtF,MAAI,CAAC,SAAS,KAAM,QAAO,CAAC;AAC5B,QAAM,UAAe,CAAC;AACtB,aAAW,OAAO,MAAM;AACtB,UAAM,OAAO,SAAS,IAAI,IAAI,WAAW;AACzC,QAAI,CAAC,KAAM;AACX,UAAM,aAAa,IAAI,UAAU,IAAI,YAAY;AACjD,QAAI,CAAC,2BAA2B,IAAI,SAAS,KAAK,WAAW,KAAK,IAAI,MAAM,MAAO;AACnF,YAAQ,KAAK,EAAE,GAAG,MAAM,QAAQ,WAAW,KAAK,IAAI,cAAc,KAAK,IAAI,CAAC;AAAA,EAC9E;AACA,SAAO;AACT;",
6
+ "names": []
7
+ }
@@ -0,0 +1,21 @@
1
+ import { arbiQueryKeys } from "../hooks.js";
2
+ function startsWith(key, prefix) {
3
+ return prefix.every((part, i) => key[i] === part);
4
+ }
5
+ function subscribeDocumentReads(qc, onRows) {
6
+ const lists = arbiQueryKeys.allDocuments();
7
+ const one = arbiQueryKeys.document("").slice(0, -1);
8
+ return qc.getQueryCache().subscribe((event) => {
9
+ if (event.type !== "updated" || event.action.type !== "success") return;
10
+ const key = event.query.queryKey;
11
+ const data = event.query.state.data;
12
+ if (key.length !== lists.length + 1) return;
13
+ if (startsWith(key, lists) && Array.isArray(data)) onRows(data);
14
+ else if (startsWith(key, one) && data && typeof data === "object" && !Array.isArray(data))
15
+ onRows([data]);
16
+ });
17
+ }
18
+ export {
19
+ subscribeDocumentReads
20
+ };
21
+ //# sourceMappingURL=processing-settle.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/documents/processing-settle.ts"],
4
+ "sourcesContent": ["/**\n * Every read of documents that lands in the caches (a workspace's list, one document: a viewer\n * re-reading it while it processes, a refresh after an event), as rows, so live processing can be\n * settled from whichever read comes first (`settledByRows`): a document whose final event was lost\n * stops showing as in progress as soon as any read of it says it finished after that.\n */\n\nimport type { QueryClient, QueryKey } from '@tanstack/react-query'\nimport { arbiQueryKeys } from '../hooks'\nimport type { WorkspaceDocument } from './documents-cache'\n\nfunction startsWith(key: QueryKey, prefix: QueryKey): boolean {\n return prefix.every((part, i) => key[i] === part)\n}\n\n/** Call `onRows` with the documents each successful read or write of a documents cache holds. */\nexport function subscribeDocumentReads(\n qc: QueryClient,\n onRows: (rows: WorkspaceDocument[]) => void\n): () => void {\n const lists = arbiQueryKeys.allDocuments()\n const one = arbiQueryKeys.document('').slice(0, -1)\n return qc.getQueryCache().subscribe((event) => {\n if (event.type !== 'updated' || event.action.type !== 'success') return\n const key = event.query.queryKey\n const data: unknown = event.query.state.data\n if (key.length !== lists.length + 1) return\n if (startsWith(key, lists) && Array.isArray(data)) onRows(data as WorkspaceDocument[])\n else if (startsWith(key, one) && data && typeof data === 'object' && !Array.isArray(data))\n onRows([data as WorkspaceDocument])\n })\n}\n"],
5
+ "mappings": "AAQA,SAAS,qBAAqB;AAG9B,SAAS,WAAW,KAAe,QAA2B;AAC5D,SAAO,OAAO,MAAM,CAAC,MAAM,MAAM,IAAI,CAAC,MAAM,IAAI;AAClD;AAGO,SAAS,uBACd,IACA,QACY;AACZ,QAAM,QAAQ,cAAc,aAAa;AACzC,QAAM,MAAM,cAAc,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE;AAClD,SAAO,GAAG,cAAc,EAAE,UAAU,CAAC,UAAU;AAC7C,QAAI,MAAM,SAAS,aAAa,MAAM,OAAO,SAAS,UAAW;AACjE,UAAM,MAAM,MAAM,MAAM;AACxB,UAAM,OAAgB,MAAM,MAAM,MAAM;AACxC,QAAI,IAAI,WAAW,MAAM,SAAS,EAAG;AACrC,QAAI,WAAW,KAAK,KAAK,KAAK,MAAM,QAAQ,IAAI,EAAG,QAAO,IAA2B;AAAA,aAC5E,WAAW,KAAK,GAAG,KAAK,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI;AACtF,aAAO,CAAC,IAAyB,CAAC;AAAA,EACtC,CAAC;AACH;",
6
+ "names": []
7
+ }
@@ -0,0 +1,133 @@
1
+ import { useMemo, useRef } from "react";
2
+ import { SIMILARITY_THRESHOLD, useSimilarDocuments } from "./documents-data.js";
3
+ function getRelatedTotal(related) {
4
+ return (related.parent ? 1 : 0) + related.children.length + related.madeFrom.length + related.copies.length + related.duplicates.length + related.similar.length;
5
+ }
6
+ function getRelatedLabels(related) {
7
+ const parts = [];
8
+ if (related.parent) parts.push("1 parent");
9
+ if (related.children.length > 0) {
10
+ const n = related.children.length;
11
+ parts.push(`${n} ${n === 1 ? "attachment" : "attachments"}`);
12
+ }
13
+ if (related.madeFrom.length > 0) parts.push(`made from ${related.madeFrom.length}`);
14
+ if (related.copies.length > 0) {
15
+ const n = related.copies.length;
16
+ parts.push(`${n} ${n === 1 ? "copy" : "copies"}`);
17
+ }
18
+ if (related.duplicates.length > 0) {
19
+ const n = related.duplicates.length;
20
+ parts.push(`${n} ${n === 1 ? "duplicate" : "duplicates"}`);
21
+ }
22
+ if (related.similar.length > 0) {
23
+ const n = related.similar.length;
24
+ parts.push(`${n} similar`);
25
+ }
26
+ return parts;
27
+ }
28
+ function useRelatedDocuments(documents) {
29
+ const { data: similarData } = useSimilarDocuments();
30
+ const structuralKey = useMemo(() => {
31
+ const parts = [];
32
+ for (const doc of documents) {
33
+ parts.push(doc.external_id);
34
+ parts.push(doc.parent_ext_id || "");
35
+ parts.push(doc.content_hash || "");
36
+ parts.push(String(doc.current_version ?? 1));
37
+ for (const source of doc.derived_from ?? [])
38
+ parts.push(source.doc_ext_id, source.role, String(source.version ?? ""));
39
+ }
40
+ return parts.join("|");
41
+ }, [documents]);
42
+ const prevKeyRef = useRef(structuralKey);
43
+ const prevMapRef = useRef(/* @__PURE__ */ new Map());
44
+ const prevDocsRef = useRef(documents);
45
+ const prevSimilarRef = useRef(similarData);
46
+ return useMemo(() => {
47
+ if (prevKeyRef.current === structuralKey && prevSimilarRef.current === similarData && prevMapRef.current.size > 0 && prevDocsRef.current === documents) {
48
+ return prevMapRef.current;
49
+ }
50
+ prevKeyRef.current = structuralKey;
51
+ prevDocsRef.current = documents;
52
+ prevSimilarRef.current = similarData;
53
+ const map = /* @__PURE__ */ new Map();
54
+ const getOrCreate = (docId) => {
55
+ let entry = map.get(docId);
56
+ if (!entry) {
57
+ entry = { children: [], madeFrom: [], copies: [], roles: {}, duplicates: [], similar: [] };
58
+ map.set(docId, entry);
59
+ }
60
+ return entry;
61
+ };
62
+ const docById = /* @__PURE__ */ new Map();
63
+ for (const doc of documents) {
64
+ docById.set(doc.external_id, doc);
65
+ }
66
+ const byHash = /* @__PURE__ */ new Map();
67
+ for (const doc of documents) {
68
+ if (doc.content_hash) {
69
+ const list = byHash.get(doc.content_hash) || [];
70
+ list.push(doc);
71
+ byHash.set(doc.content_hash, list);
72
+ }
73
+ }
74
+ for (const doc of documents) {
75
+ if (doc.parent_ext_id) {
76
+ const parent = docById.get(doc.parent_ext_id);
77
+ if (parent) {
78
+ getOrCreate(doc.external_id).parent = parent;
79
+ getOrCreate(parent.external_id).children.push(doc);
80
+ }
81
+ }
82
+ }
83
+ for (const doc of documents) {
84
+ for (const source of doc.derived_from ?? []) {
85
+ const from = docById.get(source.doc_ext_id);
86
+ if (!from) continue;
87
+ const made = getOrCreate(doc.external_id);
88
+ made.madeFrom.push(from);
89
+ made.roles[from.external_id] = source.role;
90
+ if (source.version && source.version !== (from.current_version ?? 1)) {
91
+ made.versions = { ...made.versions, [from.external_id]: source.version };
92
+ }
93
+ const original = getOrCreate(from.external_id);
94
+ original.copies.push(doc);
95
+ original.roles[doc.external_id] = source.role;
96
+ }
97
+ }
98
+ for (const [, docs] of byHash) {
99
+ if (docs.length > 1) {
100
+ for (const doc of docs) {
101
+ getOrCreate(doc.external_id).duplicates = docs.filter(
102
+ (d) => d.external_id !== doc.external_id
103
+ );
104
+ }
105
+ }
106
+ }
107
+ if (similarData?.pairs) {
108
+ for (const pair of similarData.pairs) {
109
+ if (pair.similarity < SIMILARITY_THRESHOLD || pair.similarity >= 1) continue;
110
+ const docA = docById.get(pair.doc_a.external_id);
111
+ const docB = docById.get(pair.doc_b.external_id);
112
+ if (docA && docB) {
113
+ getOrCreate(docA.external_id).similar.push({
114
+ doc: docB,
115
+ similarity: pair.similarity
116
+ });
117
+ getOrCreate(docB.external_id).similar.push({
118
+ doc: docA,
119
+ similarity: pair.similarity
120
+ });
121
+ }
122
+ }
123
+ }
124
+ prevMapRef.current = map;
125
+ return map;
126
+ }, [documents, similarData, structuralKey]);
127
+ }
128
+ export {
129
+ getRelatedLabels,
130
+ getRelatedTotal,
131
+ useRelatedDocuments
132
+ };
133
+ //# sourceMappingURL=related-documents.js.map