@dxos/plugin-thread 0.8.3 → 0.8.4-main.28f8d3d

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 (294) hide show
  1. package/dist/lib/browser/ChannelContainer-O2SFQJU7.mjs +16 -0
  2. package/dist/lib/browser/ChatContainer-PVT3DUZJ.mjs +15 -0
  3. package/dist/lib/browser/{app-graph-builder-OY7R7EJP.mjs → app-graph-builder-AF3M7UWN.mjs} +8 -8
  4. package/dist/lib/browser/app-graph-builder-AF3M7UWN.mjs.map +7 -0
  5. package/dist/lib/browser/{call-manager-APQAZWHT.mjs → call-manager-XRRCAVLI.mjs} +6 -5
  6. package/dist/lib/browser/call-manager-XRRCAVLI.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-2CWJBXBH.mjs +21 -0
  8. package/dist/lib/browser/{chunk-R5MDLUPC.mjs → chunk-4APCDRSH.mjs} +3 -3
  9. package/dist/lib/browser/{chunk-R5MDLUPC.mjs.map → chunk-4APCDRSH.mjs.map} +1 -1
  10. package/dist/lib/browser/{chunk-AEXWNS6Z.mjs → chunk-DW7JD64V.mjs} +14 -5
  11. package/dist/lib/browser/chunk-DW7JD64V.mjs.map +7 -0
  12. package/dist/lib/browser/{chunk-IIUTBDVB.mjs → chunk-EV4JWI7L.mjs} +2 -2
  13. package/dist/lib/browser/chunk-FY4ZRD5X.mjs +367 -0
  14. package/dist/lib/browser/chunk-FY4ZRD5X.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-JKQUJOTX.mjs → chunk-GERVMFQW.mjs} +2 -2
  16. package/dist/lib/browser/chunk-J3JO5NWO.mjs +477 -0
  17. package/dist/lib/browser/chunk-J3JO5NWO.mjs.map +7 -0
  18. package/dist/lib/browser/chunk-JGKMMI65.mjs +56 -0
  19. package/dist/lib/browser/chunk-JGKMMI65.mjs.map +7 -0
  20. package/dist/lib/browser/{chunk-4H4A264L.mjs → chunk-TUFWPOVS.mjs} +148 -158
  21. package/dist/lib/browser/chunk-TUFWPOVS.mjs.map +7 -0
  22. package/dist/lib/browser/{chunk-5P5BH5GE.mjs → chunk-X5PIP5YR.mjs} +67 -6
  23. package/dist/lib/browser/chunk-X5PIP5YR.mjs.map +7 -0
  24. package/dist/lib/browser/{chunk-XZKBN3NS.mjs → chunk-ZJ7QBXK6.mjs} +246 -245
  25. package/dist/lib/browser/chunk-ZJ7QBXK6.mjs.map +7 -0
  26. package/dist/lib/browser/index.mjs +36 -42
  27. package/dist/lib/browser/index.mjs.map +3 -3
  28. package/dist/lib/browser/{intent-resolver-FK2MDVDT.mjs → intent-resolver-DCY4P4OX.mjs} +31 -15
  29. package/dist/lib/browser/intent-resolver-DCY4P4OX.mjs.map +7 -0
  30. package/dist/lib/browser/{markdown-TE5SWWNJ.mjs → markdown-WZSXCEZJ.mjs} +8 -8
  31. package/dist/lib/browser/markdown-WZSXCEZJ.mjs.map +7 -0
  32. package/dist/lib/browser/meta.json +1 -1
  33. package/dist/lib/browser/react-root-QXPALOUQ.mjs +28 -0
  34. package/dist/lib/browser/{react-surface-VXUJKSOG.mjs → react-surface-PYAMIADB.mjs} +12 -11
  35. package/dist/lib/browser/react-surface-PYAMIADB.mjs.map +7 -0
  36. package/dist/lib/browser/{settings-RB2RSLXV.mjs → settings-AC6YSASL.mjs} +4 -4
  37. package/dist/lib/browser/{state-RKL5MSDP.mjs → state-2T4KDWBX.mjs} +4 -4
  38. package/dist/lib/browser/{state-RKL5MSDP.mjs.map → state-2T4KDWBX.mjs.map} +2 -2
  39. package/dist/lib/browser/types/index.mjs +2 -2
  40. package/dist/lib/node-esm/ChannelContainer-B2ZGAE4P.mjs +17 -0
  41. package/dist/lib/node-esm/{ChatContainer-F6CSADV7.mjs → ChatContainer-2CT4PJ7I.mjs} +6 -5
  42. package/dist/lib/node-esm/{app-graph-builder-BAHBHYWI.mjs → app-graph-builder-OLSJVCWY.mjs} +8 -8
  43. package/dist/lib/node-esm/app-graph-builder-OLSJVCWY.mjs.map +7 -0
  44. package/dist/lib/node-esm/{call-manager-UUYXLF4T.mjs → call-manager-EI7FXRAU.mjs} +6 -5
  45. package/dist/lib/node-esm/call-manager-EI7FXRAU.mjs.map +7 -0
  46. package/dist/lib/node-esm/{chunk-WXNPD542.mjs → chunk-4TME3BR4.mjs} +147 -158
  47. package/dist/lib/node-esm/chunk-4TME3BR4.mjs.map +7 -0
  48. package/dist/lib/node-esm/{chunk-PGRP3O4O.mjs → chunk-57XR3LEF.mjs} +2 -2
  49. package/dist/lib/node-esm/chunk-6CRHHOST.mjs +23 -0
  50. package/dist/lib/node-esm/chunk-BF4UKS55.mjs +368 -0
  51. package/dist/lib/node-esm/chunk-BF4UKS55.mjs.map +7 -0
  52. package/dist/lib/node-esm/{chunk-ESQC6SYE.mjs → chunk-GRLRWTRU.mjs} +2 -2
  53. package/dist/lib/node-esm/{chunk-K4KAUOKT.mjs → chunk-PYTVBN5J.mjs} +3 -3
  54. package/dist/lib/node-esm/{chunk-K4KAUOKT.mjs.map → chunk-PYTVBN5J.mjs.map} +1 -1
  55. package/dist/lib/node-esm/chunk-QBHKLWGR.mjs +58 -0
  56. package/dist/lib/node-esm/chunk-QBHKLWGR.mjs.map +7 -0
  57. package/dist/lib/node-esm/{chunk-O3V45YJP.mjs → chunk-SED3O2XO.mjs} +66 -6
  58. package/dist/lib/node-esm/chunk-SED3O2XO.mjs.map +7 -0
  59. package/dist/lib/node-esm/chunk-VNG6M2IY.mjs +478 -0
  60. package/dist/lib/node-esm/chunk-VNG6M2IY.mjs.map +7 -0
  61. package/dist/lib/node-esm/{chunk-UJMPYKT3.mjs → chunk-XVKWHTH4.mjs} +14 -5
  62. package/dist/lib/node-esm/chunk-XVKWHTH4.mjs.map +7 -0
  63. package/dist/lib/node-esm/{chunk-2RNIPFDA.mjs → chunk-YIDU3DXK.mjs} +246 -245
  64. package/dist/lib/node-esm/chunk-YIDU3DXK.mjs.map +7 -0
  65. package/dist/lib/node-esm/index.mjs +36 -42
  66. package/dist/lib/node-esm/index.mjs.map +3 -3
  67. package/dist/lib/node-esm/{intent-resolver-BU73VYW3.mjs → intent-resolver-QGTPU6QB.mjs} +31 -15
  68. package/dist/lib/node-esm/intent-resolver-QGTPU6QB.mjs.map +7 -0
  69. package/dist/lib/node-esm/{markdown-HJUWNBLS.mjs → markdown-3MZXUGUA.mjs} +8 -8
  70. package/dist/lib/node-esm/markdown-3MZXUGUA.mjs.map +7 -0
  71. package/dist/lib/node-esm/meta.json +1 -1
  72. package/dist/lib/node-esm/{react-root-RUXOAQNW.mjs → react-root-7ZFJYVUZ.mjs} +12 -11
  73. package/dist/lib/{browser/react-root-NK3A4VG7.mjs.map → node-esm/react-root-7ZFJYVUZ.mjs.map} +1 -1
  74. package/dist/lib/node-esm/{react-surface-ELXFYKP6.mjs → react-surface-UJFCSFNO.mjs} +12 -11
  75. package/dist/lib/node-esm/react-surface-UJFCSFNO.mjs.map +7 -0
  76. package/dist/lib/node-esm/{settings-EA7DFSM6.mjs → settings-N52O7MLS.mjs} +4 -4
  77. package/dist/lib/node-esm/{state-6AUTNROZ.mjs → state-62TQKQVB.mjs} +4 -4
  78. package/dist/lib/node-esm/{state-6AUTNROZ.mjs.map → state-62TQKQVB.mjs.map} +2 -2
  79. package/dist/lib/node-esm/types/index.mjs +2 -2
  80. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  81. package/dist/types/src/calls/call-manager.d.ts +1 -1
  82. package/dist/types/src/calls/call-manager.d.ts.map +1 -1
  83. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +1 -1
  84. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  85. package/dist/types/src/calls/types.d.ts +1 -1
  86. package/dist/types/src/calls/types.d.ts.map +1 -1
  87. package/dist/types/src/calls/util/calls-service.d.ts +5 -2
  88. package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
  89. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
  90. package/dist/types/src/calls-service.stories.d.ts +22 -0
  91. package/dist/types/src/calls-service.stories.d.ts.map +1 -0
  92. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  93. package/dist/types/src/capabilities/call-manager.d.ts.map +1 -1
  94. package/dist/types/src/capabilities/capabilities.d.ts +2 -2
  95. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  96. package/dist/types/src/capabilities/index.d.ts +1 -1
  97. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  98. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  99. package/dist/types/src/capabilities/markdown.d.ts +1 -1
  100. package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
  101. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  102. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  103. package/dist/types/src/components/Call/Call.d.ts.map +1 -1
  104. package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
  105. package/dist/types/src/components/CallDebugPanel.d.ts.map +1 -1
  106. package/dist/types/src/components/CallSidebar.d.ts.map +1 -1
  107. package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
  108. package/dist/types/src/components/ChannelContainer.stories.d.ts +2 -2
  109. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
  110. package/dist/types/src/components/Chat.stories.d.ts +3 -2
  111. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  112. package/dist/types/src/components/ChatContainer.d.ts +2 -2
  113. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  114. package/dist/types/src/components/Comments.stories.d.ts +1 -1
  115. package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
  116. package/dist/types/src/components/CommentsContainer.d.ts +4 -4
  117. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  118. package/dist/types/src/components/CommentsThreadContainer.d.ts +14 -0
  119. package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -0
  120. package/dist/types/src/components/Lobby/Lobby.d.ts.map +1 -1
  121. package/dist/types/src/components/Media/VideoObject.d.ts +1 -1
  122. package/dist/types/src/components/Media/VideoObject.stories.d.ts +1 -1
  123. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  124. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  125. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +1 -1
  126. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +1 -1
  127. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
  128. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +1 -1
  129. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  130. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
  131. package/dist/types/src/components/index.d.ts +1 -1
  132. package/dist/types/src/components/index.d.ts.map +1 -1
  133. package/dist/types/src/extensions/threads.d.ts +2 -2
  134. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  135. package/dist/types/src/hooks/index.d.ts +2 -0
  136. package/dist/types/src/hooks/index.d.ts.map +1 -1
  137. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +2 -0
  138. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +1 -0
  139. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +3 -0
  140. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -0
  141. package/dist/types/src/testing/stories.d.ts.map +1 -1
  142. package/dist/types/src/translations.d.ts +74 -194
  143. package/dist/types/src/translations.d.ts.map +1 -1
  144. package/dist/types/src/types/schema.d.ts +53 -22
  145. package/dist/types/src/types/schema.d.ts.map +1 -1
  146. package/dist/types/src/types/types.d.ts +72 -24
  147. package/dist/types/src/types/types.d.ts.map +1 -1
  148. package/dist/types/src/util.d.ts +17 -2
  149. package/dist/types/src/util.d.ts.map +1 -1
  150. package/dist/types/tsconfig.tsbuildinfo +1 -1
  151. package/package.json +49 -48
  152. package/src/ThreadPlugin.tsx +9 -24
  153. package/src/calls/call-manager.ts +7 -3
  154. package/src/calls/call-swarm-synchronizer.ts +1 -1
  155. package/src/calls/media-manager.ts +13 -6
  156. package/src/calls/types.ts +1 -1
  157. package/src/calls/util/calls-service.ts +12 -8
  158. package/src/calls/util/stub-media-streams.ts +5 -8
  159. package/src/calls-service.stories.tsx +216 -0
  160. package/src/capabilities/app-graph-builder.ts +6 -5
  161. package/src/capabilities/call-manager.ts +3 -2
  162. package/src/capabilities/capabilities.ts +2 -2
  163. package/src/capabilities/intent-resolver.ts +26 -7
  164. package/src/capabilities/markdown.ts +4 -3
  165. package/src/capabilities/react-surface.tsx +5 -4
  166. package/src/capabilities/state.ts +2 -1
  167. package/src/components/Call/Call.tsx +4 -3
  168. package/src/components/Call/Toolbar.tsx +5 -5
  169. package/src/components/CallDebugPanel.tsx +3 -3
  170. package/src/components/CallSidebar.tsx +2 -1
  171. package/src/components/ChannelContainer.stories.tsx +8 -7
  172. package/src/components/ChannelContainer.tsx +13 -11
  173. package/src/components/Chat.stories.tsx +7 -6
  174. package/src/components/ChatContainer.tsx +16 -14
  175. package/src/components/Comments.stories.tsx +24 -16
  176. package/src/components/CommentsContainer.tsx +17 -11
  177. package/src/components/{CommentContainer.tsx → CommentsThreadContainer.tsx} +51 -81
  178. package/src/components/Lobby/Lobby.tsx +1 -1
  179. package/src/components/Media/VideoObject.stories.tsx +4 -3
  180. package/src/components/MessageContainer.tsx +31 -46
  181. package/src/components/Participant/ParticipantGrid.tsx +2 -1
  182. package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +5 -4
  183. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +5 -4
  184. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +1 -1
  185. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +4 -4
  186. package/src/components/ThreadComplementary.tsx +3 -3
  187. package/src/components/ThreadSettings.tsx +2 -2
  188. package/src/components/command-extension.ts +1 -1
  189. package/src/components/index.ts +1 -1
  190. package/src/components/testing.ts +2 -2
  191. package/src/extensions/threads.ts +6 -6
  192. package/src/hooks/index.ts +2 -0
  193. package/src/hooks/useDebugMode.ts +1 -1
  194. package/src/hooks/useInaudibleAudioStreamTrack.tsx +27 -0
  195. package/src/hooks/useVideoStreamTrack.tsx +33 -0
  196. package/src/testing/stories.ts +7 -3
  197. package/src/translations.ts +11 -8
  198. package/src/types/types.ts +11 -2
  199. package/src/typings.d.ts +8 -0
  200. package/dist/lib/browser/ChannelContainer-PKFBVENP.mjs +0 -15
  201. package/dist/lib/browser/ChatContainer-RSOKYAMK.mjs +0 -14
  202. package/dist/lib/browser/app-graph-builder-OY7R7EJP.mjs.map +0 -7
  203. package/dist/lib/browser/call-manager-APQAZWHT.mjs.map +0 -7
  204. package/dist/lib/browser/chunk-4H4A264L.mjs.map +0 -7
  205. package/dist/lib/browser/chunk-5P5BH5GE.mjs.map +0 -7
  206. package/dist/lib/browser/chunk-6NBVNXTM.mjs +0 -21
  207. package/dist/lib/browser/chunk-AEXWNS6Z.mjs.map +0 -7
  208. package/dist/lib/browser/chunk-PG5CTFKK.mjs +0 -550
  209. package/dist/lib/browser/chunk-PG5CTFKK.mjs.map +0 -7
  210. package/dist/lib/browser/chunk-TAFSCSUR.mjs +0 -351
  211. package/dist/lib/browser/chunk-TAFSCSUR.mjs.map +0 -7
  212. package/dist/lib/browser/chunk-XZKBN3NS.mjs.map +0 -7
  213. package/dist/lib/browser/intent-resolver-FK2MDVDT.mjs.map +0 -7
  214. package/dist/lib/browser/markdown-TE5SWWNJ.mjs.map +0 -7
  215. package/dist/lib/browser/react-root-NK3A4VG7.mjs +0 -27
  216. package/dist/lib/browser/react-surface-VXUJKSOG.mjs.map +0 -7
  217. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs +0 -36
  218. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs.map +0 -7
  219. package/dist/lib/node/ChatContainer-GCOM3M56.cjs +0 -35
  220. package/dist/lib/node/ChatContainer-GCOM3M56.cjs.map +0 -7
  221. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs +0 -179
  222. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs.map +0 -7
  223. package/dist/lib/node/call-manager-HV2XJW5O.cjs +0 -37
  224. package/dist/lib/node/call-manager-HV2XJW5O.cjs.map +0 -7
  225. package/dist/lib/node/chunk-44I33JDT.cjs +0 -1731
  226. package/dist/lib/node/chunk-44I33JDT.cjs.map +0 -7
  227. package/dist/lib/node/chunk-4YSNVPWU.cjs +0 -37
  228. package/dist/lib/node/chunk-4YSNVPWU.cjs.map +0 -7
  229. package/dist/lib/node/chunk-E3WBZTTI.cjs +0 -371
  230. package/dist/lib/node/chunk-E3WBZTTI.cjs.map +0 -7
  231. package/dist/lib/node/chunk-ERG7G6FF.cjs +0 -59
  232. package/dist/lib/node/chunk-ERG7G6FF.cjs.map +0 -7
  233. package/dist/lib/node/chunk-FUXJAVFZ.cjs +0 -108
  234. package/dist/lib/node/chunk-FUXJAVFZ.cjs.map +0 -7
  235. package/dist/lib/node/chunk-HLMCEE5K.cjs +0 -41
  236. package/dist/lib/node/chunk-HLMCEE5K.cjs.map +0 -7
  237. package/dist/lib/node/chunk-IP533AMV.cjs +0 -554
  238. package/dist/lib/node/chunk-IP533AMV.cjs.map +0 -7
  239. package/dist/lib/node/chunk-LR5NENBE.cjs +0 -54
  240. package/dist/lib/node/chunk-LR5NENBE.cjs.map +0 -7
  241. package/dist/lib/node/chunk-UM36TPCT.cjs +0 -984
  242. package/dist/lib/node/chunk-UM36TPCT.cjs.map +0 -7
  243. package/dist/lib/node/chunk-ZGDN3XBR.cjs +0 -149
  244. package/dist/lib/node/chunk-ZGDN3XBR.cjs.map +0 -7
  245. package/dist/lib/node/index.cjs +0 -310
  246. package/dist/lib/node/index.cjs.map +0 -7
  247. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs +0 -363
  248. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs.map +0 -7
  249. package/dist/lib/node/markdown-GQIPJS2F.cjs +0 -178
  250. package/dist/lib/node/markdown-GQIPJS2F.cjs.map +0 -7
  251. package/dist/lib/node/meta.json +0 -1
  252. package/dist/lib/node/react-root-6HHDMULJ.cjs +0 -51
  253. package/dist/lib/node/react-root-6HHDMULJ.cjs.map +0 -7
  254. package/dist/lib/node/react-surface-NBH42NN2.cjs +0 -122
  255. package/dist/lib/node/react-surface-NBH42NN2.cjs.map +0 -7
  256. package/dist/lib/node/settings-4LQSFEDK.cjs +0 -36
  257. package/dist/lib/node/settings-4LQSFEDK.cjs.map +0 -7
  258. package/dist/lib/node/state-IY5XX3H2.cjs +0 -50
  259. package/dist/lib/node/state-IY5XX3H2.cjs.map +0 -7
  260. package/dist/lib/node/types/index.cjs +0 -38
  261. package/dist/lib/node/types/index.cjs.map +0 -7
  262. package/dist/lib/node-esm/ChannelContainer-O4QJII2P.mjs +0 -16
  263. package/dist/lib/node-esm/app-graph-builder-BAHBHYWI.mjs.map +0 -7
  264. package/dist/lib/node-esm/call-manager-UUYXLF4T.mjs.map +0 -7
  265. package/dist/lib/node-esm/chunk-2RNIPFDA.mjs.map +0 -7
  266. package/dist/lib/node-esm/chunk-O3V45YJP.mjs.map +0 -7
  267. package/dist/lib/node-esm/chunk-O63QJPQX.mjs +0 -23
  268. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs +0 -352
  269. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs.map +0 -7
  270. package/dist/lib/node-esm/chunk-UJMPYKT3.mjs.map +0 -7
  271. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs +0 -551
  272. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs.map +0 -7
  273. package/dist/lib/node-esm/chunk-WXNPD542.mjs.map +0 -7
  274. package/dist/lib/node-esm/intent-resolver-BU73VYW3.mjs.map +0 -7
  275. package/dist/lib/node-esm/markdown-HJUWNBLS.mjs.map +0 -7
  276. package/dist/lib/node-esm/react-surface-ELXFYKP6.mjs.map +0 -7
  277. package/dist/types/src/components/CommentContainer.d.ts +0 -13
  278. package/dist/types/src/components/CommentContainer.d.ts.map +0 -1
  279. package/dist/types/src/peers.stories.d.ts +0 -11
  280. package/dist/types/src/peers.stories.d.ts.map +0 -1
  281. package/src/peers.stories.tsx +0 -189
  282. /package/dist/lib/browser/{ChannelContainer-PKFBVENP.mjs.map → ChannelContainer-O2SFQJU7.mjs.map} +0 -0
  283. /package/dist/lib/browser/{ChatContainer-RSOKYAMK.mjs.map → ChatContainer-PVT3DUZJ.mjs.map} +0 -0
  284. /package/dist/lib/browser/{chunk-6NBVNXTM.mjs.map → chunk-2CWJBXBH.mjs.map} +0 -0
  285. /package/dist/lib/browser/{chunk-IIUTBDVB.mjs.map → chunk-EV4JWI7L.mjs.map} +0 -0
  286. /package/dist/lib/browser/{chunk-JKQUJOTX.mjs.map → chunk-GERVMFQW.mjs.map} +0 -0
  287. /package/dist/lib/{node-esm/react-root-RUXOAQNW.mjs.map → browser/react-root-QXPALOUQ.mjs.map} +0 -0
  288. /package/dist/lib/browser/{settings-RB2RSLXV.mjs.map → settings-AC6YSASL.mjs.map} +0 -0
  289. /package/dist/lib/node-esm/{ChannelContainer-O4QJII2P.mjs.map → ChannelContainer-B2ZGAE4P.mjs.map} +0 -0
  290. /package/dist/lib/node-esm/{ChatContainer-F6CSADV7.mjs.map → ChatContainer-2CT4PJ7I.mjs.map} +0 -0
  291. /package/dist/lib/node-esm/{chunk-PGRP3O4O.mjs.map → chunk-57XR3LEF.mjs.map} +0 -0
  292. /package/dist/lib/node-esm/{chunk-O63QJPQX.mjs.map → chunk-6CRHHOST.mjs.map} +0 -0
  293. /package/dist/lib/node-esm/{chunk-ESQC6SYE.mjs.map → chunk-GRLRWTRU.mjs.map} +0 -0
  294. /package/dist/lib/node-esm/{settings-EA7DFSM6.mjs.map → settings-N52O7MLS.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-thread",
3
- "version": "0.8.3",
3
+ "version": "0.8.4-main.28f8d3d",
4
4
  "description": "DXOS Threads Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,11 +10,13 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs",
15
16
  "node": "./dist/lib/node-esm/index.mjs"
16
17
  },
