@dxos/plugin-thread 0.8.3 → 0.8.4-main.1c7ec43d41

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 (558) hide show
  1. package/dist/lib/browser/add-message-3FTZANTW.mjs +89 -0
  2. package/dist/lib/browser/add-message-3FTZANTW.mjs.map +7 -0
  3. package/dist/lib/browser/append-channel-message-CO3M6FSA.mjs +40 -0
  4. package/dist/lib/browser/append-channel-message-CO3M6FSA.mjs.map +7 -0
  5. package/dist/lib/browser/blueprints/index.mjs +37 -0
  6. package/dist/lib/browser/blueprints/index.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  8. package/dist/lib/browser/chunk-MR4CWITF.mjs +31 -0
  9. package/dist/lib/browser/chunk-MR4CWITF.mjs.map +7 -0
  10. package/dist/lib/browser/chunk-TPNZ43NB.mjs +258 -0
  11. package/dist/lib/browser/chunk-TPNZ43NB.mjs.map +7 -0
  12. package/dist/lib/browser/create-GMUAPFZM.mjs +55 -0
  13. package/dist/lib/browser/create-GMUAPFZM.mjs.map +7 -0
  14. package/dist/lib/browser/create-channel-ZXKSLHGN.mjs +19 -0
  15. package/dist/lib/browser/create-channel-ZXKSLHGN.mjs.map +7 -0
  16. package/dist/lib/browser/create-proposals-AV5CREPV.mjs +56 -0
  17. package/dist/lib/browser/create-proposals-AV5CREPV.mjs.map +7 -0
  18. package/dist/lib/browser/delete-673YOWCG.mjs +59 -0
  19. package/dist/lib/browser/delete-673YOWCG.mjs.map +7 -0
  20. package/dist/lib/browser/delete-message-RQ72ZY5D.mjs +55 -0
  21. package/dist/lib/browser/delete-message-RQ72ZY5D.mjs.map +7 -0
  22. package/dist/lib/browser/index.mjs +1783 -270
  23. package/dist/lib/browser/index.mjs.map +4 -4
  24. package/dist/lib/browser/meta.json +1 -1
  25. package/dist/lib/browser/on-create-space-SPE3QVFZ.mjs +24 -0
  26. package/dist/lib/browser/on-create-space-SPE3QVFZ.mjs.map +7 -0
  27. package/dist/lib/browser/operations/index.mjs +13 -0
  28. package/dist/lib/browser/operations/index.mjs.map +7 -0
  29. package/dist/lib/browser/restore-VX7FLZOZ.mjs +32 -0
  30. package/dist/lib/browser/restore-VX7FLZOZ.mjs.map +7 -0
  31. package/dist/lib/browser/restore-message-D65NSWUA.mjs +33 -0
  32. package/dist/lib/browser/restore-message-D65NSWUA.mjs.map +7 -0
  33. package/dist/lib/browser/select-DO4AYSCB.mjs +26 -0
  34. package/dist/lib/browser/select-DO4AYSCB.mjs.map +7 -0
  35. package/dist/lib/browser/toggle-resolved-JD3D4WBZ.mjs +36 -0
  36. package/dist/lib/browser/toggle-resolved-JD3D4WBZ.mjs.map +7 -0
  37. package/dist/lib/browser/translations.mjs +90 -0
  38. package/dist/lib/browser/translations.mjs.map +7 -0
  39. package/dist/lib/browser/types/index.mjs +6 -12
  40. package/dist/lib/node-esm/add-message-56J2HLJB.mjs +90 -0
  41. package/dist/lib/node-esm/add-message-56J2HLJB.mjs.map +7 -0
  42. package/dist/lib/node-esm/append-channel-message-F7KGBSWP.mjs +41 -0
  43. package/dist/lib/node-esm/append-channel-message-F7KGBSWP.mjs.map +7 -0
  44. package/dist/lib/node-esm/blueprints/index.mjs +38 -0
  45. package/dist/lib/node-esm/blueprints/index.mjs.map +7 -0
  46. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  47. package/dist/lib/node-esm/chunk-L6UL3NVS.mjs +32 -0
  48. package/dist/lib/node-esm/chunk-L6UL3NVS.mjs.map +7 -0
  49. package/dist/lib/node-esm/chunk-XKUMDYGR.mjs +259 -0
  50. package/dist/lib/node-esm/chunk-XKUMDYGR.mjs.map +7 -0
  51. package/dist/lib/node-esm/create-LEXHIPUT.mjs +56 -0
  52. package/dist/lib/node-esm/create-LEXHIPUT.mjs.map +7 -0
  53. package/dist/lib/node-esm/create-channel-6VHTC2OR.mjs +20 -0
  54. package/dist/lib/node-esm/create-channel-6VHTC2OR.mjs.map +7 -0
  55. package/dist/lib/node-esm/create-proposals-P5O2ICOL.mjs +57 -0
  56. package/dist/lib/node-esm/create-proposals-P5O2ICOL.mjs.map +7 -0
  57. package/dist/lib/node-esm/delete-4KSU4UEJ.mjs +60 -0
  58. package/dist/lib/node-esm/delete-4KSU4UEJ.mjs.map +7 -0
  59. package/dist/lib/node-esm/delete-message-PGNLB6TL.mjs +56 -0
  60. package/dist/lib/node-esm/delete-message-PGNLB6TL.mjs.map +7 -0
  61. package/dist/lib/node-esm/index.mjs +1783 -270
  62. package/dist/lib/node-esm/index.mjs.map +4 -4
  63. package/dist/lib/node-esm/meta.json +1 -1
  64. package/dist/lib/node-esm/on-create-space-TFBSHWQ4.mjs +25 -0
  65. package/dist/lib/node-esm/on-create-space-TFBSHWQ4.mjs.map +7 -0
  66. package/dist/lib/node-esm/operations/index.mjs +14 -0
  67. package/dist/lib/node-esm/operations/index.mjs.map +7 -0
  68. package/dist/lib/node-esm/restore-E27OAIFJ.mjs +33 -0
  69. package/dist/lib/node-esm/restore-E27OAIFJ.mjs.map +7 -0
  70. package/dist/lib/node-esm/restore-message-J3CH6NGI.mjs +34 -0
  71. package/dist/lib/node-esm/restore-message-J3CH6NGI.mjs.map +7 -0
  72. package/dist/lib/node-esm/select-NDHRM75K.mjs +27 -0
  73. package/dist/lib/node-esm/select-NDHRM75K.mjs.map +7 -0
  74. package/dist/lib/node-esm/toggle-resolved-VS6NKXL3.mjs +37 -0
  75. package/dist/lib/node-esm/toggle-resolved-VS6NKXL3.mjs.map +7 -0
  76. package/dist/lib/node-esm/translations.mjs +91 -0
  77. package/dist/lib/node-esm/translations.mjs.map +7 -0
  78. package/dist/lib/node-esm/types/index.mjs +6 -12
  79. package/dist/types/src/ThreadPlugin.d.ts +3 -1
  80. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  81. package/dist/types/src/ThreadPlugin.node.d.ts +4 -0
  82. package/dist/types/src/ThreadPlugin.node.d.ts.map +1 -0
  83. package/dist/types/src/ThreadPlugin.test.d.ts +2 -0
  84. package/dist/types/src/ThreadPlugin.test.d.ts.map +1 -0
  85. package/dist/types/src/blueprints/index.d.ts +2 -0
  86. package/dist/types/src/blueprints/index.d.ts.map +1 -0
  87. package/dist/types/src/blueprints/thread-blueprint.d.ts +4 -0
  88. package/dist/types/src/blueprints/thread-blueprint.d.ts.map +1 -0
  89. package/dist/types/src/calls/call-manager.d.ts +40 -30
  90. package/dist/types/src/calls/call-manager.d.ts.map +1 -1
  91. package/dist/types/src/calls/call-swarm-synchronizer.d.ts +2 -2
  92. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +1 -1
  93. package/dist/types/src/calls/media-manager.d.ts +2 -2
  94. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  95. package/dist/types/src/calls/speaking-monitor.d.ts +0 -3
  96. package/dist/types/src/calls/speaking-monitor.d.ts.map +1 -1
  97. package/dist/types/src/calls/types.d.ts +1 -1
  98. package/dist/types/src/calls/types.d.ts.map +1 -1
  99. package/dist/types/src/calls/util/audio.d.ts.map +1 -1
  100. package/dist/types/src/calls/util/calls-service.d.ts +11 -6
  101. package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
  102. package/dist/types/src/calls/util/history-cache.d.ts.map +1 -1
  103. package/dist/types/src/calls/util/media.d.ts.map +1 -1
  104. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
  105. package/dist/types/src/calls/util/task-scheduling.d.ts +2 -2
  106. package/dist/types/src/calls/util/task-scheduling.d.ts.map +1 -1
  107. package/dist/types/src/calls-service.stories.d.ts +23 -0
  108. package/dist/types/src/calls-service.stories.d.ts.map +1 -0
  109. package/dist/types/src/capabilities/app-graph-builder.d.ts +4 -2
  110. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  111. package/dist/types/src/capabilities/blueprint-definition.d.ts +6 -0
  112. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  113. package/dist/types/src/capabilities/call-manager.d.ts +3 -2
  114. package/dist/types/src/capabilities/call-manager.d.ts.map +1 -1
  115. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  116. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  117. package/dist/types/src/capabilities/index.d.ts +19 -13
  118. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  119. package/dist/types/src/capabilities/markdown.d.ts +3 -2
  120. package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
  121. package/dist/types/src/capabilities/operation-handler.d.ts +6 -0
  122. package/dist/types/src/capabilities/operation-handler.d.ts.map +1 -0
  123. package/dist/types/src/capabilities/react-root.d.ts +4 -2
  124. package/dist/types/src/capabilities/react-root.d.ts.map +1 -1
  125. package/dist/types/src/capabilities/react-surface.d.ts +3 -2
  126. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  127. package/dist/types/src/capabilities/settings.d.ts +5 -2
  128. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  129. package/dist/types/src/capabilities/state.d.ts +5 -5
  130. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  131. package/dist/types/src/capabilities/undo-mappings.d.ts +5 -0
  132. package/dist/types/src/capabilities/undo-mappings.d.ts.map +1 -0
  133. package/dist/types/src/components/Call/Call.d.ts +32 -4
  134. package/dist/types/src/components/Call/Call.d.ts.map +1 -1
  135. package/dist/types/src/components/Call/Toolbar.d.ts +6 -6
  136. package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
  137. package/dist/types/src/components/Chat/Chat.d.ts +51 -0
  138. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -0
  139. package/dist/types/src/components/Chat/index.d.ts +2 -0
  140. package/dist/types/src/components/Chat/index.d.ts.map +1 -0
  141. package/dist/types/src/components/CommentsPanel/CommentsPanel.d.ts +13 -0
  142. package/dist/types/src/components/CommentsPanel/CommentsPanel.d.ts.map +1 -0
  143. package/dist/types/src/components/CommentsPanel/CommentsPanel.stories.d.ts +160 -0
  144. package/dist/types/src/components/CommentsPanel/CommentsPanel.stories.d.ts.map +1 -0
  145. package/dist/types/src/components/CommentsPanel/CommentsThread.d.ts +14 -0
  146. package/dist/types/src/components/CommentsPanel/CommentsThread.d.ts.map +1 -0
  147. package/dist/types/src/components/CommentsPanel/index.d.ts +3 -0
  148. package/dist/types/src/components/CommentsPanel/index.d.ts.map +1 -0
  149. package/dist/types/src/components/Lobby/Lobby.d.ts +24 -3
  150. package/dist/types/src/components/Lobby/Lobby.d.ts.map +1 -1
  151. package/dist/types/src/components/Media/VideoObject.d.ts +3 -3
  152. package/dist/types/src/components/Media/VideoObject.d.ts.map +1 -1
  153. package/dist/types/src/components/Media/VideoObject.stories.d.ts +18 -4
  154. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  155. package/dist/types/src/components/MessagePanel/MessagePanel.d.ts +15 -0
  156. package/dist/types/src/components/MessagePanel/MessagePanel.d.ts.map +1 -0
  157. package/dist/types/src/components/MessagePanel/index.d.ts +2 -0
  158. package/dist/types/src/components/MessagePanel/index.d.ts.map +1 -0
  159. package/dist/types/src/components/Participant/Participant.d.ts.map +1 -1
  160. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +1 -1
  161. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts.map +1 -1
  162. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +160 -5
  163. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  164. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
  165. package/dist/types/src/components/ResponsiveGrid/{ResponsiveContainer.d.ts → ResponsivePanel.d.ts} +4 -4
  166. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts.map +1 -0
  167. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts +164 -0
  168. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts.map +1 -0
  169. package/dist/types/src/components/ResponsiveGrid/index.d.ts +1 -1
  170. package/dist/types/src/components/ResponsiveGrid/index.d.ts.map +1 -1
  171. package/dist/types/src/components/ThreadSettings/ThreadSettings.d.ts +6 -0
  172. package/dist/types/src/components/ThreadSettings/ThreadSettings.d.ts.map +1 -0
  173. package/dist/types/src/components/ThreadSettings/ThreadSettings.stories.d.ts +161 -0
  174. package/dist/types/src/components/ThreadSettings/ThreadSettings.stories.d.ts.map +1 -0
  175. package/dist/types/src/components/ThreadSettings/index.d.ts +2 -0
  176. package/dist/types/src/components/ThreadSettings/index.d.ts.map +1 -0
  177. package/dist/types/src/components/index.d.ts +5 -9
  178. package/dist/types/src/components/index.d.ts.map +1 -1
  179. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts +15 -0
  180. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts.map +1 -0
  181. package/dist/types/src/containers/CallDebugPanel/index.d.ts +2 -0
  182. package/dist/types/src/containers/CallDebugPanel/index.d.ts.map +1 -0
  183. package/dist/types/src/{components → containers/CallSidebar}/CallSidebar.d.ts +0 -1
  184. package/dist/types/src/containers/CallSidebar/CallSidebar.d.ts.map +1 -0
  185. package/dist/types/src/containers/CallSidebar/index.d.ts +2 -0
  186. package/dist/types/src/containers/CallSidebar/index.d.ts.map +1 -0
  187. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts +20 -0
  188. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts.map +1 -0
  189. package/dist/types/src/containers/ChannelChat/index.d.ts +4 -0
  190. package/dist/types/src/containers/ChannelChat/index.d.ts.map +1 -0
  191. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts +12 -0
  192. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts.map +1 -0
  193. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts +162 -0
  194. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts.map +1 -0
  195. package/dist/types/src/containers/ChannelContainer/index.d.ts +2 -0
  196. package/dist/types/src/containers/ChannelContainer/index.d.ts.map +1 -0
  197. package/dist/types/src/containers/ThreadCompanion/ThreadCompanion.d.ts +8 -0
  198. package/dist/types/src/containers/ThreadCompanion/ThreadCompanion.d.ts.map +1 -0
  199. package/dist/types/src/containers/ThreadCompanion/index.d.ts +2 -0
  200. package/dist/types/src/containers/ThreadCompanion/index.d.ts.map +1 -0
  201. package/dist/types/src/containers/ThreadContainer/ThreadContainer.d.ts +20 -0
  202. package/dist/types/src/containers/ThreadContainer/ThreadContainer.d.ts.map +1 -0
  203. package/dist/types/src/containers/ThreadContainer/ThreadContainer.stories.d.ts +162 -0
  204. package/dist/types/src/containers/ThreadContainer/ThreadContainer.stories.d.ts.map +1 -0
  205. package/dist/types/src/containers/ThreadContainer/index.d.ts +4 -0
  206. package/dist/types/src/containers/ThreadContainer/index.d.ts.map +1 -0
  207. package/dist/types/src/containers/index.d.ts +8 -0
  208. package/dist/types/src/containers/index.d.ts.map +1 -0
  209. package/dist/types/src/{components/command-extension.d.ts → extensions/command.d.ts} +1 -1
  210. package/dist/types/src/extensions/command.d.ts.map +1 -0
  211. package/dist/types/src/extensions/index.d.ts +1 -0
  212. package/dist/types/src/extensions/index.d.ts.map +1 -1
  213. package/dist/types/src/extensions/threads.d.ts +9 -4
  214. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  215. package/dist/types/src/hooks/analytics.d.ts +2 -3
  216. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  217. package/dist/types/src/hooks/index.d.ts +3 -0
  218. package/dist/types/src/hooks/index.d.ts.map +1 -1
  219. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +2 -0
  220. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +1 -0
  221. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +2 -0
  222. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +1 -0
  223. package/dist/types/src/hooks/useStatus.d.ts.map +1 -1
  224. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +3 -0
  225. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -0
  226. package/dist/types/src/index.d.ts +4 -3
  227. package/dist/types/src/index.d.ts.map +1 -1
  228. package/dist/types/src/meta.d.ts +3 -4
  229. package/dist/types/src/meta.d.ts.map +1 -1
  230. package/dist/types/src/operations/add-message.d.ts +5 -0
  231. package/dist/types/src/operations/add-message.d.ts.map +1 -0
  232. package/dist/types/src/operations/append-channel-message.d.ts +5 -0
  233. package/dist/types/src/operations/append-channel-message.d.ts.map +1 -0
  234. package/dist/types/src/operations/create-channel.d.ts +5 -0
  235. package/dist/types/src/operations/create-channel.d.ts.map +1 -0
  236. package/dist/types/src/operations/create-proposals.d.ts +5 -0
  237. package/dist/types/src/operations/create-proposals.d.ts.map +1 -0
  238. package/dist/types/src/operations/create.d.ts +5 -0
  239. package/dist/types/src/operations/create.d.ts.map +1 -0
  240. package/dist/types/src/operations/definitions.d.ts +1995 -0
  241. package/dist/types/src/operations/definitions.d.ts.map +1 -0
  242. package/dist/types/src/operations/delete-message.d.ts +5 -0
  243. package/dist/types/src/operations/delete-message.d.ts.map +1 -0
  244. package/dist/types/src/operations/delete.d.ts +5 -0
  245. package/dist/types/src/operations/delete.d.ts.map +1 -0
  246. package/dist/types/src/operations/index.d.ts +4 -0
  247. package/dist/types/src/operations/index.d.ts.map +1 -0
  248. package/dist/types/src/operations/on-create-space.d.ts +5 -0
  249. package/dist/types/src/operations/on-create-space.d.ts.map +1 -0
  250. package/dist/types/src/operations/restore-message.d.ts +5 -0
  251. package/dist/types/src/operations/restore-message.d.ts.map +1 -0
  252. package/dist/types/src/operations/restore.d.ts +5 -0
  253. package/dist/types/src/operations/restore.d.ts.map +1 -0
  254. package/dist/types/src/operations/select.d.ts +5 -0
  255. package/dist/types/src/operations/select.d.ts.map +1 -0
  256. package/dist/types/src/operations/toggle-resolved.d.ts +5 -0
  257. package/dist/types/src/operations/toggle-resolved.d.ts.map +1 -0
  258. package/dist/types/src/testing/data.d.ts +5 -0
  259. package/dist/types/src/testing/data.d.ts.map +1 -0
  260. package/dist/types/src/testing/index.d.ts +1 -1
  261. package/dist/types/src/testing/index.d.ts.map +1 -1
  262. package/dist/types/src/translations.d.ts +144 -194
  263. package/dist/types/src/translations.d.ts.map +1 -1
  264. package/dist/types/src/types/Settings.d.ts +5 -0
  265. package/dist/types/src/types/Settings.d.ts.map +1 -0
  266. package/dist/types/src/types/capabilities.d.ts +29 -0
  267. package/dist/types/src/types/capabilities.d.ts.map +1 -0
  268. package/dist/types/src/types/index.d.ts +1 -1
  269. package/dist/types/src/types/index.d.ts.map +1 -1
  270. package/dist/types/src/types/types.d.ts +4 -326
  271. package/dist/types/src/types/types.d.ts.map +1 -1
  272. package/dist/types/src/util.d.ts +21 -3
  273. package/dist/types/src/util.d.ts.map +1 -1
  274. package/dist/types/tsconfig.tsbuildinfo +1 -1
  275. package/package.json +119 -75
  276. package/src/ThreadPlugin.node.ts +39 -0
  277. package/src/ThreadPlugin.test.ts +37 -0
  278. package/src/ThreadPlugin.tsx +66 -149
  279. package/src/blueprints/index.ts +5 -0
  280. package/src/blueprints/thread-blueprint.ts +36 -0
  281. package/src/calls/call-manager.ts +78 -50
  282. package/src/calls/call-swarm-synchronizer.ts +3 -3
  283. package/src/calls/media-manager.ts +77 -41
  284. package/src/calls/types.ts +8 -4
  285. package/src/calls/util/calls-service.ts +74 -19
  286. package/src/calls/util/stub-media-streams.ts +65 -9
  287. package/src/calls/util/task-scheduling.ts +4 -4
  288. package/src/calls-service.stories.tsx +230 -0
  289. package/src/capabilities/app-graph-builder.ts +177 -162
  290. package/src/capabilities/blueprint-definition.ts +19 -0
  291. package/src/capabilities/call-manager.ts +19 -11
  292. package/src/capabilities/create-object.ts +29 -0
  293. package/src/capabilities/index.ts +17 -11
  294. package/src/capabilities/markdown.ts +55 -37
  295. package/src/capabilities/operation-handler.ts +16 -0
  296. package/src/capabilities/react-root.tsx +12 -9
  297. package/src/capabilities/react-surface.tsx +83 -74
  298. package/src/capabilities/settings.ts +28 -12
  299. package/src/capabilities/state.ts +14 -17
  300. package/src/capabilities/undo-mappings.ts +46 -0
  301. package/src/components/Call/Call.tsx +17 -12
  302. package/src/components/Call/Toolbar.tsx +63 -46
  303. package/src/components/Chat/Chat.tsx +258 -0
  304. package/src/components/Chat/index.ts +5 -0
  305. package/src/components/CommentsPanel/CommentsPanel.stories.tsx +95 -0
  306. package/src/components/CommentsPanel/CommentsPanel.tsx +71 -0
  307. package/src/components/CommentsPanel/CommentsThread.tsx +172 -0
  308. package/src/components/CommentsPanel/index.ts +6 -0
  309. package/src/components/Lobby/Lobby.tsx +21 -17
  310. package/src/components/Media/AudioStream.tsx +2 -2
  311. package/src/components/Media/VideoObject.stories.tsx +37 -30
  312. package/src/components/Media/VideoObject.tsx +1 -1
  313. package/src/components/MessagePanel/MessagePanel.tsx +225 -0
  314. package/src/components/MessagePanel/index.ts +5 -0
  315. package/src/components/Participant/Participant.tsx +35 -15
  316. package/src/components/Participant/ParticipantGrid.tsx +1 -1
  317. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +51 -49
  318. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +6 -6
  319. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +15 -12
  320. package/src/components/ResponsiveGrid/{ResponsiveContainer.stories.tsx → ResponsivePanel.stories.tsx} +12 -12
  321. package/src/components/ResponsiveGrid/{ResponsiveContainer.tsx → ResponsivePanel.tsx} +5 -5
  322. package/src/components/ResponsiveGrid/index.ts +1 -1
  323. package/src/components/ThreadSettings/ThreadSettings.stories.tsx +32 -0
  324. package/src/components/ThreadSettings/ThreadSettings.tsx +20 -0
  325. package/src/components/ThreadSettings/index.ts +5 -0
  326. package/src/components/index.ts +6 -12
  327. package/src/containers/CallDebugPanel/CallDebugPanel.tsx +173 -0
  328. package/src/containers/CallDebugPanel/index.ts +5 -0
  329. package/src/containers/CallSidebar/CallSidebar.tsx +18 -0
  330. package/src/containers/CallSidebar/index.ts +5 -0
  331. package/src/containers/ChannelChat/ChannelChat.tsx +75 -0
  332. package/src/containers/ChannelChat/index.ts +8 -0
  333. package/src/containers/ChannelContainer/ChannelContainer.stories.tsx +105 -0
  334. package/src/containers/ChannelContainer/ChannelContainer.tsx +223 -0
  335. package/src/containers/ChannelContainer/index.ts +5 -0
  336. package/src/containers/ThreadCompanion/ThreadCompanion.tsx +215 -0
  337. package/src/containers/ThreadCompanion/index.ts +5 -0
  338. package/src/containers/ThreadContainer/ThreadContainer.stories.tsx +86 -0
  339. package/src/containers/ThreadContainer/ThreadContainer.tsx +75 -0
  340. package/src/containers/ThreadContainer/index.ts +8 -0
  341. package/src/containers/index.ts +12 -0
  342. package/src/{components/command-extension.ts → extensions/command.ts} +7 -4
  343. package/src/extensions/index.ts +1 -0
  344. package/src/extensions/threads.ts +89 -44
  345. package/src/hooks/analytics.ts +22 -21
  346. package/src/hooks/index.ts +4 -0
  347. package/src/hooks/useBlackCanvasStreamTrack.tsx +27 -0
  348. package/src/hooks/useDebugMode.ts +1 -1
  349. package/src/hooks/useInaudibleAudioStreamTrack.tsx +27 -0
  350. package/src/hooks/useVideoStreamTrack.tsx +36 -0
  351. package/src/index.ts +11 -4
  352. package/src/meta.ts +11 -7
  353. package/src/operations/add-message.ts +81 -0
  354. package/src/operations/append-channel-message.ts +36 -0
  355. package/src/operations/create-channel.ts +20 -0
  356. package/src/operations/create-proposals.ts +49 -0
  357. package/src/operations/create.ts +48 -0
  358. package/src/operations/definitions.ts +177 -0
  359. package/src/operations/delete-message.ts +53 -0
  360. package/src/operations/delete.ts +63 -0
  361. package/src/operations/index.ts +22 -0
  362. package/src/operations/on-create-space.ts +27 -0
  363. package/src/operations/restore-message.ts +38 -0
  364. package/src/operations/restore.ts +38 -0
  365. package/src/operations/select.ts +24 -0
  366. package/src/operations/toggle-resolved.ts +41 -0
  367. package/src/testing/data.ts +49 -0
  368. package/src/testing/index.ts +1 -1
  369. package/src/translations.ts +77 -73
  370. package/src/types/Settings.ts +10 -0
  371. package/src/types/capabilities.ts +42 -0
  372. package/src/types/index.ts +1 -1
  373. package/src/types/types.ts +5 -91
  374. package/src/typings/peermetrics-webrtc-stats.d.ts +17 -1
  375. package/src/typings.d.ts +8 -0
  376. package/src/util.ts +38 -6
  377. package/dist/lib/browser/ChannelContainer-PKFBVENP.mjs +0 -15
  378. package/dist/lib/browser/ChatContainer-RSOKYAMK.mjs +0 -14
  379. package/dist/lib/browser/app-graph-builder-OY7R7EJP.mjs +0 -171
  380. package/dist/lib/browser/app-graph-builder-OY7R7EJP.mjs.map +0 -7
  381. package/dist/lib/browser/call-manager-APQAZWHT.mjs +0 -23
  382. package/dist/lib/browser/call-manager-APQAZWHT.mjs.map +0 -7
  383. package/dist/lib/browser/chunk-4H4A264L.mjs +0 -1708
  384. package/dist/lib/browser/chunk-4H4A264L.mjs.map +0 -7
  385. package/dist/lib/browser/chunk-5P5BH5GE.mjs +0 -88
  386. package/dist/lib/browser/chunk-5P5BH5GE.mjs.map +0 -7
  387. package/dist/lib/browser/chunk-6NBVNXTM.mjs +0 -21
  388. package/dist/lib/browser/chunk-6NBVNXTM.mjs.map +0 -7
  389. package/dist/lib/browser/chunk-AEXWNS6Z.mjs +0 -128
  390. package/dist/lib/browser/chunk-AEXWNS6Z.mjs.map +0 -7
  391. package/dist/lib/browser/chunk-IIUTBDVB.mjs +0 -17
  392. package/dist/lib/browser/chunk-IIUTBDVB.mjs.map +0 -7
  393. package/dist/lib/browser/chunk-JKQUJOTX.mjs +0 -31
  394. package/dist/lib/browser/chunk-JKQUJOTX.mjs.map +0 -7
  395. package/dist/lib/browser/chunk-PG5CTFKK.mjs +0 -550
  396. package/dist/lib/browser/chunk-PG5CTFKK.mjs.map +0 -7
  397. package/dist/lib/browser/chunk-R5MDLUPC.mjs +0 -18
  398. package/dist/lib/browser/chunk-R5MDLUPC.mjs.map +0 -7
  399. package/dist/lib/browser/chunk-TAFSCSUR.mjs +0 -351
  400. package/dist/lib/browser/chunk-TAFSCSUR.mjs.map +0 -7
  401. package/dist/lib/browser/chunk-XZKBN3NS.mjs +0 -983
  402. package/dist/lib/browser/chunk-XZKBN3NS.mjs.map +0 -7
  403. package/dist/lib/browser/intent-resolver-FK2MDVDT.mjs +0 -353
  404. package/dist/lib/browser/intent-resolver-FK2MDVDT.mjs.map +0 -7
  405. package/dist/lib/browser/markdown-TE5SWWNJ.mjs +0 -169
  406. package/dist/lib/browser/markdown-TE5SWWNJ.mjs.map +0 -7
  407. package/dist/lib/browser/react-root-NK3A4VG7.mjs +0 -27
  408. package/dist/lib/browser/react-root-NK3A4VG7.mjs.map +0 -7
  409. package/dist/lib/browser/react-surface-VXUJKSOG.mjs +0 -108
  410. package/dist/lib/browser/react-surface-VXUJKSOG.mjs.map +0 -7
  411. package/dist/lib/browser/settings-RB2RSLXV.mjs +0 -22
  412. package/dist/lib/browser/settings-RB2RSLXV.mjs.map +0 -7
  413. package/dist/lib/browser/state-RKL5MSDP.mjs +0 -34
  414. package/dist/lib/browser/state-RKL5MSDP.mjs.map +0 -7
  415. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs +0 -36
  416. package/dist/lib/node/ChannelContainer-YS5YT2ML.cjs.map +0 -7
  417. package/dist/lib/node/ChatContainer-GCOM3M56.cjs +0 -35
  418. package/dist/lib/node/ChatContainer-GCOM3M56.cjs.map +0 -7
  419. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs +0 -179
  420. package/dist/lib/node/app-graph-builder-PBHJNDQY.cjs.map +0 -7
  421. package/dist/lib/node/call-manager-HV2XJW5O.cjs +0 -37
  422. package/dist/lib/node/call-manager-HV2XJW5O.cjs.map +0 -7
  423. package/dist/lib/node/chunk-44I33JDT.cjs +0 -1731
  424. package/dist/lib/node/chunk-44I33JDT.cjs.map +0 -7
  425. package/dist/lib/node/chunk-4YSNVPWU.cjs +0 -37
  426. package/dist/lib/node/chunk-4YSNVPWU.cjs.map +0 -7
  427. package/dist/lib/node/chunk-E3WBZTTI.cjs +0 -371
  428. package/dist/lib/node/chunk-E3WBZTTI.cjs.map +0 -7
  429. package/dist/lib/node/chunk-ERG7G6FF.cjs +0 -59
  430. package/dist/lib/node/chunk-ERG7G6FF.cjs.map +0 -7
  431. package/dist/lib/node/chunk-FUXJAVFZ.cjs +0 -108
  432. package/dist/lib/node/chunk-FUXJAVFZ.cjs.map +0 -7
  433. package/dist/lib/node/chunk-HLMCEE5K.cjs +0 -41
  434. package/dist/lib/node/chunk-HLMCEE5K.cjs.map +0 -7
  435. package/dist/lib/node/chunk-IP533AMV.cjs +0 -554
  436. package/dist/lib/node/chunk-IP533AMV.cjs.map +0 -7
  437. package/dist/lib/node/chunk-LR5NENBE.cjs +0 -54
  438. package/dist/lib/node/chunk-LR5NENBE.cjs.map +0 -7
  439. package/dist/lib/node/chunk-UM36TPCT.cjs +0 -984
  440. package/dist/lib/node/chunk-UM36TPCT.cjs.map +0 -7
  441. package/dist/lib/node/chunk-ZGDN3XBR.cjs +0 -149
  442. package/dist/lib/node/chunk-ZGDN3XBR.cjs.map +0 -7
  443. package/dist/lib/node/index.cjs +0 -310
  444. package/dist/lib/node/index.cjs.map +0 -7
  445. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs +0 -363
  446. package/dist/lib/node/intent-resolver-SYSJ5SJG.cjs.map +0 -7
  447. package/dist/lib/node/markdown-GQIPJS2F.cjs +0 -178
  448. package/dist/lib/node/markdown-GQIPJS2F.cjs.map +0 -7
  449. package/dist/lib/node/meta.json +0 -1
  450. package/dist/lib/node/react-root-6HHDMULJ.cjs +0 -51
  451. package/dist/lib/node/react-root-6HHDMULJ.cjs.map +0 -7
  452. package/dist/lib/node/react-surface-NBH42NN2.cjs +0 -122
  453. package/dist/lib/node/react-surface-NBH42NN2.cjs.map +0 -7
  454. package/dist/lib/node/settings-4LQSFEDK.cjs +0 -36
  455. package/dist/lib/node/settings-4LQSFEDK.cjs.map +0 -7
  456. package/dist/lib/node/state-IY5XX3H2.cjs +0 -50
  457. package/dist/lib/node/state-IY5XX3H2.cjs.map +0 -7
  458. package/dist/lib/node/types/index.cjs +0 -38
  459. package/dist/lib/node/types/index.cjs.map +0 -7
  460. package/dist/lib/node-esm/ChannelContainer-O4QJII2P.mjs +0 -16
  461. package/dist/lib/node-esm/ChannelContainer-O4QJII2P.mjs.map +0 -7
  462. package/dist/lib/node-esm/ChatContainer-F6CSADV7.mjs +0 -15
  463. package/dist/lib/node-esm/ChatContainer-F6CSADV7.mjs.map +0 -7
  464. package/dist/lib/node-esm/app-graph-builder-BAHBHYWI.mjs +0 -172
  465. package/dist/lib/node-esm/app-graph-builder-BAHBHYWI.mjs.map +0 -7
  466. package/dist/lib/node-esm/call-manager-UUYXLF4T.mjs +0 -24
  467. package/dist/lib/node-esm/call-manager-UUYXLF4T.mjs.map +0 -7
  468. package/dist/lib/node-esm/chunk-2RNIPFDA.mjs +0 -984
  469. package/dist/lib/node-esm/chunk-2RNIPFDA.mjs.map +0 -7
  470. package/dist/lib/node-esm/chunk-ESQC6SYE.mjs +0 -19
  471. package/dist/lib/node-esm/chunk-ESQC6SYE.mjs.map +0 -7
  472. package/dist/lib/node-esm/chunk-K4KAUOKT.mjs +0 -19
  473. package/dist/lib/node-esm/chunk-K4KAUOKT.mjs.map +0 -7
  474. package/dist/lib/node-esm/chunk-O3V45YJP.mjs +0 -90
  475. package/dist/lib/node-esm/chunk-O3V45YJP.mjs.map +0 -7
  476. package/dist/lib/node-esm/chunk-O63QJPQX.mjs +0 -23
  477. package/dist/lib/node-esm/chunk-O63QJPQX.mjs.map +0 -7
  478. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs +0 -352
  479. package/dist/lib/node-esm/chunk-P6RLFCNT.mjs.map +0 -7
  480. package/dist/lib/node-esm/chunk-PGRP3O4O.mjs +0 -33
  481. package/dist/lib/node-esm/chunk-PGRP3O4O.mjs.map +0 -7
  482. package/dist/lib/node-esm/chunk-UJMPYKT3.mjs +0 -129
  483. package/dist/lib/node-esm/chunk-UJMPYKT3.mjs.map +0 -7
  484. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs +0 -551
  485. package/dist/lib/node-esm/chunk-UZWVVFT3.mjs.map +0 -7
  486. package/dist/lib/node-esm/chunk-WXNPD542.mjs +0 -1710
  487. package/dist/lib/node-esm/chunk-WXNPD542.mjs.map +0 -7
  488. package/dist/lib/node-esm/intent-resolver-BU73VYW3.mjs +0 -354
  489. package/dist/lib/node-esm/intent-resolver-BU73VYW3.mjs.map +0 -7
  490. package/dist/lib/node-esm/markdown-HJUWNBLS.mjs +0 -170
  491. package/dist/lib/node-esm/markdown-HJUWNBLS.mjs.map +0 -7
  492. package/dist/lib/node-esm/react-root-RUXOAQNW.mjs +0 -28
  493. package/dist/lib/node-esm/react-root-RUXOAQNW.mjs.map +0 -7
  494. package/dist/lib/node-esm/react-surface-ELXFYKP6.mjs +0 -109
  495. package/dist/lib/node-esm/react-surface-ELXFYKP6.mjs.map +0 -7
  496. package/dist/lib/node-esm/settings-EA7DFSM6.mjs +0 -23
  497. package/dist/lib/node-esm/settings-EA7DFSM6.mjs.map +0 -7
  498. package/dist/lib/node-esm/state-6AUTNROZ.mjs +0 -35
  499. package/dist/lib/node-esm/state-6AUTNROZ.mjs.map +0 -7
  500. package/dist/types/src/capabilities/capabilities.d.ts +0 -27
  501. package/dist/types/src/capabilities/capabilities.d.ts.map +0 -1
  502. package/dist/types/src/capabilities/intent-resolver.d.ts +0 -4
  503. package/dist/types/src/capabilities/intent-resolver.d.ts.map +0 -1
  504. package/dist/types/src/components/CallDebugPanel.d.ts +0 -8
  505. package/dist/types/src/components/CallDebugPanel.d.ts.map +0 -1
  506. package/dist/types/src/components/CallSidebar.d.ts.map +0 -1
  507. package/dist/types/src/components/ChannelContainer.d.ts +0 -14
  508. package/dist/types/src/components/ChannelContainer.d.ts.map +0 -1
  509. package/dist/types/src/components/ChannelContainer.stories.d.ts +0 -10
  510. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +0 -1
  511. package/dist/types/src/components/Chat.stories.d.ts +0 -6
  512. package/dist/types/src/components/Chat.stories.d.ts.map +0 -1
  513. package/dist/types/src/components/ChatContainer.d.ts +0 -17
  514. package/dist/types/src/components/ChatContainer.d.ts.map +0 -1
  515. package/dist/types/src/components/CommentContainer.d.ts +0 -13
  516. package/dist/types/src/components/CommentContainer.d.ts.map +0 -1
  517. package/dist/types/src/components/Comments.stories.d.ts +0 -6
  518. package/dist/types/src/components/Comments.stories.d.ts.map +0 -1
  519. package/dist/types/src/components/CommentsContainer.d.ts +0 -13
  520. package/dist/types/src/components/CommentsContainer.d.ts.map +0 -1
  521. package/dist/types/src/components/MessageContainer.d.ts +0 -11
  522. package/dist/types/src/components/MessageContainer.d.ts.map +0 -1
  523. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.d.ts.map +0 -1
  524. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +0 -10
  525. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +0 -1
  526. package/dist/types/src/components/ThreadComplementary.d.ts +0 -5
  527. package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
  528. package/dist/types/src/components/ThreadSettings.d.ts +0 -6
  529. package/dist/types/src/components/ThreadSettings.d.ts.map +0 -1
  530. package/dist/types/src/components/command-extension.d.ts.map +0 -1
  531. package/dist/types/src/components/testing.d.ts +0 -4
  532. package/dist/types/src/components/testing.d.ts.map +0 -1
  533. package/dist/types/src/peers.stories.d.ts +0 -11
  534. package/dist/types/src/peers.stories.d.ts.map +0 -1
  535. package/dist/types/src/testing/stories.d.ts +0 -2
  536. package/dist/types/src/testing/stories.d.ts.map +0 -1
  537. package/dist/types/src/types/schema.d.ts +0 -133
  538. package/dist/types/src/types/schema.d.ts.map +0 -1
  539. package/src/capabilities/capabilities.ts +0 -33
  540. package/src/capabilities/intent-resolver.ts +0 -296
  541. package/src/components/CallDebugPanel.tsx +0 -115
  542. package/src/components/CallSidebar.tsx +0 -17
  543. package/src/components/ChannelContainer.stories.tsx +0 -58
  544. package/src/components/ChannelContainer.tsx +0 -199
  545. package/src/components/Chat.stories.tsx +0 -88
  546. package/src/components/ChatContainer.tsx +0 -140
  547. package/src/components/CommentContainer.tsx +0 -198
  548. package/src/components/Comments.stories.tsx +0 -85
  549. package/src/components/CommentsContainer.tsx +0 -66
  550. package/src/components/MessageContainer.tsx +0 -167
  551. package/src/components/ThreadComplementary.tsx +0 -151
  552. package/src/components/ThreadSettings.tsx +0 -17
  553. package/src/components/testing.ts +0 -29
  554. package/src/peers.stories.tsx +0 -189
  555. package/src/testing/stories.ts +0 -50
  556. package/src/types/schema.ts +0 -33
  557. /package/dist/lib/browser/{ChannelContainer-PKFBVENP.mjs.map → chunk-J5LGTIGS.mjs.map} +0 -0
  558. /package/dist/lib/{browser/ChatContainer-RSOKYAMK.mjs.map → node-esm/chunk-HSLMI22Q.mjs.map} +0 -0
