@dxos/plugin-thread 0.8.4-main.67995b8 → 0.8.4-main.c4373fc

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 (283) hide show
  1. package/dist/lib/browser/ChannelContainer-BGDGZHV4.mjs +16 -0
  2. package/dist/lib/browser/ChatContainer-75KJZ4XR.mjs +15 -0
  3. package/dist/lib/browser/{app-graph-builder-N7BE5TYW.mjs → app-graph-builder-ODKIAXR7.mjs} +19 -19
  4. package/dist/lib/browser/app-graph-builder-ODKIAXR7.mjs.map +7 -0
  5. package/dist/lib/browser/{call-manager-NIPDYUVD.mjs → call-manager-BCKLI4QD.mjs} +7 -7
  6. package/dist/lib/browser/call-manager-BCKLI4QD.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-2MUYQOQE.mjs +23 -0
  8. package/dist/lib/browser/{chunk-FR7KJPNY.mjs.map → chunk-2MUYQOQE.mjs.map} +3 -3
  9. package/dist/lib/browser/chunk-B7YQ7QR2.mjs +376 -0
  10. package/dist/lib/browser/chunk-B7YQ7QR2.mjs.map +7 -0
  11. package/dist/lib/browser/{chunk-KWPRNHTK.mjs → chunk-CMCVHULC.mjs} +235 -233
  12. package/dist/lib/browser/chunk-CMCVHULC.mjs.map +7 -0
  13. package/dist/lib/browser/{chunk-GERVMFQW.mjs → chunk-CP7E2HRE.mjs} +2 -2
  14. package/dist/lib/browser/chunk-CP7E2HRE.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-ERWASUQK.mjs → chunk-HDEQRBOC.mjs} +38 -6
  16. package/dist/lib/{node-esm/chunk-25ABSYP2.mjs.map → browser/chunk-HDEQRBOC.mjs.map} +4 -4
  17. package/dist/lib/browser/chunk-L326LSNS.mjs +18 -0
  18. package/dist/lib/browser/chunk-L326LSNS.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-EV4JWI7L.mjs → chunk-T4KJ5JR4.mjs} +5 -7
  20. package/dist/lib/browser/chunk-T4KJ5JR4.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-VJMKS4CZ.mjs +619 -0
  22. package/dist/lib/browser/chunk-VJMKS4CZ.mjs.map +7 -0
  23. package/dist/lib/browser/{chunk-GCLD5ESP.mjs → chunk-VTYX3SIM.mjs} +26 -16
  24. package/dist/lib/browser/chunk-VTYX3SIM.mjs.map +7 -0
  25. package/dist/lib/browser/{chunk-6NSMBO3B.mjs → chunk-XYUJXHYV.mjs} +55 -5
  26. package/dist/lib/browser/chunk-XYUJXHYV.mjs.map +7 -0
  27. package/dist/lib/browser/{chunk-ZE7KWN36.mjs → chunk-ZCEU5K23.mjs} +461 -240
  28. package/dist/lib/browser/chunk-ZCEU5K23.mjs.map +7 -0
  29. package/dist/lib/browser/index.mjs +23 -14
  30. package/dist/lib/browser/index.mjs.map +3 -3
  31. package/dist/lib/browser/{intent-resolver-JFGLZ6VI.mjs → intent-resolver-VOQD3TQ2.mjs} +75 -17
  32. package/dist/lib/browser/intent-resolver-VOQD3TQ2.mjs.map +7 -0
  33. package/dist/lib/browser/{markdown-M3FMR7OD.mjs → markdown-R6MGRIA6.mjs} +7 -7
  34. package/dist/lib/browser/markdown-R6MGRIA6.mjs.map +7 -0
  35. package/dist/lib/browser/meta.json +1 -1
  36. package/dist/lib/browser/react-root-UMSBTN6H.mjs +28 -0
  37. package/dist/lib/browser/react-root-UMSBTN6H.mjs.map +7 -0
  38. package/dist/lib/browser/{react-surface-XWS6GIZY.mjs → react-surface-SXMQEWKE.mjs} +22 -22
  39. package/dist/lib/browser/react-surface-SXMQEWKE.mjs.map +7 -0
  40. package/dist/lib/browser/{settings-E32MTL7A.mjs → settings-TCNF54PN.mjs} +5 -5
  41. package/dist/lib/browser/{settings-E32MTL7A.mjs.map → settings-TCNF54PN.mjs.map} +1 -1
  42. package/dist/lib/browser/{state-H6CYONWE.mjs → state-ZQ4IPOJT.mjs} +5 -5
  43. package/dist/lib/browser/state-ZQ4IPOJT.mjs.map +7 -0
  44. package/dist/lib/browser/toolkit-JF4B4QIO.mjs +84 -0
  45. package/dist/lib/browser/toolkit-JF4B4QIO.mjs.map +7 -0
  46. package/dist/lib/browser/types/index.mjs +2 -2
  47. package/dist/lib/node-esm/ChannelContainer-OXC6BTU7.mjs +17 -0
  48. package/dist/lib/node-esm/{ChatContainer-IQUWU426.mjs → ChatContainer-SH6LTFQL.mjs} +6 -6
  49. package/dist/lib/node-esm/{app-graph-builder-VCW76Z6V.mjs → app-graph-builder-DMPT3MY6.mjs} +19 -19
  50. package/dist/lib/node-esm/app-graph-builder-DMPT3MY6.mjs.map +7 -0
  51. package/dist/lib/node-esm/{call-manager-D6O5ZJJ4.mjs → call-manager-Q7RY2YP4.mjs} +7 -7
  52. package/dist/lib/node-esm/call-manager-Q7RY2YP4.mjs.map +7 -0
  53. package/dist/lib/node-esm/{chunk-C3XFMUAY.mjs → chunk-2KZ4ODHU.mjs} +235 -233
  54. package/dist/lib/node-esm/chunk-2KZ4ODHU.mjs.map +7 -0
  55. package/dist/lib/node-esm/{chunk-25ABSYP2.mjs → chunk-2MMJF7DW.mjs} +38 -6
  56. package/dist/lib/node-esm/chunk-2MMJF7DW.mjs.map +7 -0
  57. package/dist/lib/node-esm/{chunk-OU5BYIDO.mjs → chunk-2V3WSLUZ.mjs} +55 -5
  58. package/dist/lib/node-esm/chunk-2V3WSLUZ.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-57XR3LEF.mjs → chunk-ABUFOZVX.mjs} +2 -2
  60. package/dist/lib/node-esm/chunk-ABUFOZVX.mjs.map +7 -0
  61. package/dist/lib/node-esm/{chunk-TDFHTCZZ.mjs → chunk-BAMZXJS4.mjs} +26 -16
  62. package/dist/lib/node-esm/chunk-BAMZXJS4.mjs.map +7 -0
  63. package/dist/lib/node-esm/chunk-BTGKI5IK.mjs +377 -0
  64. package/dist/lib/node-esm/chunk-BTGKI5IK.mjs.map +7 -0
  65. package/dist/lib/node-esm/chunk-GZ4WL2IS.mjs +25 -0
  66. package/dist/lib/node-esm/{chunk-2CXOK2TD.mjs.map → chunk-GZ4WL2IS.mjs.map} +3 -3
  67. package/dist/lib/node-esm/chunk-LCHTNRK7.mjs +19 -0
  68. package/dist/lib/node-esm/chunk-LCHTNRK7.mjs.map +7 -0
  69. package/dist/lib/node-esm/chunk-NHSIAEDW.mjs +620 -0
  70. package/dist/lib/node-esm/chunk-NHSIAEDW.mjs.map +7 -0
  71. package/dist/lib/node-esm/{chunk-GRLRWTRU.mjs → chunk-OBVAURUU.mjs} +5 -7
  72. package/dist/lib/node-esm/chunk-OBVAURUU.mjs.map +7 -0
  73. package/dist/lib/node-esm/{chunk-IHDNQLLR.mjs → chunk-TIPIOH2J.mjs} +461 -240
  74. package/dist/lib/node-esm/chunk-TIPIOH2J.mjs.map +7 -0
  75. package/dist/lib/node-esm/index.mjs +23 -14
  76. package/dist/lib/node-esm/index.mjs.map +3 -3
  77. package/dist/lib/node-esm/{intent-resolver-OXGNQ44Y.mjs → intent-resolver-AKVH66PH.mjs} +75 -17
  78. package/dist/lib/node-esm/intent-resolver-AKVH66PH.mjs.map +7 -0
  79. package/dist/lib/node-esm/{markdown-INKTE4MH.mjs → markdown-MYGTDXT6.mjs} +7 -7
  80. package/dist/lib/node-esm/markdown-MYGTDXT6.mjs.map +7 -0
  81. package/dist/lib/node-esm/meta.json +1 -1
  82. package/dist/lib/node-esm/react-root-W6AVTL5M.mjs +29 -0
  83. package/dist/lib/node-esm/react-root-W6AVTL5M.mjs.map +7 -0
  84. package/dist/lib/node-esm/{react-surface-MJ33KPYE.mjs → react-surface-NLSZJGMO.mjs} +22 -22
  85. package/dist/lib/node-esm/react-surface-NLSZJGMO.mjs.map +7 -0
  86. package/dist/lib/node-esm/{settings-SJ24YG7M.mjs → settings-ZQHGVFBY.mjs} +5 -5
  87. package/dist/lib/node-esm/{settings-SJ24YG7M.mjs.map → settings-ZQHGVFBY.mjs.map} +1 -1
  88. package/dist/lib/node-esm/{state-D7WNDT3N.mjs → state-FSLLJ5TZ.mjs} +5 -5
  89. package/dist/lib/node-esm/state-FSLLJ5TZ.mjs.map +7 -0
  90. package/dist/lib/node-esm/toolkit-DHPKJITO.mjs +85 -0
  91. package/dist/lib/node-esm/toolkit-DHPKJITO.mjs.map +7 -0
  92. package/dist/lib/node-esm/types/index.mjs +2 -2
  93. package/dist/types/src/ThreadPlugin.d.ts +1 -1
  94. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  95. package/dist/types/src/calls/call-manager.d.ts.map +1 -1
  96. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +1 -1
  97. package/dist/types/src/calls/media-manager.d.ts +1 -1
  98. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  99. package/dist/types/src/calls/types.d.ts +1 -1
  100. package/dist/types/src/calls/types.d.ts.map +1 -1
  101. package/dist/types/src/calls/util/calls-service.d.ts +4 -2
  102. package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
  103. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
  104. package/dist/types/src/calls-service.stories.d.ts +10 -9
  105. package/dist/types/src/calls-service.stories.d.ts.map +1 -1
  106. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
  107. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  108. package/dist/types/src/capabilities/call-manager.d.ts +1 -1
  109. package/dist/types/src/capabilities/call-manager.d.ts.map +1 -1
  110. package/dist/types/src/capabilities/capabilities.d.ts +2 -2
  111. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  112. package/dist/types/src/capabilities/index.d.ts +11 -10
  113. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  114. package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
  115. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  116. package/dist/types/src/capabilities/markdown.d.ts +1 -1
  117. package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
  118. package/dist/types/src/capabilities/react-root.d.ts +2 -2
  119. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  120. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  121. package/dist/types/src/capabilities/settings.d.ts +1 -1
  122. package/dist/types/src/capabilities/state.d.ts +2 -2
  123. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  124. package/dist/types/src/capabilities/toolkit.d.ts +6 -0
  125. package/dist/types/src/capabilities/toolkit.d.ts.map +1 -0
  126. package/dist/types/src/components/Call/Call.d.ts.map +1 -1
  127. package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
  128. package/dist/types/src/components/CallDebugPanel.d.ts +7 -0
  129. package/dist/types/src/components/CallDebugPanel.d.ts.map +1 -1
  130. package/dist/types/src/components/CallSidebar.d.ts.map +1 -1
  131. package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
  132. package/dist/types/src/components/ChannelContainer.stories.d.ts +89 -5
  133. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
  134. package/dist/types/src/components/Chat.stories.d.ts +91 -5
  135. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  136. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  137. package/dist/types/src/components/Comments.stories.d.ts +160 -4
  138. package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
  139. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  140. package/dist/types/src/components/CommentsThreadContainer.d.ts +2 -2
  141. package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -1
  142. package/dist/types/src/components/Lobby/Lobby.d.ts.map +1 -1
  143. package/dist/types/src/components/Media/VideoObject.d.ts +2 -2
  144. package/dist/types/src/components/Media/VideoObject.d.ts.map +1 -1
  145. package/dist/types/src/components/Media/VideoObject.stories.d.ts +18 -4
  146. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  147. package/dist/types/src/components/MessageContainer.d.ts +4 -1
  148. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  149. package/dist/types/src/components/Participant/Participant.d.ts.map +1 -1
  150. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +1 -1
  151. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +155 -3
  152. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
  153. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +157 -4
  154. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  155. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
  156. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
  157. package/dist/types/src/components/ThreadSettings.d.ts +1 -1
  158. package/dist/types/src/components/ThreadSettings.d.ts.map +1 -1
  159. package/dist/types/src/components/command-extension.d.ts.map +1 -1
  160. package/dist/types/src/components/testing.d.ts +1 -0
  161. package/dist/types/src/components/testing.d.ts.map +1 -1
  162. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  163. package/dist/types/src/hooks/index.d.ts +1 -0
  164. package/dist/types/src/hooks/index.d.ts.map +1 -1
  165. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +2 -0
  166. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +1 -0
  167. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +1 -1
  168. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -1
  169. package/dist/types/src/meta.d.ts +1 -2
  170. package/dist/types/src/meta.d.ts.map +1 -1
  171. package/dist/types/src/translations.d.ts +3 -1
  172. package/dist/types/src/translations.d.ts.map +1 -1
  173. package/dist/types/src/types/schema.d.ts +126 -109
  174. package/dist/types/src/types/schema.d.ts.map +1 -1
  175. package/dist/types/src/types/types.d.ts +259 -172
  176. package/dist/types/src/types/types.d.ts.map +1 -1
  177. package/dist/types/tsconfig.tsbuildinfo +1 -1
  178. package/package.json +64 -62
  179. package/src/ThreadPlugin.tsx +130 -124
  180. package/src/calls/call-manager.ts +2 -2
  181. package/src/calls/call-swarm-synchronizer.ts +1 -1
  182. package/src/calls/media-manager.ts +60 -34
  183. package/src/calls/types.ts +8 -4
  184. package/src/calls/util/calls-service.ts +65 -14
  185. package/src/calls/util/stub-media-streams.ts +62 -5
  186. package/src/calls-service.stories.tsx +78 -65
  187. package/src/capabilities/app-graph-builder.ts +18 -14
  188. package/src/capabilities/call-manager.ts +3 -2
  189. package/src/capabilities/capabilities.ts +7 -7
  190. package/src/capabilities/index.ts +1 -0
  191. package/src/capabilities/intent-resolver.ts +43 -9
  192. package/src/capabilities/markdown.ts +4 -3
  193. package/src/capabilities/react-root.tsx +2 -2
  194. package/src/capabilities/react-surface.tsx +14 -13
  195. package/src/capabilities/state.ts +2 -1
  196. package/src/capabilities/toolkit.ts +82 -0
  197. package/src/components/Call/Call.tsx +3 -2
  198. package/src/components/Call/Toolbar.tsx +5 -5
  199. package/src/components/CallDebugPanel.tsx +108 -49
  200. package/src/components/CallSidebar.tsx +2 -1
  201. package/src/components/ChannelContainer.stories.tsx +11 -10
  202. package/src/components/ChannelContainer.tsx +8 -7
  203. package/src/components/Chat.stories.tsx +34 -31
  204. package/src/components/ChatContainer.tsx +8 -4
  205. package/src/components/Comments.stories.tsx +39 -38
  206. package/src/components/CommentsContainer.tsx +2 -1
  207. package/src/components/CommentsThreadContainer.tsx +9 -7
  208. package/src/components/Lobby/Lobby.tsx +1 -1
  209. package/src/components/Media/VideoObject.stories.tsx +36 -28
  210. package/src/components/MessageContainer.tsx +43 -9
  211. package/src/components/Participant/Participant.tsx +13 -7
  212. package/src/components/Participant/ParticipantGrid.tsx +2 -1
  213. package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +8 -8
  214. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +44 -42
  215. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +1 -1
  216. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +2 -2
  217. package/src/components/ThreadComplementary.tsx +37 -7
  218. package/src/components/ThreadSettings.tsx +6 -7
  219. package/src/components/command-extension.ts +5 -2
  220. package/src/components/testing.ts +22 -0
  221. package/src/extensions/threads.ts +3 -3
  222. package/src/hooks/index.ts +1 -0
  223. package/src/hooks/useBlackCanvasStreamTrack.tsx +27 -0
  224. package/src/hooks/useDebugMode.ts +1 -1
  225. package/src/hooks/useVideoStreamTrack.tsx +6 -3
  226. package/src/meta.ts +3 -4
  227. package/src/testing/stories.ts +3 -3
  228. package/src/translations.ts +3 -1
  229. package/src/types/schema.ts +1 -1
  230. package/src/types/types.ts +22 -13
  231. package/src/typings/peermetrics-webrtc-stats.d.ts +17 -1
  232. package/src/typings.d.ts +8 -0
  233. package/src/util.ts +1 -1
  234. package/dist/lib/browser/ChannelContainer-3GIE7ASU.mjs +0 -16
  235. package/dist/lib/browser/ChatContainer-AIGIWAUG.mjs +0 -15
  236. package/dist/lib/browser/app-graph-builder-N7BE5TYW.mjs.map +0 -7
  237. package/dist/lib/browser/call-manager-NIPDYUVD.mjs.map +0 -7
  238. package/dist/lib/browser/chunk-3SGRT4NM.mjs +0 -367
  239. package/dist/lib/browser/chunk-3SGRT4NM.mjs.map +0 -7
  240. package/dist/lib/browser/chunk-6NSMBO3B.mjs.map +0 -7
  241. package/dist/lib/browser/chunk-ERWASUQK.mjs.map +0 -7
  242. package/dist/lib/browser/chunk-EV4JWI7L.mjs.map +0 -7
  243. package/dist/lib/browser/chunk-FR7KJPNY.mjs +0 -21
  244. package/dist/lib/browser/chunk-GCLD5ESP.mjs.map +0 -7
  245. package/dist/lib/browser/chunk-GERVMFQW.mjs.map +0 -7
  246. package/dist/lib/browser/chunk-KWPRNHTK.mjs.map +0 -7
  247. package/dist/lib/browser/chunk-LGSDKXPF.mjs +0 -18
  248. package/dist/lib/browser/chunk-LGSDKXPF.mjs.map +0 -7
  249. package/dist/lib/browser/chunk-VUWC4IJM.mjs +0 -479
  250. package/dist/lib/browser/chunk-VUWC4IJM.mjs.map +0 -7
  251. package/dist/lib/browser/chunk-ZE7KWN36.mjs.map +0 -7
  252. package/dist/lib/browser/intent-resolver-JFGLZ6VI.mjs.map +0 -7
  253. package/dist/lib/browser/markdown-M3FMR7OD.mjs.map +0 -7
  254. package/dist/lib/browser/react-root-JEUSQXI6.mjs +0 -28
  255. package/dist/lib/browser/react-root-JEUSQXI6.mjs.map +0 -7
  256. package/dist/lib/browser/react-surface-XWS6GIZY.mjs.map +0 -7
  257. package/dist/lib/browser/state-H6CYONWE.mjs.map +0 -7
  258. package/dist/lib/node-esm/ChannelContainer-7FXCKO7X.mjs +0 -17
  259. package/dist/lib/node-esm/app-graph-builder-VCW76Z6V.mjs.map +0 -7
  260. package/dist/lib/node-esm/call-manager-D6O5ZJJ4.mjs.map +0 -7
  261. package/dist/lib/node-esm/chunk-2CXOK2TD.mjs +0 -23
  262. package/dist/lib/node-esm/chunk-2MFNK53T.mjs +0 -480
  263. package/dist/lib/node-esm/chunk-2MFNK53T.mjs.map +0 -7
  264. package/dist/lib/node-esm/chunk-57XR3LEF.mjs.map +0 -7
  265. package/dist/lib/node-esm/chunk-75RJ5DJI.mjs +0 -19
  266. package/dist/lib/node-esm/chunk-75RJ5DJI.mjs.map +0 -7
  267. package/dist/lib/node-esm/chunk-C3XFMUAY.mjs.map +0 -7
  268. package/dist/lib/node-esm/chunk-FLBFYGBK.mjs +0 -368
  269. package/dist/lib/node-esm/chunk-FLBFYGBK.mjs.map +0 -7
  270. package/dist/lib/node-esm/chunk-GRLRWTRU.mjs.map +0 -7
  271. package/dist/lib/node-esm/chunk-IHDNQLLR.mjs.map +0 -7
  272. package/dist/lib/node-esm/chunk-OU5BYIDO.mjs.map +0 -7
  273. package/dist/lib/node-esm/chunk-TDFHTCZZ.mjs.map +0 -7
  274. package/dist/lib/node-esm/intent-resolver-OXGNQ44Y.mjs.map +0 -7
  275. package/dist/lib/node-esm/markdown-INKTE4MH.mjs.map +0 -7
  276. package/dist/lib/node-esm/react-root-XYYY2JXZ.mjs +0 -29
  277. package/dist/lib/node-esm/react-root-XYYY2JXZ.mjs.map +0 -7
  278. package/dist/lib/node-esm/react-surface-MJ33KPYE.mjs.map +0 -7
  279. package/dist/lib/node-esm/state-D7WNDT3N.mjs.map +0 -7
  280. /package/dist/lib/browser/{ChannelContainer-3GIE7ASU.mjs.map → ChannelContainer-BGDGZHV4.mjs.map} +0 -0
  281. /package/dist/lib/browser/{ChatContainer-AIGIWAUG.mjs.map → ChatContainer-75KJZ4XR.mjs.map} +0 -0
  282. /package/dist/lib/node-esm/{ChannelContainer-7FXCKO7X.mjs.map → ChannelContainer-OXC6BTU7.mjs.map} +0 -0
  283. /package/dist/lib/node-esm/{ChatContainer-IQUWU426.mjs.map → ChatContainer-SH6LTFQL.mjs.map} +0 -0