17
18
  "./types": {
19
+ "source": "./src/types/index.ts",
18
20
  "types": "./dist/types/src/types/index.d.ts",
19
21
  "browser": "./dist/lib/browser/types/index.mjs",
20
22
  "node": "./dist/lib/node-esm/types/index.mjs"
@@ -45,66 +47,65 @@
45
47
  "md5-hex": "5.0.0",
46
48
  "react-resize-detector": "^12.0.2",
47
49
  "wavefile": "^11.0.0",
48
- "@dxos/app-framework": "0.8.3",
49
- "@dxos/codec-protobuf": "0.8.3",
50
- "@dxos/async": "0.8.3",
51
- "@dxos/context": "0.8.3",
52
- "@dxos/devtools": "0.8.3",
53
- "@dxos/echo": "0.8.3",
54
- "@dxos/echo-schema": "0.8.3",
55
- "@dxos/keys": "0.8.3",
56
- "@dxos/display-name": "0.8.3",
57
- "@dxos/invariant": "0.8.3",
58
- "@dxos/local-storage": "0.8.3",
59
- "@dxos/live-object": "0.8.3",
60
- "@dxos/log": "0.8.3",
61
- "@dxos/plugin-attention": "0.8.3",
62
- "@dxos/plugin-client": "0.8.3",
63
- "@dxos/plugin-deck": "0.8.3",
64
- "@dxos/plugin-graph": "0.8.3",
65
- "@dxos/plugin-observability": "0.8.3",
66
- "@dxos/plugin-space": "0.8.3",
67
- "@dxos/plugin-markdown": "0.8.3",
68
- "@dxos/protocols": "0.8.3",
69
- "@dxos/react-client": "0.8.3",
70
- "@dxos/react-ui-attention": "0.8.3",
71
- "@dxos/react-ui-editor": "0.8.3",
72
- "@dxos/react-ui-form": "0.8.3",
73
- "@dxos/react-ui-dnd": "0.8.3",
74
- "@dxos/react-ui-menu": "0.8.3",
75
- "@dxos/react-ui-syntax-highlighter": "0.8.3",
76
- "@dxos/react-ui-sfx": "0.8.3",
77
- "@dxos/react-ui-stack": "0.8.3",
78
- "@dxos/react-ui-tabs": "0.8.3",
79
- "@dxos/schema": "0.8.3",
80
- "@dxos/util": "0.8.3",
81
- "@dxos/react-ui-thread": "0.8.3"
50
+ "@dxos/app-framework": "0.8.4-main.28f8d3d",
51
+ "@dxos/async": "0.8.4-main.28f8d3d",
52
+ "@dxos/codec-protobuf": "0.8.4-main.28f8d3d",
53
+ "@dxos/debug": "0.8.4-main.28f8d3d",
54
+ "@dxos/context": "0.8.4-main.28f8d3d",
55
+ "@dxos/devtools": "0.8.4-main.28f8d3d",
56
+ "@dxos/display-name": "0.8.4-main.28f8d3d",
57
+ "@dxos/echo": "0.8.4-main.28f8d3d",
58
+ "@dxos/echo-schema": "0.8.4-main.28f8d3d",
59
+ "@dxos/invariant": "0.8.4-main.28f8d3d",
60
+ "@dxos/keys": "0.8.4-main.28f8d3d",
61
+ "@dxos/live-object": "0.8.4-main.28f8d3d",
62
+ "@dxos/local-storage": "0.8.4-main.28f8d3d",
63
+ "@dxos/log": "0.8.4-main.28f8d3d",
64
+ "@dxos/plugin-deck": "0.8.4-main.28f8d3d",
65
+ "@dxos/plugin-attention": "0.8.4-main.28f8d3d",
66
+ "@dxos/plugin-graph": "0.8.4-main.28f8d3d",
67
+ "@dxos/plugin-client": "0.8.4-main.28f8d3d",
68
+ "@dxos/plugin-markdown": "0.8.4-main.28f8d3d",
69
+ "@dxos/plugin-observability": "0.8.4-main.28f8d3d",
70
+ "@dxos/plugin-space": "0.8.4-main.28f8d3d",
71
+ "@dxos/protocols": "0.8.4-main.28f8d3d",
72
+ "@dxos/react-client": "0.8.4-main.28f8d3d",
73
+ "@dxos/react-ui-dnd": "0.8.4-main.28f8d3d",
74
+ "@dxos/react-ui-attention": "0.8.4-main.28f8d3d",
75
+ "@dxos/react-ui-editor": "0.8.4-main.28f8d3d",
76
+ "@dxos/react-ui-form": "0.8.4-main.28f8d3d",
77
+ "@dxos/react-ui-stack": "0.8.4-main.28f8d3d",
78
+ "@dxos/react-ui-sfx": "0.8.4-main.28f8d3d",
79
+ "@dxos/react-ui-menu": "0.8.4-main.28f8d3d",
80
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.28f8d3d",
81
+ "@dxos/react-ui-tabs": "0.8.4-main.28f8d3d",
82
+ "@dxos/react-ui-thread": "0.8.4-main.28f8d3d",
83
+ "@dxos/schema": "0.8.4-main.28f8d3d",
84
+ "@dxos/util": "0.8.4-main.28f8d3d"
82
85
  },