@@ -1,1708 +0,0 @@
1
- // packages/plugins/plugin-thread/src/calls/types.ts
2
- import { buf } from "@dxos/protocols/buf";
3
- import { UserStateSchema } from "@dxos/protocols/buf/dxos/edge/calls_pb";
4
- var CALLS_URL = "https://calls-service.dxos.workers.dev";
5
- var codec = {
6
- encode: (message) => {
7
- return buf.toBinary(UserStateSchema, buf.create(UserStateSchema, message));
8
- },
9
- decode: (message) => {
10
- return buf.fromBinary(UserStateSchema, message);
11
- }
12
- };
13
- var TrackNameCodec = {
14
- encode: (trackData) => {
15
- return trackData.sessionId + "/" + trackData.trackName;
16
- },
17
- decode: (name) => {
18
- const [sessionId, trackName] = name.split("/");
19
- return {
20
- sessionId,
21
- trackName,
22
- location: "remote"
23
- };
24
- }
25
- };
26
-
27
- // packages/plugins/plugin-thread/src/calls/call-swarm-synchronizer.ts
28
- import md5Hex from "md5-hex";
29
- import { DeferredTask, Event, scheduleTaskInterval, synchronized } from "@dxos/async";
30
- import { Context, Resource } from "@dxos/context";
31
- import { generateName } from "@dxos/display-name";
32
- import { invariant } from "@dxos/invariant";
33
- import { PublicKey } from "@dxos/keys";
34
- import { log } from "@dxos/log";
35
- import { buf as buf2 } from "@dxos/protocols/buf";
36
- import { ActivitySchema } from "@dxos/protocols/buf/dxos/edge/calls_pb";
37
- import { ConnectionState } from "@dxos/protocols/proto/dxos/edge/messenger";
38
- import { isNonNullable } from "@dxos/util";
39
- function _ts_decorate(decorators, target, key, desc) {
40
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
41
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
42
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
43
- return c > 3 && r && Object.defineProperty(target, key, r), r;
44
- }
45
- var __dxlog_file = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/calls/call-swarm-synchronizer.ts";
46
- var DISCONNECTED_ABRUPT_TIMEOUT = 1e4;
47
- var CallSwarmSynchronizer = class extends Resource {
48
- constructor({ networkService }) {
49
- super();
50
- this.stateUpdated = new Event();
51
- this._state = {
52
- activities: {}
53
- };
54
- this._lastSwarmEvent = void 0;
55
- this._reconcileSwarmStateTask = void 0;
56
- this._identityKey = void 0;
57
- this._deviceKey = void 0;
58
- this._displayName = void 0;
59
- this._swarmCtx = void 0;
60
- this._sendStateTask = void 0;
61
- this._networkService = networkService;
62
- }
63
- /**
64
- * @internal
65
- */
66
- _getState() {
67
- return this._state;
68
- }
69
- setRaisedHand(raisedHand) {
70
- if (this._state.raisedHand === raisedHand) {
71
- return;
72
- }
73
- this._state.raisedHand = raisedHand;
74
- this._notifyAndSchedule();
75
- }
76
- setSpeaking(speaking) {
77
- if (this._state.speaking === speaking) {
78
- return;
79
- }
80
- this._state.speaking = speaking;
81
- this._notifyAndSchedule();
82
- }
83
- setJoined(joined) {
84
- if (this._state.joined === joined) {
85
- return;
86
- }
87
- this._state.joined = joined;
88
- this._notifyAndSchedule();
89
- }
90
- setTracks(tracks) {
91
- this._state.tracks = {
92
- ...this._state.tracks,
93
- ...tracks
94
- };
95
- this._notifyAndSchedule();
96
- }
97
- setActivity(key, payload) {
98
- const lamportTimestamp = LamportTimestampCrdt.increment(this._state.activities?.[key]?.lamportTimestamp ?? {
99
- id: this._deviceKey
100
- });
101
- this._state.activities[key] = {
102
- lamportTimestamp,
103
- payload
104
- };
105
- this._notifyAndSchedule();
106
- }
107
- /**
108
- * @internal
109
- */
110
- _setIdentity(identity) {
111
- this._identityKey = identity.identityKey.toHex();
112
- this._displayName = identity.profile?.displayName ?? generateName(identity.identityKey.toHex());
113
- }
114
- /**
115
- * @internal
116
- */
117
- _setDevice(device) {
118
- this._deviceKey = device.deviceKey.toHex();
119
- }
120
- /**
121
- * @internal
122
- */
123
- _setRoomId(roomId) {
124
- if (this._swarmCtx) {
125
- log.verbose("joined to a different room", {
126
- roomId
127
- }, {
128
- F: __dxlog_file,
129
- L: 152,
130
- S: this,
131
- C: (f, a) => f(...a)
132
- });
133
- return;
134
- }
135
- this._state.roomId = roomId;
136
- }
137
- async _open() {
138
- this._sendStateTask = new DeferredTask(this._ctx, async () => {
139
- await this._sendState();
140
- });
141
- this._reconcileSwarmStateTask = new DeferredTask(this._ctx, async () => {
142
- await this._reconcileSwarmState();
143
- });
144
- }
145
- async _close() {
146
- this._sendStateTask = void 0;
147
- this._reconcileSwarmStateTask = void 0;
148
- }
149
- async join() {
150
- invariant(this._state.roomId, void 0, {
151
- F: __dxlog_file,
152
- L: 176,
153
- S: this,
154
- A: [
155
- "this._state.roomId",
156
- ""
157
- ]
158
- });
159
- invariant(!this._swarmCtx, "Already joined", {
160
- F: __dxlog_file,
161
- L: 177,
162
- S: this,
163
- A: [
164
- "!this._swarmCtx",
165
- "'Already joined'"
166
- ]
167
- });
168
- this._swarmCtx = new Context(void 0, {
169
- F: __dxlog_file,
170
- L: 179
171
- });
172
- const topic = getTopic(this._state.roomId);
173
- log("joining swarm", {
174
- topic,
175
- peer: {
176
- identityKey: this._identityKey,
177
- peerKey: this._deviceKey
178
- }
179
- }, {
180
- F: __dxlog_file,
181
- L: 181,
182
- S: this,
183
- C: (f, a) => f(...a)
184
- });
185
- const stream = this._networkService.subscribeSwarmState({
186
- topic
187
- });
188
- stream.subscribe((event) => this._processSwarmEvent(event));
189
- const cleanup = () => {
190
- void stream.close();
191
- if (topic && this._identityKey && this._deviceKey) {
192
- log("leaving swarm", {
193
- topic,
194
- peer: {
195
- identityKey: this._identityKey,
196
- peerKey: this._deviceKey
197
- }
198
- }, {
199
- F: __dxlog_file,
200
- L: 188,
201
- S: this,
202
- C: (f, a) => f(...a)
203
- });
204
- void this._networkService.leaveSwarm({
205
- topic,
206
- peer: {
207
- identityKey: this._identityKey,
208
- peerKey: this._deviceKey
209
- }
210
- }).catch((err) => log.catch(err, void 0, {
211
- F: __dxlog_file,
212
- L: 194,
213
- S: this,
214
- C: (f, a) => f(...a)
215
- }));
216
- }
217
- window.removeEventListener("beforeunload", cleanup);
218
- };
219
- window.addEventListener("beforeunload", cleanup);
220
- this._swarmCtx.onDispose(cleanup);
221
- this._notifyAndSchedule();
222
- }
223
- async leave() {
224
- if (!this._swarmCtx) {
225
- return;
226
- }
227
- await this._swarmCtx.dispose();
228
- this._swarmCtx = void 0;
229
- this._state.users = void 0;
230
- this._state.self = void 0;
231
- }
232
- async querySwarm(roomId) {
233
- const topic = getTopic(roomId);
234
- const swarm = await this._networkService.querySwarm({
235
- topic
236
- });
237
- return swarm.peers ?? [];
238
- }
239
- /**
240
- * Notify and schedule send state task.
241
- */
242
- _notifyAndSchedule() {
243
- this.stateUpdated.emit(this._state);
244
- if (this._state.joined) {
245
- this._sendStateTask?.schedule();
246
- }
247
- }
248
- async _sendState() {
249
- if (!this._state.roomId || !this._identityKey || !this._deviceKey || !this._state.joined) {
250
- return;
251
- }
252
- const state = {
253
- ...this._state,
254
- id: this._deviceKey,
255
- name: this._displayName,
256
- activities: this._state.activities ? Object.fromEntries(Object.entries(this._state.activities).map(([key, activity]) => [
257
- key,
258
- buf2.create(ActivitySchema, activity)
259
- ])) : {}
260
- };
261
- await this._networkService.joinSwarm({
262
- topic: getTopic(this._state.roomId),
263
- peer: {
264
- identityKey: this._identityKey,
265
- peerKey: this._deviceKey,
266
- state: codec.encode(state)
267
- }
268
- });
269
- }
270
- _processSwarmEvent(swarmEvent) {
271
- if (!this._state.joined) {
272
- return;
273
- }
274
- this._lastSwarmEvent = swarmEvent;
275
- this._reconcileSwarmStateTask.schedule();
276
- }
277
- async _reconcileSwarmState() {
278
- const swarmEvent = this._lastSwarmEvent;
279
- invariant(swarmEvent, void 0, {
280
- F: __dxlog_file,
281
- L: 273,
282
- S: this,
283
- A: [
284
- "swarmEvent",
285
- ""
286
- ]
287
- });
288
- const peers = [
289
- ...swarmEvent.peers ?? [],
290
- ...(swarmEvent.inactivePeers ?? []).filter(({ disconnected, connectionState }) => connectionState === ConnectionState.DISCONNECTED_ABRUPT && disconnected && disconnected > Date.now() - DISCONNECTED_ABRUPT_TIMEOUT)
291
- ].sort((peer1, peer2) => peer1.peerKey.localeCompare(peer2.peerKey));
292
- const users = peers.map((peer) => {
293
- try {
294
- return codec.decode(peer.state);
295
- } catch (error) {
296
- log.error("error decoding peer state", {
297
- error,
298
- peer
299
- }, {
300
- F: __dxlog_file,
301
- L: 290,
302
- S: this,
303
- C: (f, a) => f(...a)
304
- });
305
- return void 0;
306
- }
307
- }).filter(isNonNullable);
308
- this._state.users = users;
309
- this._state.self = users.find((user) => user.id === this._deviceKey);
310
- log("reconciling swarm state", {
311
- users
312
- }, {
313
- F: __dxlog_file,
314
- L: 297,
315
- S: this,
316
- C: (f, a) => f(...a)
317
- });
318
- if (users.length === 0) {
319
- return;
320
- }
321
- const activityKeys = new Set(users.flatMap((user) => Object.keys(user.activities)));
322
- [
323
- ...activityKeys
324
- ].forEach((key) => {
325
- const activities = users.map((user) => user.activities?.[key]).filter(isNonNullable);
326
- const lastActivity = LamportTimestampCrdt.getLastState(activities);
327
- if (lastActivity && lastActivity.lamportTimestamp.version > (this._state.activities[key]?.lamportTimestamp?.version ?? 0)) {
328
- this._state.activities[key] = lastActivity;
329
- }
330
- });
331
- this.stateUpdated.emit(this._state);
332
- if (peers.some((peer) => peer.connectionState !== ConnectionState.CONNECTED)) {
333
- scheduleTaskInterval(this._ctx, async () => this._reconcileSwarmStateTask.schedule(), Math.min(DISCONNECTED_ABRUPT_TIMEOUT / 2, 1e3));
334
- }
335
- }
336
- };
337
- _ts_decorate([
338
- synchronized
339
- ], CallSwarmSynchronizer.prototype, "join", null);
340
- _ts_decorate([
341
- synchronized
342
- ], CallSwarmSynchronizer.prototype, "leave", null);
343
- var LamportTimestampCrdt = class {
344
- static getLastState(states) {
345
- const maxTimestamp = Math.max(...states.map((state) => state.lamportTimestamp?.version ?? 0));
346
- const sortedStates = states.filter((state) => state.lamportTimestamp && state.lamportTimestamp.version === maxTimestamp && state.lamportTimestamp.id).sort((a, b) => a.lamportTimestamp.id.localeCompare(b.lamportTimestamp.id));
347
- return sortedStates[0];
348
- }
349
- static increment(timestamp) {
350
- return {
351
- ...timestamp ?? {},
352
- version: (timestamp?.version ?? 0) + 1
353
- };
354
- }
355
- };
356
- var getTopic = (roomId) => PublicKey.fromHex(md5Hex(roomId));
357
-
358
- // packages/plugins/plugin-thread/src/calls/util/audio.ts
359
- var monitorAudioLevel = ({ mediaStreamTrack, intervalMs = 1e3 / 10, onMeasure }) => {
360
- let timeout = -1;
361
- let interval = -1;
362
- const audioContext = new AudioContext();
363
- const stream = new MediaStream();
364
- stream.addTrack(mediaStreamTrack);
365
- const mediaStreamAudioSourceNode = audioContext.createMediaStreamSource(stream);
366
- const analyserNode = audioContext.createAnalyser();
367
- mediaStreamAudioSourceNode.connect(analyserNode);
368
- analyserNode.fftSize = 32;
369
- const pcmData = new Float32Array(analyserNode.fftSize);
370
- let peak = 0;
371
- interval = window.setInterval(() => {
372
- onMeasure(peak);
373
- peak = 0;
374
- }, intervalMs);
375
- const tick = () => {
376
- timeout = window.setTimeout(() => {
377
- analyserNode.getFloatTimeDomainData(pcmData);
378
- let sumSquares = 0;
379
- for (const amplitude of pcmData) {
380
- sumSquares += amplitude * amplitude;
381
- }
382
- const current = Math.sqrt(sumSquares / pcmData.length);
383
- if (current > peak) {
384
- peak = current;
385
- }
386
- tick();
387
- }, intervalMs);
388
- };
389
- tick();
390
- return () => {
391
- mediaStreamAudioSourceNode.disconnect();
392
- analyserNode.disconnect();
393
- void audioContext.close();
394
- clearInterval(interval);
395
- clearTimeout(timeout);
396
- stream.removeTrack(mediaStreamTrack);
397
- };
398
- };
399
-
400
- // packages/plugins/plugin-thread/src/calls/util/calls-service.ts
401
- import { PersistentLifecycle } from "@dxos/async";
402
- import { Resource as Resource2 } from "@dxos/context";
403
- import { invariant as invariant2 } from "@dxos/invariant";
404
- import { log as log2 } from "@dxos/log";
405
-
406
- // packages/plugins/plugin-thread/src/calls/util/history-cache.ts
407
- var HistoryCache = class {
408
- constructor(limit = 100) {
409
- this._limit = limit;
410
- this._messages = [];
411
- }
412
- push(...messages) {
413
- if (this._messages.length >= this._limit) {
414
- this._messages.shift();
415
- }
416
- this._messages.push(...messages);
417
- }
418
- get() {
419
- return this._messages;
420
- }
421
- };
422
-
423
- // packages/plugins/plugin-thread/src/calls/util/task-scheduling.ts
424
- var DefaultBatchSizeLimit = 64;
425
- var FIFOScheduler = class {
426
- #schedulerChain;
427
- constructor() {
428
- this.#schedulerChain = Promise.resolve();
429
- }
430
- schedule(task) {
431
- return new Promise((resolve, reject) => {
432
- this.#schedulerChain = this.#schedulerChain.then(async () => {
433
- try {
434
- resolve(await task());
435
- } catch (error) {
436
- reject(error);
437
- }
438
- });
439
- });
440
- }
441
- };
442
- var BulkRequestDispatcher = class {
443
- #currentBatch;
444
- #currentBulkResponse;
445
- #batchSizeLimit;
446
- constructor(batchSizeLimit = DefaultBatchSizeLimit) {
447
- this.#currentBatch = [];
448
- this.#currentBulkResponse = null;
449
- this.#batchSizeLimit = batchSizeLimit;
450
- }
451
- /**
452
- * Returns a bulk response promise.
453
- * At the event loop iteration end, the accumulated entries will be dispatched as a bulk request.
454
- */
455
- doBulkRequest(params, bulkRequestFunc) {
456
- if (this.#currentBatch.length >= this.#batchSizeLimit) {
457
- this.#currentBatch = [];
458
- this.#currentBulkResponse = null;
459
- }
460
- this.#currentBatch.push(params);
461
- if (this.#currentBulkResponse != null) {
462
- return this.#currentBulkResponse;
463
- }
464
- const batch = this.#currentBatch;
465
- this.#currentBulkResponse = new Promise((resolve, reject) => {
466
- setTimeout(() => {
467
- this.#currentBulkResponse = null;
468
- const batchCopy = batch.splice(0, batch.length);
469
- bulkRequestFunc(batchCopy).then((result) => {
470
- resolve(result);
471
- }).catch((err) => {
472
- reject(err);
473
- });
474
- }, 0);
475
- });
476
- return this.#currentBulkResponse;
477
- }
478
- };
479
-
480
- // packages/plugins/plugin-thread/src/calls/util/calls-service.ts
481
- var __dxlog_file2 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/calls/util/calls-service.ts";
482
- var NETWORK_TIMEOUT = 5e3;
483
- var CallsServicePeer = class extends Resource2 {
484
- constructor(config) {
485
- super();
486
- this.history = new HistoryCache(100);
487
- this._persistentLifecycle = new PersistentLifecycle({
488
- start: () => this._startSession(),
489
- stop: (session) => this._stopSession(session)
490
- });
491
- this.taskScheduler = new FIFOScheduler();
492
- this.pushTrackDispatcher = new BulkRequestDispatcher(32);
493
- this.pullTrackDispatcher = new BulkRequestDispatcher(32);
494
- this.closeTrackDispatcher = new BulkRequestDispatcher(32);
495
- this._config = config;
496
- }
497
- async _open(ctx) {
498
- await this._persistentLifecycle.open(ctx);
499
- }
500
- async _close() {
501
- await this._persistentLifecycle.close();
502
- }
503
- get session() {
504
- return this._persistentLifecycle.state;
505
- }
506
- async _startSession() {
507
- const peerConnection = await this._createRtcConnection();
508
- const sessionId = await this._initiateCallSession();
509
- return {
510
- sessionId,
511
- peerConnection
512
- };
513
- }
514
- async _stopSession(session) {
515
- session.peerConnection.close();
516
- }
517
- async _createRtcConnection() {
518
- const peerConnection = new RTCPeerConnection({
519
- iceServers: this._config.iceServers,
520
- bundlePolicy: "max-bundle"
521
- });
522
- peerConnection.addEventListener("connectionstatechange", () => {
523
- if (peerConnection.connectionState === "failed" || peerConnection.connectionState === "closed") {
524
- log2.warn("calls connection failed", {
525
- state: peerConnection.connectionState
526
- }, {
527
- F: __dxlog_file2,
528
- L: 115,
529
- S: this,
530
- C: (f, a) => f(...a)
531
- });
532
- void this._persistentLifecycle.scheduleRestart();
533
- }
534
- });
535
- let iceTimeout = -1;
536
- peerConnection.addEventListener("iceconnectionstatechange", () => {
537
- clearTimeout(iceTimeout);
538
- if (peerConnection.iceConnectionState === "failed" || peerConnection.iceConnectionState === "closed") {
539
- log2.warn("calls connection to ICEs failed", {
540
- state: peerConnection.iceConnectionState
541
- }, {
542
- F: __dxlog_file2,
543
- L: 124,
544
- S: this,
545
- C: (f, a) => f(...a)
546
- });
547
- void this._persistentLifecycle.scheduleRestart();
548
- } else if (peerConnection.iceConnectionState === "disconnected") {
549
- const timeoutSeconds = 7;
550
- iceTimeout = window.setTimeout(() => {
551
- if (peerConnection.iceConnectionState === "connected") {
552
- log2.info("calls iceConnectionState is connected", void 0, {
553
- F: __dxlog_file2,
554
- L: 133,
555
- S: this,
556
- C: (f, a) => f(...a)
557
- });
558
- return;
559
- }
560
- log2.warn("calls iceConnectionState timed out", {
561
- state: peerConnection.iceConnectionState,
562
- timeoutSeconds
563
- }, {
564
- F: __dxlog_file2,
565
- L: 137,
566
- S: this,
567
- C: (f, a) => f(...a)
568
- });
569
- void this._persistentLifecycle.scheduleRestart();
570
- }, timeoutSeconds * 1e3);
571
- }
572
- });
573
- return peerConnection;
574
- }
575
- async _initiateCallSession() {
576
- log2("creating new session", void 0, {
577
- F: __dxlog_file2,
578
- L: 147,
579
- S: this,
580
- C: (f, a) => f(...a)
581
- });
582
- const { sessionId } = await this._fetch("/sessions/new?SESSION", {
583
- method: "POST"
584
- });
585
- return sessionId;
586
- }
587
- async _fetch(relativePath, requestInit) {
588
- this.history.push({
589
- type: "request",
590
- time: (/* @__PURE__ */ new Date()).toISOString(),
591
- method: requestInit?.method ?? "GET",
592
- body: requestInit?.body
593
- });
594
- const response = await fetch(`${this._config.apiBase}${relativePath}`, {
595
- ...requestInit,
596
- redirect: "manual"
597
- });
598
- if (response.status >= 400) {
599
- log2.error("error while fetching from Calls service", {
600
- status: response.status,
601
- text: await response.text()
602
- }, {
603
- F: __dxlog_file2,
604
- L: 162,
605
- S: this,
606
- C: (f, a) => f(...a)
607
- });
608
- throw new Error("Error while fetching from Calls service");
609
- }
610
- try {
611
- const data = await response.clone().json();
612
- this.history.push({
613
- type: "response",
614
- time: (/* @__PURE__ */ new Date()).toISOString(),
615
- status: response.status,
616
- json: data
617
- });
618
- if (data.errorCode) {
619
- throw new Error(data.errorDescription);
620
- }
621
- return data;
622
- } catch (error) {
623
- const text = await response.text();
624
- this.history.push({
625
- type: "response",
626
- time: (/* @__PURE__ */ new Date()).toISOString(),
627
- status: response.status,
628
- text
629
- });
630
- log2.error("Error parsing response from Calls service", {
631
- error,
632
- text,
633
- status: response.status
634
- }, {
635
- F: __dxlog_file2,
636
- L: 187,
637
- S: this,
638
- C: (f, a) => f(...a)
639
- });
640
- throw error;
641
- }
642
- }
643
- async _pushTrackInBulk({ ctx, peerConnection, transceiver, sessionId, trackName }) {
644
- log2.verbose("pushing track ", trackName, {
645
- F: __dxlog_file2,
646
- L: 209,
647
- S: this,
648
- C: (f, a) => f(...a)
649
- });
650
- const pushedTrackPromise = this.pushTrackDispatcher.doBulkRequest({
651
- trackName,
652
- transceiver
653
- }, (tracks) => this.taskScheduler.schedule(async () => {
654
- const offer = await peerConnection.createOffer();
655
- offer.sdp = offer.sdp?.replace("useinbandfec=1", "usedtx=1;useinbandfec=1");
656
- await peerConnection.setLocalDescription(offer);
657
- const response = await this._fetch(`/sessions/${sessionId}/tracks/new?PUSHING`, {
658
- method: "POST",
659
- body: JSON.stringify({
660
- sessionDescription: {
661
- sdp: offer.sdp,
662
- type: "offer"
663
- },
664
- tracks: tracks.map(({ trackName: trackName2, transceiver: transceiver2 }) => ({
665
- trackName: trackName2,
666
- mid: transceiver2.mid,
667
- location: "local"
668
- }))
669
- })
670
- });
671
- invariant2(response.tracks !== void 0, void 0, {
672
- F: __dxlog_file2,
673
- L: 234,
674
- S: this,
675
- A: [
676
- "response.tracks !== undefined",
677
- ""
678
- ]
679
- });
680
- if (!response.errorCode) {
681
- await peerConnection.setRemoteDescription(new RTCSessionDescription(response.sessionDescription));
682
- await peerConnectionIsConnected(peerConnection);
683
- }
684
- return {
685
- tracks: response.tracks
686
- };
687
- })).then(({ tracks }) => {
688
- const trackData = tracks.find((t) => t.mid === transceiver.mid);
689
- if (trackData) {
690
- return {
691
- ...trackData,
692
- sessionId,
693
- location: "remote"
694
- };
695
- } else {
696
- log2.error("missing track data", void 0, {
697
- F: __dxlog_file2,
698
- L: 254,
699
- S: this,
700
- C: (f, a) => f(...a)
701
- });
702
- }
703
- }).catch((err) => {
704
- log2.catch(err, void 0, {
705
- F: __dxlog_file2,
706
- L: 258,
707
- S: this,
708
- C: (f, a) => f(...a)
709
- });
710
- });
711
- const onDispose = async () => {
712
- if (transceiver.mid) {
713
- await this._closeTrackInBulk(peerConnection, transceiver.mid, sessionId);
714
- }
715
- };
716
- ctx?.onDispose(async () => await onDispose());
717
- this._ctx.onDispose(() => onDispose());
718
- return pushedTrackPromise;
719
- }
720
- async pushTrack({ track, encodings = [], ctx, previousTrack }) {
721
- await this.waitUntilOpen();
722
- invariant2(this.session, void 0, {
723
- F: __dxlog_file2,
724
- L: 285,
725
- S: this,
726
- A: [
727
- "this.session",
728
- ""
729
- ]
730
- });
731
- log2("trying to push track", {
732
- track,
733
- previousTrack,
734
- encodings
735
- }, {
736
- F: __dxlog_file2,
737
- L: 286,
738
- S: this,
739
- C: (f, a) => f(...a)
740
- });
741
- if (previousTrack) {
742
- const transceiver2 = this.session.peerConnection.getTransceivers().find((t) => t.mid === previousTrack.mid);
743
- if (transceiver2?.sender.track === track) {
744
- log2.verbose("track already pushed", {
745
- track,
746
- previousTrack,
747
- transceiver: transceiver2
748
- }, {
749
- F: __dxlog_file2,
750
- L: 290,
751
- S: this,
752
- C: (f, a) => f(...a)
753
- });
754
- return previousTrack;
755
- } else if (transceiver2) {
756
- log2.verbose("replacing track", {
757
- track,
758
- previousTrack,
759
- transceiver: transceiver2
760
- }, {
761
- F: __dxlog_file2,
762
- L: 293,
763
- S: this,
764
- C: (f, a) => f(...a)
765
- });
766
- transceiver2.sender.replaceTrack(track).catch((err) => log2.catch(err, void 0, {
767
- F: __dxlog_file2,
768
- L: 294,
769
- S: this,
770
- C: (f, a) => f(...a)
771
- }));
772
- return previousTrack;
773
- }
774
- }
775
- invariant2(track, void 0, {
776
- F: __dxlog_file2,
777
- L: 298,
778
- S: this,
779
- A: [
780
- "track",
781
- ""
782
- ]
783
- });
784
- const stableId = crypto.randomUUID();
785
- const transceiver = this.session.peerConnection.addTransceiver(track, {
786
- direction: "sendonly"
787
- });
788
- log2.verbose("creating transceiver", void 0, {
789
- F: __dxlog_file2,
790
- L: 303,
791
- S: this,
792
- C: (f, a) => f(...a)
793
- });
794
- const pushedTrackData = await this._pushTrackInBulk({
795
- ctx,
796
- peerConnection: this.session.peerConnection,
797
- transceiver,
798
- sessionId: this.session.sessionId,
799
- trackName: stableId
800
- });
801
- invariant2(pushedTrackData, void 0, {
802
- F: __dxlog_file2,
803
- L: 312,
804
- S: this,
805
- A: [
806
- "pushedTrackData",
807
- ""
808
- ]
809
- });
810
- const parameters = transceiver.sender.getParameters();
811
- encodings.forEach((encoding, i) => {
812
- const existing = parameters.encodings[i];
813
- parameters.encodings[i] = {
814
- ...existing,
815
- ...encoding
816
- };
817
- });
818
- transceiver.sender.setParameters(parameters).catch((err) => log2.catch(err, void 0, {
819
- F: __dxlog_file2,
820
- L: 319,
821
- S: this,
822
- C: (f, a) => f(...a)
823
- }));
824
- return pushedTrackData;
825
- }
826
- // TODO(mykola): Add retry logic if the tracks fails to pull.
827
- async _pullTrackInBulk({ peerConnection, sessionId, trackData, ctx }) {
828
- let mid = "";
829
- log2("pulling track", {
830
- trackName: trackData.trackName
831
- }, {
832
- F: __dxlog_file2,
833
- L: 337,
834
- S: this,
835
- C: (f, a) => f(...a)
836
- });
837
- const pulledTrackPromise = this.pullTrackDispatcher.doBulkRequest(trackData, (tracks) => this.taskScheduler.schedule(async () => {
838
- const newTrackResponse = await this._fetch(`/sessions/${sessionId}/tracks/new?PULLING`, {
839
- method: "POST",
840
- body: JSON.stringify({
841
- tracks
842
- })
843
- });
844
- if (newTrackResponse.errorCode) {
845
- throw new Error(newTrackResponse.errorDescription);
846
- }
847
- invariant2(newTrackResponse.tracks, void 0, {
848
- F: __dxlog_file2,
849
- L: 350,
850
- S: this,
851
- A: [
852
- "newTrackResponse.tracks",
853
- ""
854
- ]
855
- });
856
- const trackMap = tracks.reduce((acc, track) => {
857
- const pulledTrackData = newTrackResponse.tracks?.find((t) => t.trackName === track.trackName && t.sessionId === track.sessionId);
858
- if (pulledTrackData && pulledTrackData.mid) {
859
- acc.set(track, {
860
- mid: pulledTrackData.mid,
861
- resolvedTrack: resolveTrack(peerConnection, (t) => t.mid === pulledTrackData.mid)
862
- });
863
- }
864
- return acc;
865
- }, /* @__PURE__ */ new Map());
866
- if (newTrackResponse.requiresImmediateRenegotiation) {
867
- await peerConnection.setRemoteDescription(new RTCSessionDescription(newTrackResponse.sessionDescription));
868
- const answer = await peerConnection.createAnswer();
869
- await peerConnection.setLocalDescription(answer);
870
- const renegotiationResponse = await this._fetch(`/sessions/${sessionId}/renegotiate`, {
871
- method: "PUT",
872
- body: JSON.stringify({
873
- sessionDescription: {
874
- type: "answer",
875
- sdp: peerConnection.currentLocalDescription?.sdp
876
- }
877
- })
878
- });
879
- if (renegotiationResponse.errorCode) {
880
- throw new Error(renegotiationResponse.errorDescription);
881
- } else {
882
- await peerConnectionIsConnected(peerConnection);
883
- }
884
- }
885
- return {
886
- trackMap
887
- };
888
- })).then(({ trackMap }) => {
889
- const trackInfo = trackMap.get(trackData);
890
- if (trackInfo) {
891
- return trackInfo.resolvedTrack.then((track) => {
892
- mid = trackInfo.mid;
893
- return track;
894
- }).catch((err) => log2.catch(err, void 0, {
895
- F: __dxlog_file2,
896
- L: 402,
897
- S: this,
898
- C: (f, a) => f(...a)
899
- }));
900
- } else {
901
- log2.error("missing track info", void 0, {
902
- F: __dxlog_file2,
903
- L: 404,
904
- S: this,
905
- C: (f, a) => f(...a)
906
- });
907
- }
908
- });
909
- const onDispose = async () => {
910
- if (mid) {
911
- log2("closing pulled track ", trackData.trackName, {
912
- F: __dxlog_file2,
913
- L: 410,
914
- S: this,
915
- C: (f, a) => f(...a)
916
- });
917
- await this._closeTrackInBulk(peerConnection, mid, sessionId);
918
- mid = "";
919
- }
920
- };
921
- this._ctx.onDispose(() => onDispose());
922
- ctx?.onDispose(() => onDispose());
923
- return pulledTrackPromise;
924
- }
925
- async pullTrack({ ctx, trackData }) {
926
- await this.waitUntilOpen();
927
- invariant2(this.session, void 0, {
928
- F: __dxlog_file2,
929
- L: 431,
930
- S: this,
931
- A: [
932
- "this.session",
933
- ""
934
- ]
935
- });
936
- const session = this.session;
937
- return this._pullTrackInBulk({
938
- peerConnection: session.peerConnection,
939
- sessionId: session.sessionId,
940
- trackData,
941
- ctx
942
- });
943
- }
944
- async _closeTrackInBulk(peerConnection, mid, sessionId) {
945
- const transceiver = peerConnection.getTransceivers().find((t) => t.mid === mid);
946
- if (peerConnection.connectionState !== "connected" || transceiver === void 0) {
947
- return;
948
- }
949
- await this.closeTrackDispatcher.doBulkRequest({
950
- mid
951
- }, (mids) => this.taskScheduler.schedule(async () => {
952
- transceiver.stop();
953
- const activeTransceivers = peerConnection.getTransceivers().filter((t) => t.mid !== mid && t.direction !== "stopped");
954
- let requestBody;
955
- if (activeTransceivers.length > 0) {
956
- const offer = await peerConnection.createOffer();
957
- await peerConnection.setLocalDescription(offer);
958
- requestBody = {
959
- tracks: mids,
960
- sessionDescription: {
961
- sdp: peerConnection.localDescription?.sdp,
962
- type: "offer"
963
- },
964
- force: false
965
- };
966
- } else {
967
- requestBody = {
968
- tracks: mids,
969
- force: true
970
- };
971
- }
972
- const response = await this._fetch(`/sessions/${sessionId}/tracks/close`, {
973
- method: "PUT",
974
- body: JSON.stringify(requestBody)
975
- });
976
- if (requestBody.sessionDescription) {
977
- await peerConnection.setRemoteDescription(new RTCSessionDescription(response.sessionDescription));
978
- }
979
- }));
980
- }
981
- };
982
- var resolveTrack = async (peerConnection, compare, timeout = NETWORK_TIMEOUT) => new Promise((resolve, reject) => {
983
- setTimeout(reject, timeout);
984
- const handler = () => {
985
- const transceiver = peerConnection.getTransceivers().find(compare);
986
- if (transceiver) {
987
- resolve(transceiver.receiver.track);
988
- peerConnection.removeEventListener("track", handler);
989
- }
990
- };
991
- peerConnection.addEventListener("track", handler);
992
- });
993
- var peerConnectionIsConnected = async (peerConnection) => {
994
- if (peerConnection.connectionState !== "connected") {
995
- const connected = new Promise((resolve, reject) => {
996
- const timeout = setTimeout(() => {
997
- peerConnection.removeEventListener("connectionstatechange", connectionStateChangeHandler);
998
- reject(new Error("Connection timeout"));
999
- }, NETWORK_TIMEOUT);
1000
- const connectionStateChangeHandler = () => {
1001
- if (peerConnection.connectionState === "connected") {
1002
- peerConnection.removeEventListener("connectionstatechange", connectionStateChangeHandler);
1003
- clearTimeout(timeout);
1004
- resolve(void 0);
1005
- }
1006
- };
1007
- peerConnection.addEventListener("connectionstatechange", connectionStateChangeHandler);
1008
- });
1009
- await connected;
1010
- }
1011
- };
1012
-
1013
- // packages/plugins/plugin-thread/src/calls/util/media.ts
1014
- import { log as log3 } from "@dxos/log";
1015
- var __dxlog_file3 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/calls/util/media.ts";
1016
- var getUserMediaTrack = async (kind, constraints = {}, deviceList) => {
1017
- deviceList ??= (await getDeviceList()).filter((device) => device.kind === kind);
1018
- const firstDevice = deviceList[0];
1019
- if (!firstDevice) {
1020
- throw new Error("No devices found");
1021
- }
1022
- return acquireTrack(firstDevice, constraints);
1023
- };
1024
- var acquireTrack = async (device, constraints) => {
1025
- const { deviceId, label } = device;
1026
- log3.info(`requesting ${label}`, void 0, {
1027
- F: __dxlog_file3,
1028
- L: 23,
1029
- S: void 0,
1030
- C: (f, a) => f(...a)
1031
- });
1032
- const mediaStream = await navigator.mediaDevices.getUserMedia(device.kind === "videoinput" ? {
1033
- video: {
1034
- ...constraints,
1035
- deviceId
1036
- }
1037
- } : {
1038
- audio: {
1039
- ...constraints,
1040
- deviceId
1041
- }
1042
- });
1043
- return device.kind === "videoinput" ? mediaStream.getVideoTracks()[0] : mediaStream.getAudioTracks()[0];
1044
- };
1045
- var getDeviceList = () => navigator.mediaDevices.enumerateDevices();
1046
- var SCREENSHARE_CONSTRAINTS = {
1047
- video: {
1048
- width: {
1049
- max: 1920
1050
- },
1051
- height: {
1052
- max: 1080
1053
- },
1054
- frameRate: {
1055
- max: 10
1056
- }
1057
- }
1058
- };
1059
- var getScreenshare = async ({ contentHint }) => {
1060
- const ms = await navigator.mediaDevices.getDisplayMedia(SCREENSHARE_CONSTRAINTS);
1061
- ms.getVideoTracks().forEach((track) => {
1062
- if (contentHint && "contentHint" in track) {
1063
- track.contentHint = contentHint;
1064
- }
1065
- });
1066
- return ms;
1067
- };
1068
-
1069
- // packages/plugins/plugin-thread/src/calls/util/stub-media-streams.ts
1070
- import { waitForCondition, scheduleTaskInterval as scheduleTaskInterval2 } from "@dxos/async";
1071
- import { cancelWithContext } from "@dxos/context";
1072
- import { invariant as invariant3 } from "@dxos/invariant";
1073
- var __dxlog_file4 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/calls/util/stub-media-streams.ts";
1074
- var createBlackCanvasStreamTrack = async ({ ctx, width, height }) => {
1075
- const canvas = document.createElement("canvas");
1076
- canvas.width = width;
1077
- canvas.height = height;
1078
- const canvasCtx = canvas.getContext("2d");
1079
- invariant3(canvasCtx, void 0, {
1080
- F: __dxlog_file4,
1081
- L: 28,
1082
- S: void 0,
1083
- A: [
1084
- "canvasCtx",
1085
- ""
1086
- ]
1087
- });
1088
- const drawFrame = () => {
1089
- canvasCtx.fillStyle = "black";
1090
- canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
1091
- };
1092
- scheduleTaskInterval2(ctx, async () => drawFrame(), 1e3);
1093
- const track = canvas.captureStream().getVideoTracks()[0];
1094
- drawFrame();
1095
- await cancelWithContext(ctx, waitForCondition({
1096
- condition: () => track.readyState === "live",
1097
- timeout: 1e3
1098
- }));
1099
- return track;
1100
- };
1101
- var createInaudibleAudioStreamTrack = async ({ ctx }) => {
1102
- const audioContext = new window.AudioContext();
1103
- const oscillator = audioContext.createOscillator();
1104
- oscillator.type = "triangle";
1105
- oscillator.frequency.setValueAtTime(0.1, audioContext.currentTime);
1106
- const gainNode = audioContext.createGain();
1107
- gainNode.gain.setValueAtTime(0, audioContext.currentTime);
1108
- oscillator.connect(gainNode);
1109
- const destination = audioContext.createMediaStreamDestination();
1110
- gainNode.connect(destination);
1111
- oscillator.start();
1112
- ctx.onDispose(async () => {
1113
- oscillator.disconnect();
1114
- oscillator.stop();
1115
- await audioContext.close();
1116
- });
1117
- return destination.stream.getAudioTracks()[0];
1118
- };
1119
-
1120
- // packages/plugins/plugin-thread/src/calls/speaking-monitor.ts
1121
- import { DeferredTask as DeferredTask2, Event as Event2, sleep } from "@dxos/async";
1122
- import { Resource as Resource3 } from "@dxos/context";
1123
- var NOT_SPEAKING_AFTER = 500;
1124
- var START_SPEAKING_THRESHOLD = 0.05;
1125
- var CONTINUE_SPEAKING_THRESHOLD = 0.02;
1126
- var MIN_EVENT_INTERVAL = 100;
1127
- var SpeakingMonitor = class extends Resource3 {
1128
- constructor(_mediaStreamTrack) {
1129
- super(), this._mediaStreamTrack = _mediaStreamTrack, this.speakingChanged = new Event2(), this._isSpeaking = false, this._lastEventTime = 0;
1130
- }
1131
- get isSpeaking() {
1132
- return this._isSpeaking;
1133
- }
1134
- async _open() {
1135
- this._deferredUpdate = new DeferredTask2(this._ctx, async () => this._emitSpeakingChanged());
1136
- let timeout;
1137
- const cleanup = monitorAudioLevel({
1138
- mediaStreamTrack: this._mediaStreamTrack,
1139
- onMeasure: (vol) => {
1140
- const audioLevelAboveThreshold = vol > (this._isSpeaking ? CONTINUE_SPEAKING_THRESHOLD : START_SPEAKING_THRESHOLD);
1141
- if (audioLevelAboveThreshold) {
1142
- clearTimeout(timeout);
1143
- timeout = void 0;
1144
- if (!this._isSpeaking) {
1145
- this._isSpeaking = true;
1146
- this._deferredUpdate?.schedule();
1147
- }
1148
- } else if (timeout === void 0) {
1149
- timeout = setTimeout(() => {
1150
- this._isSpeaking = false;
1151
- timeout = void 0;
1152
- this._deferredUpdate?.schedule();
1153
- }, NOT_SPEAKING_AFTER);
1154
- }
1155
- }
1156
- });
1157
- this._ctx.onDispose(() => {
1158
- cleanup();
1159
- clearTimeout(timeout);
1160
- });
1161
- }
1162
- /**
1163
- * Emits the speaking changed event with debouncing based on timing.
1164
- */
1165
- async _emitSpeakingChanged() {
1166
- const timeSinceLastEvent = Date.now() - this._lastEventTime;
1167
- const timeToNextEvent = MIN_EVENT_INTERVAL - timeSinceLastEvent;
1168
- if (timeToNextEvent > 0) {
1169
- await sleep(timeToNextEvent);
1170
- }
1171
- this._lastEventTime = Date.now();
1172
- this.speakingChanged.emit(this._isSpeaking);
1173
- }
1174
- };
1175
-
1176
- // packages/plugins/plugin-thread/src/calls/media-manager.ts
1177
- import { DeferredTask as DeferredTask3, Event as Event3, sleep as sleep2, synchronized as synchronized2 } from "@dxos/async";
1178
- import { cancelWithContext as cancelWithContext2, Resource as Resource4 } from "@dxos/context";
1179
- import { log as log4 } from "@dxos/log";
1180
- function _ts_decorate2(decorators, target, key, desc) {
1181
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1182
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1183
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1184
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1185
- }
1186
- var __dxlog_file5 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/calls/media-manager.ts";
1187
- var VIDEO_WIDTH = 1280;
1188
- var VIDEO_HEIGHT = 720;
1189
- var MAX_WEB_CAM_FRAMERATE = 24;
1190
- var MAX_WEB_CAM_BITRATE = 12e5;
1191
- var RETRY_INTERVAL = 500;
1192
- var MediaManager = class extends Resource4 {
1193
- constructor() {
1194
- super(...arguments);
1195
- this.stateUpdated = new Event3();
1196
- this._state = {
1197
- pulledVideoStreams: {},
1198
- pulledAudioTracks: {}
1199
- };
1200
- this._speakingMonitor = void 0;
1201
- this._trackToReconcile = [];
1202
- this._blackCanvasStreamTrack = void 0;
1203
- this._inaudibleAudioStreamTrack = void 0;
1204
- this._pushTracksTask = void 0;
1205
- this._pullTracksTask = void 0;
1206
- }
1207
- get isSpeaking() {
1208
- return this._speakingMonitor?.isSpeaking;
1209
- }
1210
- /**
1211
- * @internal
1212
- */
1213
- _getState() {
1214
- return this._state;
1215
- }
1216
- async _open() {
1217
- this._blackCanvasStreamTrack = await createBlackCanvasStreamTrack({
1218
- ctx: this._ctx,
1219
- width: VIDEO_WIDTH,
1220
- height: VIDEO_HEIGHT
1221
- });
1222
- this._state.videoTrack = this._blackCanvasStreamTrack;
1223
- this._state.videoStream = new MediaStream();
1224
- this._state.videoStream.addTrack(this._state.videoTrack);
1225
- this._inaudibleAudioStreamTrack = await createInaudibleAudioStreamTrack({
1226
- ctx: this._ctx
1227
- });
1228
- this._state.audioTrack = this._inaudibleAudioStreamTrack;
1229
- this._pushTracksTask = new DeferredTask3(this._ctx, async () => {
1230
- await this._pushTracks();
1231
- });
1232
- this._pullTracksTask = new DeferredTask3(this._ctx, async () => {
1233
- await this._reconcilePulledMedia();
1234
- });
1235
- }
1236
- async _close() {
1237
- void this._speakingMonitor?.close();
1238
- this._state.videoTrack && this._state.videoStream?.removeTrack(this._state.videoTrack);
1239
- this._state.audioTrack?.stop();
1240
- this._state.videoTrack?.stop();
1241
- this._state.screenshareTrack?.stop();
1242
- this._pushTracksTask = void 0;
1243
- this._pullTracksTask = void 0;
1244
- }
1245
- async join(serviceConfig) {
1246
- this._state.peer = new CallsServicePeer(serviceConfig);
1247
- await this._state.peer.open();
1248
- this._pushTracksTask.schedule();
1249
- }
1250
- async leave() {
1251
- await Promise.all(Object.values(this._state.pulledAudioTracks).map(({ ctx }) => ctx.dispose()));
1252
- await Promise.all(Object.values(this._state.pulledVideoStreams).map(({ ctx }) => ctx.dispose()));
1253
- this._trackToReconcile = [];
1254
- await this._state.peer?.close();
1255
- this._state.peer = void 0;
1256
- this._state.pushedVideoTrack = void 0;
1257
- this._state.pushedAudioTrack = void 0;
1258
- this._state.pushedScreenshareTrack = void 0;
1259
- this._state.pulledAudioTracks = {};
1260
- this._state.pulledVideoStreams = {};
1261
- }
1262
- async turnVideoOn() {
1263
- this._state.videoStream.removeTrack(this._state.videoTrack);
1264
- this._state.videoTrack = await getUserMediaTrack("videoinput", {
1265
- width: VIDEO_WIDTH,
1266
- height: VIDEO_HEIGHT
1267
- });
1268
- this._state.videoStream.addTrack(this._state.videoTrack);
1269
- this._state.videoEnabled = true;
1270
- this.stateUpdated.emit(this._state);
1271
- this._pushTracksTask.schedule();
1272
- }
1273
- async turnVideoOff() {
1274
- if (this._state.videoTrack !== this._blackCanvasStreamTrack) {
1275
- this._state.videoStream.removeTrack(this._state.videoTrack);
1276
- this._state.videoTrack?.stop();
1277
- this._state.videoTrack = this._blackCanvasStreamTrack;
1278
- this._state.videoStream.addTrack(this._state.videoTrack);
1279
- }
1280
- this._state.videoEnabled = false;
1281
- this.stateUpdated.emit(this._state);
1282
- this._pushTracksTask.schedule();
1283
- }
1284
- // TODO(mykola): Change to `setAudioEnabled(enabled: boolean)`.
1285
- async turnAudioOn() {
1286
- void this._speakingMonitor?.close();
1287
- this._state.audioEnabled = true;
1288
- this._state.audioTrack = await getUserMediaTrack("audioinput", {
1289
- echoCancellation: true,
1290
- noiseSuppression: true,
1291
- autoGainControl: true,
1292
- sampleRate: 16e3
1293
- });
1294
- this.stateUpdated.emit(this._state);
1295
- this._pushTracksTask.schedule();
1296
- this._speakingMonitor = new SpeakingMonitor(this._state.audioTrack);
1297
- this._speakingMonitor.speakingChanged.on(this._ctx, () => this.stateUpdated.emit(this._state));
1298
- void this._speakingMonitor.open();
1299
- }
1300
- async turnAudioOff() {
1301
- void this._speakingMonitor?.close();
1302
- this._speakingMonitor = void 0;
1303
- if (this._state.audioTrack !== this._inaudibleAudioStreamTrack) {
1304
- this._state.audioTrack?.stop();
1305
- this._state.audioTrack = this._inaudibleAudioStreamTrack;
1306
- }
1307
- this._state.audioEnabled = false;
1308
- this.stateUpdated.emit(this._state);
1309
- this._pushTracksTask.schedule();
1310
- }
1311
- async turnScreenshareOn() {
1312
- const ms = await getScreenshare({
1313
- contentHint: "text"
1314
- });
1315
- this._state.screenshareVideoStream = ms;
1316
- this._state.screenshareTrack = ms.getVideoTracks()[0];
1317
- this._state.screenshareEnabled = true;
1318
- this.stateUpdated.emit(this._state);
1319
- this._pushTracksTask.schedule();
1320
- }
1321
- async turnScreenshareOff() {
1322
- this._state.screenshareEnabled = false;
1323
- this._state.screenshareTrack?.stop();
1324
- this._state.screenshareTrack = void 0;
1325
- this.stateUpdated.emit(this._state);
1326
- this._pushTracksTask.schedule();
1327
- }
1328
- /**
1329
- * @internal
1330
- */
1331
- _schedulePullTracks(tracks) {
1332
- if (!tracks || this._trackToReconcile.every((name) => tracks.includes(name)) && this._trackToReconcile.length === tracks.length) {
1333
- return;
1334
- }
1335
- this._trackToReconcile = tracks;
1336
- this._pullTracksTask.schedule();
1337
- }
1338
- async _reconcilePulledMedia() {
1339
- log4("reconciling tracks", void 0, {
1340
- F: __dxlog_file5,
1341
- L: 215,
1342
- S: this,
1343
- C: (f, a) => f(...a)
1344
- });
1345
- await cancelWithContext2(this._ctx, sleep2(800));
1346
- const trackNames = this._trackToReconcile;
1347
- const tracksToPull = trackNames.filter((name) => !this._state.pulledAudioTracks[name] && !this._state.pulledVideoStreams[name]);
1348
- const audioTracksToClose = Object.entries(this._state.pulledAudioTracks).filter(([key]) => !trackNames.some((name) => name === key));
1349
- const videoStreamsToClose = Object.entries(this._state.pulledVideoStreams).filter(([key]) => !trackNames.some((name) => name === key));
1350
- log4("reconciling tracks", {
1351
- trackNames,
1352
- tracksToPull,
1353
- videoStreamsToClose,
1354
- audioTracksToClose,
1355
- currentAudioTracks: Object.keys(this._state.pulledAudioTracks),
1356
- currentVideoStreams: Object.keys(this._state.pulledVideoStreams)
1357
- }, {
1358
- F: __dxlog_file5,
1359
- L: 234,
1360
- S: this,
1361
- C: (f, a) => f(...a)
1362
- });
1363
- await Promise.all(tracksToPull.map((name) => this._pullTrack(name)));
1364
- await Promise.all([
1365
- ...audioTracksToClose,
1366
- ...videoStreamsToClose
1367
- ].map(([_, { ctx }]) => ctx.dispose()));
1368
- log4("reconciled tracks", {
1369
- currentAudioTracks: Object.keys(this._state.pulledAudioTracks),
1370
- currentVideoStreams: Object.keys(this._state.pulledVideoStreams)
1371
- }, {
1372
- F: __dxlog_file5,
1373
- L: 249,
1374
- S: this,
1375
- C: (f, a) => f(...a)
1376
- });
1377
- this.stateUpdated.emit(this._state);
1378
- }
1379
- async _pushTracks() {
1380
- if (!this._state.peer?.isOpen) {
1381
- return;
1382
- }
1383
- let updated = false;
1384
- const [pushedVideoTrack, pushedAudioTrack, pushedScreenshareTrack] = await Promise.all([
1385
- this._pushTrack(this._state.videoTrack, this._state.pushedVideoTrack, [
1386
- {
1387
- maxFramerate: MAX_WEB_CAM_FRAMERATE,
1388
- maxBitrate: MAX_WEB_CAM_BITRATE
1389
- }
1390
- ]),
1391
- this._pushTrack(this._state.audioTrack, this._state.pushedAudioTrack, [
1392
- {
1393
- networkPriority: "high"
1394
- }
1395
- ]),
1396
- this._pushTrack(this._state.screenshareTrack, this._state.pushedScreenshareTrack)
1397
- ]);
1398
- if (pushedVideoTrack !== this._state.pushedVideoTrack) {
1399
- this._state.pushedVideoTrack = pushedVideoTrack;
1400
- updated = true;
1401
- }
1402
- if (pushedAudioTrack !== this._state.pushedAudioTrack) {
1403
- this._state.pushedAudioTrack = pushedAudioTrack;
1404
- updated = true;
1405
- }
1406
- if (pushedScreenshareTrack !== this._state.pushedScreenshareTrack) {
1407
- this._state.pushedScreenshareTrack = pushedScreenshareTrack;
1408
- updated = true;
1409
- }
1410
- if (!updated) {
1411
- return;
1412
- }
1413
- this.stateUpdated.emit(this._state);
1414
- }
1415
- async _pullTrack(name) {
1416
- const ctx = this._ctx.derive();
1417
- try {
1418
- const trackData = TrackNameCodec.decode(name);
1419
- const track = await this._state.peer.pullTrack({
1420
- trackData,
1421
- ctx
1422
- });
1423
- if (track?.readyState === "ended") {
1424
- throw new Error("Pulled track ended immediately");
1425
- }
1426
- switch (track?.kind) {
1427
- case "audio": {
1428
- this._state.pulledAudioTracks[name] = {
1429
- track,
1430
- ctx
1431
- };
1432
- ctx.onDispose(() => delete this._state.pulledAudioTracks[name]);
1433
- break;
1434
- }
1435
- case "video": {
1436
- const mediaStream = new MediaStream();
1437
- mediaStream.addTrack(track);
1438
- this._state.pulledVideoStreams[name] = {
1439
- stream: mediaStream,
1440
- ctx
1441
- };
1442
- ctx.onDispose(() => {
1443
- mediaStream.removeTrack(track);
1444
- track.stop();
1445
- delete this._state.pulledVideoStreams[name];
1446
- });
1447
- break;
1448
- }
1449
- default:
1450
- throw new Error(`Invalid track kind: ${track?.kind}`);
1451
- }
1452
- } catch (err) {
1453
- log4.verbose("failed to pull track", {
1454
- err,
1455
- name
1456
- }, {
1457
- F: __dxlog_file5,
1458
- L: 319,
1459
- S: this,
1460
- C: (f, a) => f(...a)
1461
- });
1462
- void ctx.dispose();
1463
- await cancelWithContext2(this._ctx, sleep2(RETRY_INTERVAL));
1464
- log4.verbose("retrying pull track", {
1465
- name
1466
- }, {
1467
- F: __dxlog_file5,
1468
- L: 322,
1469
- S: this,
1470
- C: (f, a) => f(...a)
1471
- });
1472
- this._pullTracksTask.schedule();
1473
- }
1474
- }
1475
- async _pushTrack(track, previousTrack, encodings) {
1476
- if (!track && !previousTrack) {
1477
- return;
1478
- }
1479
- return this._state.peer.pushTrack({
1480
- track: track ?? null,
1481
- previousTrack,
1482
- encodings
1483
- });
1484
- }
1485
- };
1486
- _ts_decorate2([
1487
- synchronized2
1488
- ], MediaManager.prototype, "join", null);
1489
- _ts_decorate2([
1490
- synchronized2
1491
- ], MediaManager.prototype, "leave", null);
1492
-
1493
- // packages/plugins/plugin-thread/src/calls/call-manager.ts
1494
- import { computed } from "@preact/signals-core";
1495
- import { Event as Event4, synchronized as synchronized3 } from "@dxos/async";
1496
- import { Resource as Resource5 } from "@dxos/context";
1497
- import { invariant as invariant4 } from "@dxos/invariant";
1498
- import { live } from "@dxos/live-object";
1499
- import { isNonNullable as isNonNullable2 } from "@dxos/util";
1500
- function _ts_decorate3(decorators, target, key, desc) {
1501
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
1502
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
1503
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
1504
- return c > 3 && r && Object.defineProperty(target, key, r), r;
1505
- }
1506
- var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/plugins/plugin-thread/src/calls/call-manager.ts";
1507
- var CallManager = class extends Resource5 {
1508
- /** @reactive */
1509
- get roomId() {
1510
- return this._state.call.roomId;
1511
- }
1512
- /** @reactive */
1513
- get raisedHand() {
1514
- return this._raisedHandSignal.value;
1515
- }
1516
- /** @reactive */
1517
- get speaking() {
1518
- return this._speakingSignal.value;
1519
- }
1520
- /** @reactive */
1521
- get joined() {
1522
- return this._joinedSignal.value;
1523
- }
1524
- /** @reactive */
1525
- get self() {
1526
- return this._state.call.self ?? {};
1527
- }
1528
- /** @reactive */
1529
- get tracks() {
1530
- return this._state.call.tracks ?? {};
1531
- }
1532
- /** @reactive */
1533
- get users() {
1534
- return this._state.call.users ?? [];
1535
- }
1536
- /** @reactive */
1537
- get media() {
1538
- return this._state.media;
1539
- }
1540
- /** @reactive */
1541
- get pulledAudioTracks() {
1542
- return Object.values(this._state.media.pulledAudioTracks).map((track) => track.track);
1543
- }
1544
- /** @reactive */
1545
- get state() {
1546
- return this._state;
1547
- }
1548
- /** @reactive */
1549
- getVideoStream(name) {
1550
- return name ? this._state.media.pulledVideoStreams[name]?.stream : void 0;
1551
- }
1552
- /** @reactive */
1553
- getActivity(key) {
1554
- return this._state.call.activities?.[key];
1555
- }
1556
- setRoomId(roomId) {
1557
- this._swarmSynchronizer._setRoomId(roomId);
1558
- }
1559
- setSpeaking(speaking) {
1560
- this._swarmSynchronizer.setSpeaking(speaking);
1561
- }
1562
- setRaisedHand(raisedHand) {
1563
- this._swarmSynchronizer.setRaisedHand(raisedHand);
1564
- }
1565
- setActivity(key, payload) {
1566
- this._swarmSynchronizer.setActivity(key, payload);
1567
- }
1568
- turnAudioOn() {
1569
- return this._mediaManager.turnAudioOn();
1570
- }
1571
- turnAudioOff() {
1572
- return this._mediaManager.turnAudioOff();
1573
- }
1574
- turnVideoOn() {
1575
- return this._mediaManager.turnVideoOn();
1576
- }
1577
- turnVideoOff() {
1578
- return this._mediaManager.turnVideoOff();
1579
- }
1580
- turnScreenshareOn() {
1581
- return this._mediaManager.turnScreenshareOn();
1582
- }
1583
- turnScreenshareOff() {
1584
- return this._mediaManager.turnScreenshareOff();
1585
- }
1586
- // TODO(burdon): Can this be mocked?
1587
- constructor(_client) {
1588
- super(), this._client = _client, this.callStateUpdated = new Event4(), this.mediaStateUpdated = new Event4(), this.left = new Event4(), this._state = live({
1589
- call: {},
1590
- media: {
1591
- pulledAudioTracks: {},
1592
- pulledVideoStreams: {}
1593
- }
1594
- }), this._raisedHandSignal = computed(() => this._state.call.raisedHand ?? false), this._speakingSignal = computed(() => this._state.call.speaking ?? false), this._joinedSignal = computed(() => this._state.call.joined ?? false);
1595
- this._client.config.getOrThrow("runtime.services.edge.url");
1596
- const networkService = this._client.services.services.NetworkService;
1597
- invariant4(networkService, "network service not found", {
1598
- F: __dxlog_file6,
1599
- L: 155,
1600
- S: this,
1601
- A: [
1602
- "networkService",
1603
- "'network service not found'"
1604
- ]
1605
- });
1606
- this._swarmSynchronizer = new CallSwarmSynchronizer({
1607
- networkService
1608
- });
1609
- this._mediaManager = new MediaManager();
1610
- }
1611
- async _open() {
1612
- await this._mediaManager.open();
1613
- await this._swarmSynchronizer.open();
1614
- const subscription = this._client.halo.identity.subscribe((identity) => {
1615
- if (identity) {
1616
- this._swarmSynchronizer._setIdentity(identity);
1617
- }
1618
- if (this._client.halo.device) {
1619
- this._swarmSynchronizer._setDevice(this._client.halo.device);
1620
- }
1621
- });
1622
- this._ctx.onDispose(() => subscription.unsubscribe());
1623
- this._swarmSynchronizer.stateUpdated.on(this._ctx, (state) => this._onCallStateUpdated(state));
1624
- this._mediaManager.stateUpdated.on(this._ctx, (state) => this._onMediaStateUpdated(state));
1625
- }
1626
- async _close() {
1627
- await this._swarmSynchronizer.leave();
1628
- await this._swarmSynchronizer.close();
1629
- await this._mediaManager.close();
1630
- }
1631
- async peek(roomId) {
1632
- const peers = await this._swarmSynchronizer.querySwarm(roomId);
1633
- return peers.length;
1634
- }
1635
- // TODO(mykola): Reconcile with _swarmSynchronizer.state.joined.
1636
- async join() {
1637
- this._swarmSynchronizer.setJoined(true);
1638
- await this._swarmSynchronizer.join();
1639
- await this._mediaManager.join({
1640
- iceServers: this._client.config.get("runtime.services.ice"),
1641
- apiBase: `${CALLS_URL}/api/calls`
1642
- });
1643
- }
1644
- async leave() {
1645
- this._swarmSynchronizer.setJoined(false);
1646
- await this._swarmSynchronizer.leave();
1647
- await this._mediaManager.leave();
1648
- this.roomId && this.left.emit(this.roomId);
1649
- }
1650
- _onCallStateUpdated(state) {
1651
- const tracksToPull = state.users?.filter((user) => user.joined && user.id !== state.self?.id)?.flatMap((user) => [
1652
- user.tracks?.video,
1653
- user.tracks?.audio,
1654
- user.tracks?.screenshare
1655
- ]).filter(isNonNullable2);
1656
- this._mediaManager._schedulePullTracks(tracksToPull);
1657
- this.callStateUpdated.emit(state);
1658
- this._updateState();
1659
- }
1660
- _onMediaStateUpdated(state) {
1661
- this._swarmSynchronizer.setTracks({
1662
- video: state.pushedVideoTrack ? TrackNameCodec.encode(state.pushedVideoTrack) : void 0,
1663
- audio: state.pushedAudioTrack ? TrackNameCodec.encode(state.pushedAudioTrack) : void 0,
1664
- screenshare: state.pushedScreenshareTrack ? TrackNameCodec.encode(state.pushedScreenshareTrack) : void 0,
1665
- videoEnabled: state.videoEnabled,
1666
- audioEnabled: state.audioEnabled,
1667
- screenshareEnabled: state.screenshareEnabled
1668
- });
1669
- const isSpeaking = this._mediaManager.isSpeaking ?? false;
1670
- this._swarmSynchronizer.setSpeaking(isSpeaking);
1671
- this.mediaStateUpdated.emit([
1672
- state,
1673
- isSpeaking
1674
- ]);
1675
- this._updateState();
1676
- }
1677
- /**
1678
- * Only this method is allowed to change state.
1679
- */
1680
- _updateState() {
1681
- this._state.call = this._swarmSynchronizer._getState();
1682
- this._state.media = this._mediaManager._getState();
1683
- }
1684
- };
1685
- _ts_decorate3([
1686
- synchronized3
1687
- ], CallManager.prototype, "join", null);
1688
- _ts_decorate3([
1689
- synchronized3
1690
- ], CallManager.prototype, "leave", null);
1691
-
1692
- export {
1693
- CALLS_URL,
1694
- codec,
1695
- TrackNameCodec,
1696
- CallSwarmSynchronizer,
1697
- monitorAudioLevel,
1698
- CallsServicePeer,
1699
- getUserMediaTrack,
1700
- getDeviceList,
1701
- getScreenshare,
1702
- createBlackCanvasStreamTrack,
1703
- createInaudibleAudioStreamTrack,
1704
- SpeakingMonitor,
1705
- MediaManager,
1706
- CallManager
1707
- };
1708
- //# sourceMappingURL=chunk-4H4A264L.mjs.map