@@ -2,11 +2,12 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { invariant } from '@dxos/invariant';
5
6
  import { buf } from '@dxos/protocols/buf';
6
7
  import {
7
8
  type ActivitySchema,
8
- UserStateSchema,
9
9
  type UserState as UserStateProto,
10
+ UserStateSchema,
10
11
  } from '@dxos/protocols/buf/dxos/edge/calls_pb';
11
12
 
12
13
  /**
@@ -61,10 +62,13 @@ export type EncodedTrackName = string & { __brand: 'EncodedTrackName' };
61
62
 
62
63
  export const TrackNameCodec = {
63
64
  encode: (trackData: TrackObject): EncodedTrackName => {
64
- return (trackData.sessionId + '/' + trackData.trackName) as EncodedTrackName;
65
+ invariant(trackData.sessionId);
66
+ invariant(trackData.trackName);
67
+ invariant(trackData.mid);
68
+ return (trackData.sessionId + '/' + trackData.trackName + '/' + trackData.mid) as EncodedTrackName;
65
69
  },
66
70
  decode: (name: EncodedTrackName): TrackObject => {
67
- const [sessionId, trackName] = name.split('/');
68
- return { sessionId, trackName, location: 'remote' };
71
+ const [sessionId, trackName, mid] = name.split('/');
72
+ return { sessionId, trackName, location: 'remote', mid };
69
73
  },
70
74
  };
@@ -2,21 +2,22 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { PersistentLifecycle } from '@dxos/async';
5
+ import { PersistentLifecycle, Trigger, scheduleTask } from '@dxos/async';
6
6
  import { type Context, Resource } from '@dxos/context';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import { log } from '@dxos/log';
9
9
 
10
- import { HistoryCache } from './history-cache';
11
- import { BulkRequestDispatcher, FIFOScheduler } from './task-scheduling';
12
10
  import {
13
- type SessionResponse,
14
11
  type ErrorResponse,
15
12
  type RenegotiationResponse,
13
+ type SessionResponse,
16
14
  type TrackObject,
17
15
  type TracksResponse,
18
16
  } from '../types';
19
17
 
18
+ import { HistoryCache } from './history-cache';
19
+ import { BulkRequestDispatcher, FIFOScheduler } from './task-scheduling';
20
+
20
21
  const NETWORK_TIMEOUT = 5_000;
21
22
 
22
23
  export type Session = {
@@ -32,12 +33,14 @@ export type CallsServiceConfig = {
32
33
 
33
34
  export type HistoryRecord =
34
35
  | {
36
+ endpoint: string;
35
37
  type: 'request';
36
38
  time: string;
37
39
  method: string;
38
40
  body: any;
39
41
  }
40
42
  | {
43
+ endpoint: string;
41
44
  type: 'response';
42
45
  time: string;
43
46
  status: number;
@@ -115,7 +118,7 @@ export class CallsServicePeer extends Resource {
115
118
  });
116
119
  peerConnection.addEventListener('connectionstatechange', () => {
117
120
  if (peerConnection.connectionState === 'failed' || peerConnection.connectionState === 'closed') {
118
- log.warn('calls connection failed', { state: peerConnection.connectionState });
121
+ log.info('calls connection failed', { state: peerConnection.connectionState });
119
122
  void this._persistentLifecycle.scheduleRestart();
120
123
  }
121
124
  });
@@ -124,7 +127,7 @@ export class CallsServicePeer extends Resource {
124
127
  peerConnection.addEventListener('iceconnectionstatechange', () => {
125
128
  clearTimeout(iceTimeout);
126
129
  if (peerConnection.iceConnectionState === 'failed' || peerConnection.iceConnectionState === 'closed') {
127
- log.warn('calls connection to ICEs failed', { state: peerConnection.iceConnectionState });
130
+ log.info('calls connection to ICEs failed', { state: peerConnection.iceConnectionState });
128
131
  void this._persistentLifecycle.scheduleRestart();
129
132
  } else if (peerConnection.iceConnectionState === 'disconnected') {
130
133
  // TODO(mykola): we should start to inspect the connection stats from here on for
@@ -137,7 +140,7 @@ export class CallsServicePeer extends Resource {
137
140
  return;
138
141
  }
139
142
 
140
- log.warn('calls iceConnectionState timed out', { state: peerConnection.iceConnectionState, timeoutSeconds });
143
+ log.info('calls iceConnectionState timed out', { state: peerConnection.iceConnectionState, timeoutSeconds });
141
144
  void this._persistentLifecycle.scheduleRestart();
142
145
  }, timeoutSeconds * 1_000);
143
146
  }
@@ -154,6 +157,7 @@ export class CallsServicePeer extends Resource {
154
157
 
155
158
  private async _fetch<T extends ErrorResponse>(relativePath: string, requestInit?: RequestInit): Promise<T> {
156
159
  this.history.push({
160
+ endpoint: relativePath,
157
161
  type: 'request',
158
162
  time: new Date().toISOString(),
159
163
  method: requestInit?.method ?? 'GET',
@@ -169,6 +173,7 @@ export class CallsServicePeer extends Resource {
169
173
  try {
170
174
  const data = (await response.clone().json()) as T;
171
175
  this.history.push({
176
+ endpoint: relativePath,
172
177
  type: 'response',
173
178
  time: new Date().toISOString(),
174
179
  status: response.status,
@@ -182,6 +187,7 @@ export class CallsServicePeer extends Resource {
182
187
  } catch (error) {
183
188
  const text = await response.text();
184
189
  this.history.push({
190
+ endpoint: relativePath,
185
191
  type: 'response',
186
192
  time: new Date().toISOString(),
187
193
  status: response.status,
@@ -203,11 +209,11 @@ export class CallsServicePeer extends Resource {
203
209
  sessionId,
204
210
  trackName,
205
211
  }: {
212
+ ctx: Context;
206
213
  peerConnection: RTCPeerConnection;
207
214
  transceiver: RTCRtpTransceiver;
208
215
  sessionId: string;
209
216
  trackName: string;
210
- ctx?: Context;
211
217
  }): Promise<TrackObject | void> {
212
218
  log.verbose('pushing track ', trackName);
213
219
  const pushedTrackPromise = this.pushTrackDispatcher
@@ -245,9 +251,13 @@ export class CallsServicePeer extends Resource {
245
251
  };
246
252
  }),
247
253
  )
248
- .then(({ tracks }) => {
254
+ .then(async ({ tracks }) => {
249
255
  const trackData = tracks.find((t) => t.mid === transceiver.mid);
250
256
  if (trackData) {
257
+ // we wait for the transceiver to start sending data before we emit
258
+ // the track metadata to ensure that the track will be able to be
259
+ // pulled before making the metadata available to anyone else.
260
+ // await waitForTransceiverToSendData(ctx, transceiver);
251
261
  return {
252
262
  ...trackData,
253
263
  sessionId,
@@ -256,9 +266,6 @@ export class CallsServicePeer extends Resource {
256
266
  } else {
257
267
  log.error('missing track data');
258
268
  }
259
- })
260
- .catch((err) => {
261
- log.catch(err);
262
269
  });
263
270
 
264
271
  const onDispose = async () => {
@@ -280,8 +287,8 @@ export class CallsServicePeer extends Resource {
280
287
  previousTrack,
281
288
  }: {
282
289
  track: MediaStreamTrack | null;
290
+ ctx: Context;
283
291
  encodings?: RTCRtpEncodingParameters[];
284
- ctx?: Context;
285
292
  previousTrack?: TrackObject;
286
293
  }): Promise<TrackObject | undefined> {
287
294
  await this.waitUntilOpen();
@@ -404,7 +411,7 @@ export class CallsServicePeer extends Resource {
404
411
  })
405
412
  .catch((err) => log.catch(err));
406
413
  } else {
407
- log.warn('missing track info', { trackData, availableTracks: Array.from(trackMap.keys()) });
414
+ log.info('missing track info', { trackData, availableTracks: Array.from(trackMap.keys()) });
408
415
  }
409
416
  });
410
417
 
@@ -528,3 +535,47 @@ const peerConnectionIsConnected = async (peerConnection: RTCPeerConnection) => {
528
535
  await connected;
529
536
  }
530
537
  };
538
+
539
+ const INITIAL_DELAY = 50;
540
+ const MAX_DELAY = 500;
541
+ const MAX_RETRIES = 20;
542
+ const WAIT_FOR_DATA_TIMEOUT = 10_000;
543
+
544
+ const waitForTransceiverToSendData = async (ctx: Context, transceiver: RTCRtpTransceiver): Promise<void> => {
545
+ let delay = INITIAL_DELAY;
546
+ let checks = 0;
547
+ const waitForData = new Trigger();
548
+ ctx.onDispose(() => waitForData.throw(new Error('Transceiver was closed')));
549
+
550
+ const checkStats = async () => {
551
+ if (ctx.disposed) return;
552
+
553
+ try {
554
+ const stats = await transceiver.sender.getStats();
555
+ let dataFound = false;
556
+ stats.forEach((stat) => {
557
+ if (stat.type === 'outbound-rtp' && stat.bytesSent > 0) {
558
+ dataFound = true;
559
+ }
560
+ });
561
+
562
+ if (dataFound) {
563
+ waitForData.wake();
564
+ return;
565
+ }
566
+ } catch {
567
+ // Stats might not be available yet, continue checking
568
+ }
569
+ checks++;
570
+ if (checks > MAX_RETRIES) {
571
+ waitForData.throw(new Error('Transceiver did not send data'));
572
+ return;
573
+ }
574
+
575
+ delay = Math.min(delay * 2, MAX_DELAY); // Exponential backoff with max cap
576
+ scheduleTask(ctx, checkStats, delay);
577
+ };
578
+
579
+ void checkStats();
580
+ return waitForData.wait({ timeout: WAIT_FOR_DATA_TIMEOUT });
581
+ };
@@ -3,8 +3,8 @@
3
3
  //
4
4
  //
5
5
 
6
- import { waitForCondition, scheduleTaskInterval } from '@dxos/async';
7
- import { cancelWithContext, type Context } from '@dxos/context';
6
+ import { scheduleTaskInterval, waitForCondition } from '@dxos/async';
7
+ import { type Context, cancelWithContext } from '@dxos/context';
8
8
  import { invariant } from '@dxos/invariant';
9
9
 
10
10
  /**
@@ -30,7 +30,7 @@ export const createBlackCanvasStreamTrack = async ({
30
30
  canvasCtx.fillStyle = 'black';
31
31
  canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
32
32
  };
33
- scheduleTaskInterval(ctx, async () => drawFrame(), 1_000);
33
+ scheduleTaskInterval(ctx, async () => drawFrame(), 200);
34
34
 
35
35
  const track = canvas.captureStream().getVideoTracks()[0];
36
36
  drawFrame();
@@ -40,6 +40,20 @@ export const createBlackCanvasStreamTrack = async ({
40
40
  return track;
41
41
  };
42
42
 
43
+ let audioContextStartedPreviously = false;
44
+ const userGestureEvents = [
45
+ 'click',
46
+ 'contextmenu',
47
+ 'auxclick',
48
+ 'dblclick',
49
+ 'mousedown',
50
+ 'mouseup',
51
+ 'pointerup',
52
+ 'touchend',
53
+ 'keydown',
54
+ 'keyup',
55
+ ];
56
+
43
57
  /**
44
58
  * Creates an inaudible audio stream track.
45
59
  * We need this to have audio track available when audio is disabled.
@@ -53,14 +67,57 @@ export const createInaudibleAudioStreamTrack = async ({ ctx }: { ctx: Context })
53
67
 
54
68
  const gainNode = audioContext.createGain();
55
69
  // even w/ gain at 0 some packets are sent
56
- gainNode.gain.setValueAtTime(0.02, audioContext.currentTime);
70
+ gainNode.gain.setValueAtTime(0, audioContext.currentTime);
57
71
  oscillator.connect(gainNode);
58
72
 
59
73
  const destination = audioContext.createMediaStreamDestination();
60
74
  gainNode.connect(destination);
61
- oscillator.start();
75
+
76
+ let oscillatorStarted = false;
77
+ const ensureOscillatorStarted = () => {
78
+ if (oscillatorStarted) return;
79
+ oscillator.start();
80
+ oscillatorStarted = true;
81
+ };
82
+
83
+ const stateChangeHandler = () => {
84
+ if (audioContext.state === 'running') {
85
+ audioContextStartedPreviously = true;
86
+ ensureOscillatorStarted();
87
+ }
88
+ if (audioContext.state === 'suspended' || (audioContext.state as string) === 'interrupted') {
89
+ resumeAudioContext();
90
+ }
91
+ };
92
+
93
+ audioContext.addEventListener('statechange', stateChangeHandler);
94
+
95
+ const resumeAudioContext = () => {
96
+ void audioContext.resume().then(() => {
97
+ cleanUpUserGestureListeners();
98
+ });
99
+ };
100
+
101
+ const cleanUpUserGestureListeners = () => {
102
+ userGestureEvents.forEach((gesture) => {
103
+ document.removeEventListener(gesture, resumeAudioContext, {
104
+ capture: true,
105
+ });
106
+ });
107
+ };
108
+
109
+ if (audioContextStartedPreviously) {
110
+ resumeAudioContext();
111
+ } else {
112
+ userGestureEvents.forEach((gesture) => {
113
+ document.addEventListener(gesture, resumeAudioContext, {
114
+ capture: true,
115
+ });
116
+ });
117
+ }
62
118
 
63
119
  ctx.onDispose(async () => {
120
+ cleanUpUserGestureListeners();
64
121
  oscillator.disconnect();
65
122
  oscillator.stop();
66
123
  await audioContext.close();
@@ -2,8 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import '@dxos-theme';
6
-
5
+ import { type Meta, type StoryObj } from '@storybook/react-vite';
7
6
  import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
7
 
9
8
  import { scheduleTask, sleep } from '@dxos/async';
@@ -13,14 +12,15 @@ import { log } from '@dxos/log';
13
12
  import { Config, useConfig } from '@dxos/react-client';
14
13
  import { withClientProvider } from '@dxos/react-client/testing';
15
14
  import { Button } from '@dxos/react-ui';
15
+ import { withTheme } from '@dxos/react-ui/testing';
16
16
  import { Json } from '@dxos/react-ui-syntax-highlighter';
17
- import { withLayout, withTheme } from '@dxos/storybook-utils';
18
17
 
19
- import { type TrackObject, CallsServicePeer, CALLS_URL } from './calls';
20
- import { useInaudibleAudioStreamTrack, useVideoStreamTrack } from './hooks';
21
- // @ts-ignore
22
- import video from '../testing/video.mp4';
18
+ const testVideo = new URL('../testing/video.mp4', import.meta.url).href;
19
+
20
+ import { CALLS_URL, CallsServicePeer, type TrackObject } from './calls';
21
+ import { useBlackCanvasStreamTrack, useInaudibleAudioStreamTrack, useVideoStreamTrack } from './hooks';
23
22
 
23
+ // TODO(burdon): THIS IS TOO COMPLEX FOR A TEST SETUP.
24
24
  const pushAndPullTrack = (mediaStreamTrack?: MediaStreamTrack) => {
25
25
  const config = useConfig();
26
26
  const callsConfig = {
@@ -35,16 +35,18 @@ const pushAndPullTrack = (mediaStreamTrack?: MediaStreamTrack) => {
35
35
  const [pulledTrack, setPulledTrack] = useState<MediaStreamTrack | undefined>(undefined);
36
36
  const hadRun = useRef(false);
37
37
 
38
+ const deps: any[] = [];
38
39
  // Push/pull video stream track to cloudflare.
39
40
  useEffect(() => {
40
41
  if (hadRun.current || !mediaStreamTrack || !peerPush || !peerPull) {
41
- log.info('not running', { hadRun: hadRun.current, mediaStreamTrack, peerPush, peerPull });
42
42
  return;
43
43
  }
44
44
  hadRun.current = true;
45
45
  const ctx = Context.default();
46
+ log.info('setting up ctx', { ctx, mediaStreamTrack, peerPush, peerPull });
47
+ deps.push([ctx, mediaStreamTrack, peerPush, peerPull]);
46
48
  ctx.onDispose(() => {
47
- log.info('disposing ctx', { ctx });
49
+ log.info('disposing ctx', {});
48
50
  });
49
51
  scheduleTask(
50
52
  ctx,
@@ -60,15 +62,12 @@ const pushAndPullTrack = (mediaStreamTrack?: MediaStreamTrack) => {
60
62
  // Push track to cloudflare.
61
63
  performance.mark('push:begin');
62
64
  log.info('pushing track', { track: mediaStreamTrack });
63
- trackInfo.current = await peerPush.pushTrack({ track: mediaStreamTrack });
65
+ trackInfo.current = await peerPush.pushTrack({ track: mediaStreamTrack, ctx: Context.default() });
64
66
  performance.mark('push:end');
65
67
  const pushTime = performance.measure('push', 'push:begin', 'push:end').duration;
66
68
  log.info('successfully pushed track', { pushTime, trackInfo: trackInfo.current });
67
69
  setMetrics((prev) => ({ ...prev, 'time to push track [ms]': Math.round(pushTime) }));
68
70
 
69
- // Wait for cloudflare to process the track.
70
- await sleep(1000);
71
-
72
71
  // Pull track from cloudflare.
73
72
  performance.mark('pullTrack:begin');
74
73
  pullCtx.current = Context.default();
@@ -104,7 +103,10 @@ const pushAndPullTrack = (mediaStreamTrack?: MediaStreamTrack) => {
104
103
 
105
104
  const rePullTrack = useCallback(async () => {
106
105
  performance.mark('rePullVideo:begin');
107
- invariant(pulledTrack);
106
+ if (!pulledTrack) {
107
+ log.info('no pulled track, skipping re-pull', { pulledTrack });
108
+ return;
109
+ }
108
110
  pulledTrack.stop();
109
111
  await pullCtx.current!.dispose();
110
112
  pullCtx.current = Context.default();
@@ -123,12 +125,57 @@ const pushAndPullTrack = (mediaStreamTrack?: MediaStreamTrack) => {
123
125
  pulledTrack,
124
126
  rePullTrack,
125
127
  metrics,
128
+ pushService: peerPush,
129
+ pullService: peerPull,
126
130
  };
127
131
  };
128
132
 
133
+ type StoryProps = { source: string };
134
+
135
+ const DefaultStory = ({ source }: StoryProps) => {
136
+ const pushVideoElement = useRef<HTMLVideoElement>(null);
137
+ const pullVideoElement = useRef<HTMLVideoElement>(null);
138
+ // Get video stream track.
139
+ const videoStreamTrack = useVideoStreamTrack(pushVideoElement, source);
140
+ const { pulledTrack, rePullTrack, metrics } = pushAndPullTrack(videoStreamTrack);
141
+ const hadRun = useRef(false);
142
+
143
+ // Push/pull video stream track to cloudflare.
144
+ useEffect(() => {
145
+ if (!pulledTrack || hadRun.current) {
146
+ return;
147
+ }
148
+ hadRun.current = true;
149
+ const ctx = Context.default();
150
+ scheduleTask(ctx, async () => {
151
+ pullVideoElement.current!.srcObject = new MediaStream([pulledTrack]);
152
+ await pullVideoElement.current!.play();
153
+ });
154
+
155
+ return () => {
156
+ void ctx.dispose();
157
+ };
158
+ }, [pulledTrack]);
159
+
160
+ return (
161
+ <div className='grid grid-rows-3 gap-4 items-center'>
162
+ <video ref={pushVideoElement} muted autoPlay loop />
163
+ <div className='flex flex-col gap-4'>
164
+ <video ref={pullVideoElement} muted />
165
+ <Button disabled={!pulledTrack} onClick={rePullTrack}>
166
+ Re-pull video
167
+ </Button>
168
+ </div>
169
+ <Json data={metrics} />
170
+ </div>
171
+ );
172
+ };
173
+
129
174
  const meta = {
130
175
  title: 'plugins/plugin-thread/calls-service',
176
+ render: DefaultStory,
131
177
  decorators: [
178
+ withTheme,
132
179
  withClientProvider({
133
180
  config: new Config({
134
181
  runtime: {
@@ -138,72 +185,25 @@ const meta = {
138
185
  },
139
186
  }),
140
187
  }),
141
- withTheme,
142
- withLayout(),
143
188
  ],
144
189
  parameters: {
145
190
  layout: 'centered',
146
191
  },
147
- };
192
+ } satisfies Meta<typeof DefaultStory>;
148
193
 
149
194
  export default meta;
150
195
 
151
- export const Default = {
152
- render: ({ videoSrc }: { videoSrc: string }) => {
153
- const pushVideoElement = useRef<HTMLVideoElement>(null);
154
- const pullVideoElement = useRef<HTMLVideoElement>(null);
155
- // Get video stream track.
156
- const videoStreamTrack = useVideoStreamTrack(pushVideoElement, videoSrc);
157
- const { pulledTrack, rePullTrack, metrics } = pushAndPullTrack(videoStreamTrack);
158
- const hadRun = useRef(false);
159
-
160
- // Push/pull video stream track to cloudflare.
161
- useEffect(() => {
162
- if (!pulledTrack || hadRun.current) {
163
- return;
164
- }
165
- hadRun.current = true;
166
- const ctx = Context.default();
167
- scheduleTask(ctx, async () => {
168
- pullVideoElement.current!.srcObject = new MediaStream([pulledTrack]);
169
- await pullVideoElement.current!.play();
170
- });
171
-
172
- return () => {
173
- void ctx.dispose();
174
- };
175
- }, [pulledTrack]);
196
+ type Story = StoryObj<typeof meta>;
176
197
 
177
- return (
178
- <div className='grid grid-rows-3 gap-4 items-center'>
179
- <video ref={pushVideoElement} muted autoPlay loop />
180
- <div className='flex flex-col gap-4'>
181
- <video ref={pullVideoElement} muted />
182
- <Button
183
- disabled={
184
- !(
185
- pullVideoElement?.current?.srcObject instanceof MediaStream &&
186
- pullVideoElement.current.srcObject.getTracks()[0]
187
- )
188
- }
189
- onClick={rePullTrack}
190
- >
191
- Re-pull video
192
- </Button>
193
- </div>
194
- <Json data={metrics} />
195
- </div>
196
- );
197
- },
198
+ export const Default: Story = {
198
199
  args: {
199
- videoSrc: video,
200
+ source: testVideo,
200
201
  },
201
202
  };
202
203
 
203
204
  export const InaudibleAudioStreamTrack = {
204
205
  render: () => {
205
206
  const audioStreamTrack = useInaudibleAudioStreamTrack();
206
-
207
207
  const { rePullTrack, metrics } = pushAndPullTrack(audioStreamTrack);
208
208
 
209
209
  return (
@@ -214,3 +214,16 @@ export const InaudibleAudioStreamTrack = {
214
214
  );
215
215
  },
216
216
  };
217
+
218
+ export const BlackVideoStreamTrack = {
219
+ render: () => {
220
+ const videoStreamTrack = useBlackCanvasStreamTrack();
221
+ const { rePullTrack, metrics } = pushAndPullTrack(videoStreamTrack);
222
+ return (
223
+ <div className='flex flex-col gap-4 items-center'>
224
+ <Json data={metrics} />
225
+ <Button onClick={rePullTrack}>Re-pull audio</Button>
226
+ </div>
227
+ );
228
+ },
229
+ };
@@ -3,30 +3,34 @@
3
3
  //
4
4
 
5
5
  import { Rx } from '@effect-rx/rx-react';
6
- import { Option, pipe } from 'effect';
6
+ import * as Function from 'effect/Function';
7
+ import * as Option from 'effect/Option';
7
8
 
8
- import { Capabilities, contributes, createIntent, type PluginContext } from '@dxos/app-framework';
9
+ import { Capabilities, type PluginContext, contributes, createIntent } from '@dxos/app-framework';
9
10
  import { Obj } from '@dxos/echo';
10
11
  import { AttentionCapabilities } from '@dxos/plugin-attention';
11
- import { PLANK_COMPANION_TYPE, ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
12
- import { createExtension, ROOT_ID, rxFromSignal } from '@dxos/plugin-graph';
12
+ import { ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE, PLANK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
13
+ import { ROOT_ID, createExtension, rxFromSignal } from '@dxos/plugin-graph';
13
14
  import { fullyQualifiedId } from '@dxos/react-client/echo';
14
15
 
15
- import { ThreadCapabilities } from './capabilities';
16
- import { meta, THREAD_PLUGIN } from '../meta';
16
+ import { meta } from '../meta';
17
17
  import { ChannelType, ThreadAction } from '../types';
18
18
  import { getAnchor } from '../util';
19
19
 
20
+ import { ThreadCapabilities } from './capabilities';
21
+
22
+ // TODO(wittjosiah): Highlight active calls in L1.
23
+ // Track active meetings by subscribing to meetings query and polling the swarms of recent meetings in the space.
20
24
  export default (context: PluginContext) => {
21
25
  const resolve = (typename: string) =>
22
26
  context.getCapabilities(Capabilities.Metadata).find(({ id }) => id === typename)?.metadata ?? {};
23
27
 
24
28
  return contributes(Capabilities.AppGraphBuilder, [
25
29
  createExtension({
26
- id: `${THREAD_PLUGIN}/active-call`,
30
+ id: `${meta.id}/active-call`,
27
31
  connector: (node) =>
28
32
  Rx.make((get) =>
29
- pipe(
33
+ Function.pipe(
30
34
  get(node),
31
35
  Option.flatMap((node) => (node.id === ROOT_ID ? Option.some(node) : Option.none())),
32
36
  Option.map((node) => {
@@ -40,7 +44,7 @@ export default (context: PluginContext) => {
40
44
  type: DECK_COMPANION_TYPE,
41
45
  data: null,
42
46
  properties: {
43
- label: ['call panel label', { ns: THREAD_PLUGIN }],
47
+ label: ['call panel label', { ns: meta.id }],
44
48
  icon: 'ph--video-conference--regular',
45
49
  position: 'hoist',
46
50
  disposition: 'hidden',
@@ -58,10 +62,10 @@ export default (context: PluginContext) => {
58
62
  // TODO(wittjosiah): The channel shouldn't become the companion during a call.
59
63
  // Alternative: the call/meeting/thread should be a child node of the channel and that should be opened.
60
64
  createExtension({
61
- id: `${THREAD_PLUGIN}/channel-chat-companion`,
65
+ id: `${meta.id}/channel-chat-companion`,
62
66
  connector: (node) => {
63
67
  return Rx.make((get) => {
64
- return pipe(
68
+ return Function.pipe(
65
69
  get(node),
66
70
  Option.flatMap((node) => (Obj.instanceOf(ChannelType, node.data) ? Option.some(node.data) : Option.none())),
67
71
  Option.map((channel) => {
@@ -79,7 +83,7 @@ export default (context: PluginContext) => {
79
83
  type: PLANK_COMPANION_TYPE,
80
84
  data: 'chat',
81
85
  properties: {
82
- label: ['channel companion label', { ns: THREAD_PLUGIN }],
86
+ label: ['channel companion label', { ns: meta.id }],
83
87
  icon: 'ph--hash--regular',
84
88
  position: 'hoist',
85
89
  disposition: 'hidden',
@@ -96,7 +100,7 @@ export default (context: PluginContext) => {
96
100
  id: `${meta.id}/comments-companion`,
97
101
  connector: (node) =>
98
102
  Rx.make((get) =>
99
- pipe(
103
+ Function.pipe(
100
104
  get(node),
101
105
  Option.flatMap((node) => {
102
106
  if (!Obj.isObject(node.data) || Obj.instanceOf(ChannelType, node.data)) {
@@ -126,7 +130,7 @@ export default (context: PluginContext) => {
126
130
  id: `${meta.id}/comment-toolbar`,
127
131
  actions: (node) =>
128
132
  Rx.make((get) =>
129
- pipe(
133
+ Function.pipe(
130
134
  get(node),
131
135
  Option.flatMap((node) => {
132
136
  if (!Obj.isObject(node.data) || Obj.instanceOf(ChannelType, node.data)) {
@@ -2,12 +2,13 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
- import { contributes, type PluginContext } from '@dxos/app-framework';
5
+ import { type PluginContext, contributes } from '@dxos/app-framework';
6
6
  import { ClientCapabilities } from '@dxos/plugin-client';
7
7
 
8
- import { ThreadCapabilities } from './capabilities';
9
8
  import { CallManager } from '../calls';
10
9
 
10
+ import { ThreadCapabilities } from './capabilities';
11
+
11
12
  export default async (context: PluginContext) => {
12
13
  const client = context.getCapability(ClientCapabilities.Client);
13
14
  const callManager = new CallManager(client);