83
86
  "devDependencies": {
84
- "@effect-rx/rx-react": "^0.34.1",
85
- "@effect/platform": "0.80.12",
86
- "@phosphor-icons/react": "^2.1.5",
87
+ "@effect-rx/rx-react": "0.38.0",
88
+ "@effect/platform": "0.90.2",
87
89
  "@types/react": "~18.2.0",
88
90
  "@types/react-dom": "~18.2.0",
89
- "effect": "3.14.21",
91
+ "effect": "3.17.7",
90
92
  "react": "~18.2.0",
91
93
  "react-dom": "~18.2.0",
92
94
  "vite": "5.4.7",
93
- "@dxos/random": "0.8.3",
94
- "@dxos/plugin-theme": "0.8.3",
95
- "@dxos/react-ui": "0.8.3",
96
- "@dxos/storybook-utils": "0.8.3",
97
- "@dxos/react-ui-theme": "0.8.3"
95
+ "@dxos/random": "0.8.4-main.28f8d3d",
96
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
97
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d",
98
+ "@dxos/storybook-utils": "0.8.4-main.28f8d3d",
99
+ "@dxos/plugin-theme": "0.8.4-main.28f8d3d"
98
100
  },
99
101
  "peerDependencies": {
100
102
  "@effect-rx/rx-react": "^0.34.1",
101
- "@effect/platform": "0.80.12",
102
- "@phosphor-icons/react": "^2.1.5",
103
+ "@effect/platform": "^0.80.12",
103
104
  "effect": "^3.13.3",
104
105
  "react": "~18.2.0",
105
106
  "react-dom": "~18.2.0",
106
- "@dxos/react-ui": "0.8.3",
107
- "@dxos/react-ui-theme": "0.8.3"
107
+ "@dxos/react-ui": "0.8.4-main.28f8d3d",
108
+ "@dxos/react-ui-theme": "0.8.4-main.28f8d3d"
108
109
  },
109
110
  "publishConfig": {
110
111
  "access": "public"
@@ -2,14 +2,12 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Effect } from 'effect';
6
-
7
- import { Capabilities, contributes, createIntent, defineModule, definePlugin, Events } from '@dxos/app-framework';
8
- import { Ref, Type } from '@dxos/echo';
5
+ import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
6
+ import { Ref } from '@dxos/echo';
9
7
  import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
10
8
  import { MarkdownEvents } from '@dxos/plugin-markdown';
11
9
  import { SpaceCapabilities, SpaceEvents } from '@dxos/plugin-space';
12
- import { CollectionAction, defineObjectForm } from '@dxos/plugin-space/types';
10
+ import { defineObjectForm } from '@dxos/plugin-space/types';
13
11
  import { translations as threadTranslations } from '@dxos/react-ui-thread';
14
12
  import { AnchoredTo, DataType } from '@dxos/schema';
15
13
 
@@ -22,8 +20,8 @@ import {
22
20
  ReactSurface,
23
21
  ThreadState,
24
22
  } from './capabilities';
25
- import { meta, THREAD_ITEM } from './meta';
26
- import translations from './translations';
23
+ import { THREAD_ITEM, meta } from './meta';
24
+ import { translations } from './translations';
27
25
  import { ChannelType, ThreadAction, ThreadType } from './types';
28
26
 
29
27
  // TODO(Zan): Every instance of `cursor` should be replaced with `anchor`.
@@ -124,23 +122,10 @@ export const ThreadPlugin = () =>
124
122
  defineModule({
125
123
  id: `${meta.id}/module/on-space-created`,
126
124
  activatesOn: SpaceEvents.SpaceCreated,
127
- activate: (context) => {
128
- const { dispatch } = context.getCapability(Capabilities.IntentDispatcher);
129
- return contributes(SpaceCapabilities.OnSpaceCreated, async ({ space, rootCollection }) => {
130
- const program = Effect.gen(function* () {
131
- const { object: collection } = yield* dispatch(
132
- createIntent(CollectionAction.CreateQueryCollection, { typename: Type.getTypename(ChannelType) }),
133
- );
134
- rootCollection.objects.push(Ref.make(collection));
135
-
136
- const { object: channel } = yield* dispatch(
137
- createIntent(ThreadAction.CreateChannel, { name: 'General', spaceId: space.id }),
138
- );
139
- space.db.add(channel);
140
- });
141
- await Effect.runPromise(program);
142
- });
143
- },
125
+ activate: () =>
126
+ contributes(SpaceCapabilities.OnSpaceCreated, ({ space, rootCollection }) =>
127
+ createIntent(ThreadAction.OnSpaceCreated, { space, rootCollection }),
128
+ ),
144
129
  }),
145
130
  defineModule({
146
131
  id: `${meta.id}/module/markdown`,
@@ -12,7 +12,7 @@ import { live } from '@dxos/live-object';
12
12
  import { type Tracks } from '@dxos/protocols/proto/dxos/edge/calls';
13
13
  import { isNonNullable } from '@dxos/util';
14
14
 
15
- import { CallSwarmSynchronizer, type CallState } from './call-swarm-synchronizer';
15
+ import { type CallState, CallSwarmSynchronizer } from './call-swarm-synchronizer';
16
16
  import { MediaManager, type MediaState } from './media-manager';
17
17
  import { type ActivityState, CALLS_URL, type EncodedTrackName, TrackNameCodec, type UserState } from './types';
18
18
 
@@ -88,8 +88,12 @@ export class CallManager extends Resource {
88
88
  }
89
89
 
90
90
  /** @reactive */
91
- get pulledAudioTracks() {
92
- return Object.values(this._state.media.pulledAudioTracks).map((track) => track.track);
91
+ get audioTracksToPlay(): MediaStreamTrack[] {
92
+ return (this._state.call.users ?? [])
93
+ .map((user) => (user.tracks?.audioEnabled ? user.tracks?.audio : undefined))
94
+ .filter(isNonNullable)
95
+ .map((track) => this._state.media.pulledAudioTracks[track as EncodedTrackName]?.track)
96
+ .filter(isNonNullable);
93
97
  }
94
98
 
95
99
  /** @reactive */
@@ -17,7 +17,7 @@ import { type Device, type NetworkService } from '@dxos/protocols/proto/dxos/cli
17
17
  import { ConnectionState, type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
18
18
  import { isNonNullable } from '@dxos/util';
19
19
 
20
- import { codec, type ActivityState, type UserState } from './types';
20
+ import { type ActivityState, type UserState, codec } from './types';
21
21
 
22
22
  export type CallState = {
23
23
  /**
@@ -3,11 +3,11 @@
3
3
  //
4
4
 
5
5
  import { DeferredTask, Event, sleep, synchronized } from '@dxos/async';
6
- import { cancelWithContext, type Context, Resource } from '@dxos/context';
6
+ import { type Context, Resource, cancelWithContext } from '@dxos/context';
7
7
  import { log } from '@dxos/log';
8
8
 
9
9
  import { SpeakingMonitor } from './speaking-monitor';
10
- import { TrackNameCodec, type EncodedTrackName, type TrackObject } from './types';
10
+ import { type EncodedTrackName, TrackNameCodec, type TrackObject } from './types';
11
11
  import {
12
12
  type CallsServiceConfig,
13
13
  CallsServicePeer,
@@ -54,6 +54,8 @@ export type MediaManagerParams = {
54
54
  serviceConfig: CallsServiceConfig;
55
55
  };
56
56
 
57
+ const USE_INAUDIBLE_AUDIO = false;
58
+
57
59
  export class MediaManager extends Resource {
58
60
  public readonly stateUpdated = new Event<MediaState>();
59
61
  private readonly _state: MediaState = { pulledVideoStreams: {}, pulledAudioTracks: {} };
@@ -86,8 +88,10 @@ export class MediaManager extends Resource {
86
88
  this._state.videoStream = new MediaStream();
87
89
  this._state.videoStream.addTrack(this._state.videoTrack);
88
90
 
89
- this._inaudibleAudioStreamTrack = await createInaudibleAudioStreamTrack({ ctx: this._ctx });
90
- this._state.audioTrack = this._inaudibleAudioStreamTrack;
91
+ if (USE_INAUDIBLE_AUDIO) {
92
+ this._inaudibleAudioStreamTrack = await createInaudibleAudioStreamTrack({ ctx: this._ctx });
93
+ this._state.audioTrack = this._inaudibleAudioStreamTrack;
94
+ }
91
95
 
92
96
  this._pushTracksTask = new DeferredTask(this._ctx, async () => {
93
97
  await this._pushTracks();
@@ -170,11 +174,14 @@ export class MediaManager extends Resource {
170
174
  async turnAudioOff(): Promise<void> {
171
175
  void this._speakingMonitor?.close();
172
176
  this._speakingMonitor = undefined;
173
- if (this._state.audioTrack !== this._inaudibleAudioStreamTrack) {
177
+ this._state.audioEnabled = false;
178
+ if (USE_INAUDIBLE_AUDIO && this._state.audioTrack !== this._inaudibleAudioStreamTrack) {
174
179
  this._state.audioTrack?.stop();
175
180
  this._state.audioTrack = this._inaudibleAudioStreamTrack;
181
+ } else {
182
+ this._state.audioTrack?.stop();
183
+ this._state.audioTrack = undefined;
176
184
  }
177
- this._state.audioEnabled = false;
178
185
  this.stateUpdated.emit(this._state);
179
186
  this._pushTracksTask!.schedule();
180
187
  }
@@ -5,8 +5,8 @@
5
5
  import { buf } from '@dxos/protocols/buf';
6
6
  import {
7
7
  type ActivitySchema,
8
- UserStateSchema,
9
8
  type UserState as UserStateProto,
9
+ UserStateSchema,
10
10
  } from '@dxos/protocols/buf/dxos/edge/calls_pb';
11
11
 
12
12
  /**
@@ -7,16 +7,17 @@ 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 = {
@@ -73,7 +74,10 @@ export class CallsServicePeer extends Resource {
73
74
  pullTrackDispatcher = new BulkRequestDispatcher<
74
75
  TrackObject,
75
76
  {
76
- trackMap: Map<TrackObject, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>;
77
+ /**
78
+ * trackName -> { resolvedTrack, mid }
79
+ */
80
+ trackMap: Map<string, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>;
77
81
  }
78
82
  >(32);
79
83
 
@@ -354,14 +358,14 @@ export class CallsServicePeer extends Resource {
354
358
  );
355
359
 
356
360
  if (pulledTrackData && pulledTrackData.mid) {
357
- acc.set(track, {
361
+ acc.set(track.trackName!, {
358
362
  mid: pulledTrackData.mid,
359
363
  resolvedTrack: resolveTrack(peerConnection, (t) => t.mid === pulledTrackData.mid),
360
364
  });
361
365
  }
362
366
 
363
367
  return acc;
364
- }, new Map<TrackObject, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>());
368
+ }, new Map<string, { resolvedTrack: Promise<MediaStreamTrack>; mid: string }>());
365
369
 
366
370
  if (newTrackResponse.requiresImmediateRenegotiation) {
367
371
  await peerConnection.setRemoteDescription(new RTCSessionDescription(newTrackResponse.sessionDescription));
@@ -392,7 +396,7 @@ export class CallsServicePeer extends Resource {
392
396
  }),
393
397
  )
394
398
  .then(({ trackMap }) => {
395
- const trackInfo = trackMap.get(trackData);
399
+ const trackInfo = trackMap.get(trackData.trackName!);
396
400
  if (trackInfo) {
397
401
  return trackInfo.resolvedTrack
398
402
  .then((track) => {
@@ -401,7 +405,7 @@ export class CallsServicePeer extends Resource {
401
405
  })
402
406
  .catch((err) => log.catch(err));
403
407
  } else {
404
- log.error('missing track info');
408
+ log.warn('missing track info', { trackData, availableTracks: Array.from(trackMap.keys()) });
405
409
  }
406
410
  });
407
411
 
@@ -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
  /**
@@ -48,19 +48,16 @@ export const createInaudibleAudioStreamTrack = async ({ ctx }: { ctx: Context })
48
48
  const audioContext = new window.AudioContext();
49
49
  const oscillator = audioContext.createOscillator();
50
50
  oscillator.type = 'triangle';
51
-
52
- // set to 0.1 to make inaudible
53
- oscillator.frequency.setValueAtTime(0.1, audioContext.currentTime);
51
+ // roughly sounds like a box fan
52
+ oscillator.frequency.setValueAtTime(20, audioContext.currentTime);
54
53
 
55
54
  const gainNode = audioContext.createGain();
56
55
  // even w/ gain at 0 some packets are sent
57
- gainNode.gain.setValueAtTime(0, audioContext.currentTime);
58
-
56
+ gainNode.gain.setValueAtTime(0.02, audioContext.currentTime);
59
57
  oscillator.connect(gainNode);
60
58
 
61
59
  const destination = audioContext.createMediaStreamDestination();
62
60
  gainNode.connect(destination);
63
-
64
61
  oscillator.start();
65
62
 
66
63
  ctx.onDispose(async () => {
@@ -0,0 +1,216 @@
1
+ //
2
+ // Copyright 2025 DXOS.org
3
+ //
4
+
5
+ import '@dxos-theme';
6
+
7
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
8
+
9
+ import { scheduleTask, sleep } from '@dxos/async';
10
+ import { Context } from '@dxos/context';
11
+ import { invariant } from '@dxos/invariant';
12
+ import { log } from '@dxos/log';
13
+ import { Config, useConfig } from '@dxos/react-client';
14
+ import { withClientProvider } from '@dxos/react-client/testing';
15
+ import { Button } from '@dxos/react-ui';
16
+ import { Json } from '@dxos/react-ui-syntax-highlighter';
17
+ import { withLayout, withTheme } from '@dxos/storybook-utils';
18
+
19
+ import video from '../testing/video.mp4?raw';
20
+
21
+ import { CALLS_URL, CallsServicePeer, type TrackObject } from './calls';
22
+ import { useInaudibleAudioStreamTrack, useVideoStreamTrack } from './hooks';
23
+
24
+ const pushAndPullTrack = (mediaStreamTrack?: MediaStreamTrack) => {
25
+ const config = useConfig();
26
+ const callsConfig = {
27
+ iceServers: config.get('runtime.services.ice'),
28
+ apiBase: `${CALLS_URL}/api/calls`,
29
+ };
30
+ const peerPush = useMemo(() => new CallsServicePeer(callsConfig), []);
31
+ const peerPull = useMemo(() => new CallsServicePeer(callsConfig), []);
32
+ const [metrics, setMetrics] = useState<Record<string, any>>({});
33
+ const trackInfo = useRef<TrackObject | undefined>(undefined);
34
+ const pullCtx = useRef<Context | undefined>(undefined);
35
+ const [pulledTrack, setPulledTrack] = useState<MediaStreamTrack | undefined>(undefined);
36
+ const hadRun = useRef(false);
37
+
38
+ // Push/pull video stream track to cloudflare.
39
+ useEffect(() => {
40
+ if (hadRun.current || !mediaStreamTrack || !peerPush || !peerPull) {
41
+ log.info('not running', { hadRun: hadRun.current, mediaStreamTrack, peerPush, peerPull });
42
+ return;
43
+ }
44
+ hadRun.current = true;
45
+ const ctx = Context.default();
46
+ ctx.onDispose(() => {
47
+ log.info('disposing ctx', { ctx });
48
+ });
49
+ scheduleTask(
50
+ ctx,
51
+ async () => {
52
+ log.info('starting push/pull', { mediaStreamTrack });
53
+ await peerPush.open();
54
+ await peerPull.open();
55
+ ctx.onDispose(() => {
56
+ void peerPush.close();
57
+ void peerPull.close();
58
+ });
59
+
60
+ // Push track to cloudflare.
61
+ performance.mark('push:begin');
62
+ log.info('pushing track', { track: mediaStreamTrack });
63
+ trackInfo.current = await peerPush.pushTrack({ track: mediaStreamTrack });
64
+ performance.mark('push:end');
65
+ const pushTime = performance.measure('push', 'push:begin', 'push:end').duration;
66
+ log.info('successfully pushed track', { pushTime, trackInfo: trackInfo.current });
67
+ setMetrics((prev) => ({ ...prev, 'time to push track [ms]': Math.round(pushTime) }));
68
+
69
+ // Wait for cloudflare to process the track.
70
+ await sleep(1000);
71
+
72
+ // Pull track from cloudflare.
73
+ performance.mark('pullTrack:begin');
74
+ pullCtx.current = Context.default();
75
+ let retries = 0;
76
+ let pulledTrack: MediaStreamTrack | undefined;
77
+ while (!pulledTrack && retries < 3) {
78
+ retries++;
79
+ log.info('pulling track', {
80
+ trackData: { ...trackInfo.current!, mid: undefined },
81
+ retries,
82
+ pulledTrack,
83
+ });
84
+ pulledTrack = await peerPull.pullTrack({
85
+ trackData: { ...trackInfo.current!, mid: undefined },
86
+ ctx: pullCtx.current,
87
+ });
88
+ await sleep(200);
89
+ }
90
+ invariant(pulledTrack);
91
+ setPulledTrack(pulledTrack);
92
+ performance.mark('pullTrack:end');
93
+ const pullTime = performance.measure('pullTrack', 'pullTrack:begin', 'pullTrack:end').duration;
94
+ setMetrics((prev) => ({ ...prev, 'time to pull track [ms]': Math.round(pullTime) }));
95
+ log.info('successfully pulled track', { pullTime, pulledTrack });
96
+ },
97
+ 1000,
98
+ );
99
+
100
+ return () => {
101
+ void ctx.dispose();
102
+ };
103
+ }, [mediaStreamTrack, peerPush, peerPull]);
104
+
105
+ const rePullTrack = useCallback(async () => {
106
+ performance.mark('rePullVideo:begin');
107
+ invariant(pulledTrack);
108
+ pulledTrack.stop();
109
+ await pullCtx.current!.dispose();
110
+ pullCtx.current = Context.default();
111
+ const newPulledTrack = await peerPull.pullTrack({
112
+ trackData: { ...trackInfo.current!, mid: undefined },
113
+ ctx: pullCtx.current,
114
+ });
115
+ invariant(newPulledTrack);
116
+ setPulledTrack(newPulledTrack);
117
+ performance.mark('rePullVideo:end');
118
+ const rePullTime = performance.measure('rePullVideo', 'rePullVideo:begin', 'rePullVideo:end').duration;
119
+ setMetrics((prev) => ({ ...prev, 'time to re-pull video [ms]': Math.round(rePullTime) }));
120
+ }, [peerPull, trackInfo.current, pullCtx.current, pulledTrack]);
121
+
122
+ return {
123
+ pulledTrack,
124
+ rePullTrack,
125
+ metrics,
126
+ };
127
+ };
128
+
129
+ const meta = {
130
+ title: 'plugins/plugin-thread/calls-service',
131
+ decorators: [
132
+ withClientProvider({
133
+ config: new Config({
134
+ runtime: {
135
+ services: {
136
+ iceProviders: [{ urls: 'https://edge.dxos.workers.dev/ice' }],
137
+ },
138
+ },
139
+ }),
140
+ }),
141
+ withTheme,
142
+ withLayout(),
143
+ ],
144
+ parameters: {
145
+ layout: 'centered',
146
+ },
147
+ };
148
+
149
+ export default meta;
150
+
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]);
176
+
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
+ args: {
199
+ videoSrc: video,
200
+ },
201
+ };
202
+
203
+ export const InaudibleAudioStreamTrack = {
204
+ render: () => {
205
+ const audioStreamTrack = useInaudibleAudioStreamTrack();
206
+
207
+ const { rePullTrack, metrics } = pushAndPullTrack(audioStreamTrack);
208
+
209
+ return (
210
+ <div className='flex flex-col gap-4 items-center'>
211
+ <Json data={metrics} />
212
+ <Button onClick={rePullTrack}>Re-pull audio</Button>
213
+ </div>
214
+ );
215
+ },
216
+ };
@@ -5,18 +5,19 @@
5
5
  import { Rx } from '@effect-rx/rx-react';
6
6
  import { Option, pipe } from 'effect';
7
7
 
8
- import { Capabilities, contributes, createIntent, type PluginContext } from '@dxos/app-framework';
8
+ import { Capabilities, type PluginContext, contributes, createIntent } from '@dxos/app-framework';
9
9
  import { Obj } from '@dxos/echo';
10
10
  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';
11
+ import { ATTENDABLE_PATH_SEPARATOR, DECK_COMPANION_TYPE, PLANK_COMPANION_TYPE } from '@dxos/plugin-deck/types';
12
+ import { ROOT_ID, createExtension, rxFromSignal } from '@dxos/plugin-graph';
13
13
  import { fullyQualifiedId } from '@dxos/react-client/echo';
14
14
 
15
- import { ThreadCapabilities } from './capabilities';
16
- import { meta, THREAD_PLUGIN } from '../meta';
15
+ import { THREAD_PLUGIN, meta } from '../meta';
17
16
  import { ChannelType, ThreadAction } from '../types';
18
17
  import { getAnchor } from '../util';
19
18
 
19
+ import { ThreadCapabilities } from './capabilities';
20
+
20
21
  export default (context: PluginContext) => {
21
22
  const resolve = (typename: string) =>
22
23
  context.getCapabilities(Capabilities.Metadata).find(({ id }) => id === typename)?.metadata ?? {};
@@ -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);
@@ -5,9 +5,9 @@
5
5
  import { defineCapability } from '@dxos/app-framework';
6
6
  import { type DeepReadonly } from '@dxos/util';
7
7
 
8
- import { type CallState, type MediaState, type CallManager } from '../calls';
8
+ import { type CallManager, type CallState, type MediaState } from '../calls';
9
9
  import { THREAD_PLUGIN } from '../meta';
10
- import { type ViewState, type ThreadState, type ChannelType } from '../types';
10
+ import { type ChannelType, type ThreadState, type ViewState } from '../types';
11
11
 
12
12
  export namespace ThreadCapabilities {
13
13
  export const CallManager = defineCapability<CallManager>(`${THREAD_PLUGIN}/capability/call-manager`);