@dxos/plugin-thread 0.8.4-main.abd8ff62ef → 0.8.4-main.bc2380dfbc

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 (431) hide show
  1. package/LICENSE +102 -5
  2. package/README.md +1 -1
  3. package/dist/lib/neutral/ChannelArticle-ACZD7YFT.mjs +28 -0
  4. package/dist/lib/neutral/ChannelArticle-ACZD7YFT.mjs.map +7 -0
  5. package/dist/lib/neutral/ChannelChat-6YTD5HWL.mjs +10 -0
  6. package/dist/lib/neutral/ThreadCompanion-NQWPS2H6.mjs +208 -0
  7. package/dist/lib/neutral/ThreadCompanion-NQWPS2H6.mjs.map +7 -0
  8. package/dist/lib/neutral/ThreadContainer-XYEPEOSD.mjs +61 -0
  9. package/dist/lib/neutral/ThreadContainer-XYEPEOSD.mjs.map +7 -0
  10. package/dist/lib/neutral/ThreadPlugin.mjs +80 -0
  11. package/dist/lib/neutral/ThreadPlugin.mjs.map +7 -0
  12. package/dist/lib/neutral/ThreadPlugin.node.mjs +40 -0
  13. package/dist/lib/neutral/ThreadPlugin.node.mjs.map +7 -0
  14. package/dist/lib/neutral/ThreadPlugin.workerd.mjs +24 -0
  15. package/dist/lib/neutral/ThreadPlugin.workerd.mjs.map +7 -0
  16. package/dist/lib/neutral/ThreadSettings-5MKTDK3A.mjs +15 -0
  17. package/dist/lib/neutral/ThreadSettings-5MKTDK3A.mjs.map +7 -0
  18. package/dist/lib/{browser/add-message-LRVGIHDH.mjs → neutral/add-message-FBIROBEZ.mjs} +8 -10
  19. package/dist/lib/neutral/add-message-FBIROBEZ.mjs.map +7 -0
  20. package/dist/lib/neutral/app-graph-builder-7Q6MA6RT.mjs +120 -0
  21. package/dist/lib/neutral/app-graph-builder-7Q6MA6RT.mjs.map +7 -0
  22. package/dist/lib/{browser/append-channel-message-CO3M6FSA.mjs → neutral/append-channel-message-FTFAD3PK.mjs} +5 -5
  23. package/dist/lib/neutral/append-channel-message-FTFAD3PK.mjs.map +7 -0
  24. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs +15 -0
  25. package/dist/lib/neutral/blueprint-definition-S3EBOH4R.mjs.map +7 -0
  26. package/dist/lib/neutral/blueprints/index.mjs +8 -0
  27. package/dist/lib/neutral/capabilities/index.mjs +25 -0
  28. package/dist/lib/neutral/capabilities/index.mjs.map +7 -0
  29. package/dist/lib/{browser/blueprints/index.mjs → neutral/chunk-5T5LPLBN.mjs} +4 -5
  30. package/dist/lib/neutral/chunk-5T5LPLBN.mjs.map +7 -0
  31. package/dist/lib/neutral/chunk-7GHUS3IX.mjs +20 -0
  32. package/dist/lib/neutral/chunk-7GHUS3IX.mjs.map +7 -0
  33. package/dist/lib/neutral/chunk-D5LGFCUY.mjs +55 -0
  34. package/dist/lib/neutral/chunk-D5LGFCUY.mjs.map +7 -0
  35. package/dist/lib/neutral/chunk-JLY4NVTA.mjs +38 -0
  36. package/dist/lib/neutral/chunk-JLY4NVTA.mjs.map +7 -0
  37. package/dist/lib/neutral/chunk-KRXHIW4P.mjs +164 -0
  38. package/dist/lib/neutral/chunk-KRXHIW4P.mjs.map +7 -0
  39. package/dist/lib/{browser/chunk-TPNZ43NB.mjs → neutral/chunk-PE7IH7EL.mjs} +86 -73
  40. package/dist/lib/neutral/chunk-PE7IH7EL.mjs.map +7 -0
  41. package/dist/lib/neutral/chunk-QFDT33VT.mjs +69 -0
  42. package/dist/lib/neutral/chunk-QFDT33VT.mjs.map +7 -0
  43. package/dist/lib/neutral/chunk-QMLVLKE3.mjs +8 -0
  44. package/dist/lib/neutral/chunk-QMLVLKE3.mjs.map +7 -0
  45. package/dist/lib/neutral/components/index.mjs +539 -0
  46. package/dist/lib/neutral/components/index.mjs.map +7 -0
  47. package/dist/lib/neutral/containers/index.mjs +15 -0
  48. package/dist/lib/neutral/containers/index.mjs.map +7 -0
  49. package/dist/lib/{browser/create-BTGLHLBA.mjs → neutral/create-OAQJ6LXN.mjs} +7 -10
  50. package/dist/lib/neutral/create-OAQJ6LXN.mjs.map +7 -0
  51. package/dist/lib/{browser/create-channel-ZXKSLHGN.mjs → neutral/create-channel-3E4FJ662.mjs} +4 -4
  52. package/dist/lib/neutral/create-channel-3E4FJ662.mjs.map +7 -0
  53. package/dist/lib/neutral/create-object-HIEWSBZB.mjs +27 -0
  54. package/dist/lib/neutral/create-object-HIEWSBZB.mjs.map +7 -0
  55. package/dist/lib/{browser/create-proposals-AV5CREPV.mjs → neutral/create-proposals-GRYZXRMV.mjs} +4 -4
  56. package/dist/lib/neutral/create-proposals-GRYZXRMV.mjs.map +7 -0
  57. package/dist/lib/{browser/delete-GLYEP7NE.mjs → neutral/delete-HCCG5RVR.mjs} +7 -9
  58. package/dist/lib/neutral/delete-HCCG5RVR.mjs.map +7 -0
  59. package/dist/lib/{browser/delete-message-RQ72ZY5D.mjs → neutral/delete-message-DHFRACB4.mjs} +6 -7
  60. package/dist/lib/neutral/delete-message-DHFRACB4.mjs.map +7 -0
  61. package/dist/lib/neutral/hooks/index.mjs +10 -0
  62. package/dist/lib/neutral/index.mjs +28 -0
  63. package/dist/lib/neutral/index.mjs.map +7 -0
  64. package/dist/lib/neutral/markdown-BUORNCPG.mjs +83 -0
  65. package/dist/lib/neutral/markdown-BUORNCPG.mjs.map +7 -0
  66. package/dist/lib/neutral/meta.json +1 -0
  67. package/dist/lib/neutral/meta.mjs +10 -0
  68. package/dist/lib/neutral/meta.mjs.map +7 -0
  69. package/dist/lib/{browser/on-create-space-SPE3QVFZ.mjs → neutral/on-create-space-OEBRKOAM.mjs} +5 -6
  70. package/dist/lib/neutral/on-create-space-OEBRKOAM.mjs.map +7 -0
  71. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs +13 -0
  72. package/dist/lib/neutral/operation-handler-RU6K2S4L.mjs.map +7 -0
  73. package/dist/lib/neutral/operations/index.mjs +8 -0
  74. package/dist/lib/neutral/operations/index.mjs.map +7 -0
  75. package/dist/lib/neutral/plugin.mjs +16 -0
  76. package/dist/lib/neutral/plugin.mjs.map +7 -0
  77. package/dist/lib/neutral/react-surface-XY23GVZH.mjs +76 -0
  78. package/dist/lib/neutral/react-surface-XY23GVZH.mjs.map +7 -0
  79. package/dist/lib/{browser/restore-VX7FLZOZ.mjs → neutral/restore-P4ZLXLF7.mjs} +5 -5
  80. package/dist/lib/neutral/restore-P4ZLXLF7.mjs.map +7 -0
  81. package/dist/lib/{browser/restore-message-D65NSWUA.mjs → neutral/restore-message-AUBOP2DF.mjs} +5 -5
  82. package/dist/lib/neutral/restore-message-AUBOP2DF.mjs.map +7 -0
  83. package/dist/lib/{browser/select-AT4L7EBU.mjs → neutral/select-LIVAMBCE.mjs} +6 -8
  84. package/dist/lib/neutral/select-LIVAMBCE.mjs.map +7 -0
  85. package/dist/lib/neutral/settings-HK4EB6TF.mjs +30 -0
  86. package/dist/lib/neutral/settings-HK4EB6TF.mjs.map +7 -0
  87. package/dist/lib/neutral/state-UU7VEAKV.mjs +22 -0
  88. package/dist/lib/neutral/state-UU7VEAKV.mjs.map +7 -0
  89. package/dist/lib/neutral/testing/index.mjs +58 -0
  90. package/dist/lib/neutral/testing/index.mjs.map +7 -0
  91. package/dist/lib/{browser/toggle-resolved-JD3D4WBZ.mjs → neutral/toggle-resolved-RQBDQZSV.mjs} +5 -5
  92. package/dist/lib/neutral/toggle-resolved-RQBDQZSV.mjs.map +7 -0
  93. package/dist/lib/{browser → neutral}/translations.mjs +2 -2
  94. package/dist/lib/neutral/translations.mjs.map +7 -0
  95. package/dist/lib/neutral/types/index.mjs +12 -0
  96. package/dist/lib/neutral/types/index.mjs.map +7 -0
  97. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs +54 -0
  98. package/dist/lib/neutral/undo-mappings-HOKL2L3M.mjs.map +7 -0
  99. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  100. package/dist/types/src/ThreadPlugin.node.d.ts.map +1 -1
  101. package/dist/types/src/ThreadPlugin.workerd.d.ts +4 -0
  102. package/dist/types/src/ThreadPlugin.workerd.d.ts.map +1 -0
  103. package/dist/types/src/capabilities/create-object.d.ts +11 -0
  104. package/dist/types/src/capabilities/create-object.d.ts.map +1 -0
  105. package/dist/types/src/capabilities/index.d.ts +7 -6
  106. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  107. package/dist/types/src/capabilities/markdown.d.ts +1 -1
  108. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  109. package/dist/types/src/capabilities/settings.d.ts.map +1 -1
  110. package/dist/types/src/components/Chat/Chat.d.ts +8 -1
  111. package/dist/types/src/components/Chat/Chat.d.ts.map +1 -1
  112. package/dist/types/src/components/CommentsPanel/CommentsThread.d.ts.map +1 -1
  113. package/dist/types/src/components/MessagePanel/MessagePanel.d.ts.map +1 -1
  114. package/dist/types/src/components/ThreadSettings/ThreadSettings.d.ts.map +1 -1
  115. package/dist/types/src/components/index.d.ts +0 -1
  116. package/dist/types/src/components/index.d.ts.map +1 -1
  117. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts +13 -0
  118. package/dist/types/src/containers/ChannelArticle/ChannelArticle.d.ts.map +1 -0
  119. package/dist/types/src/containers/{ChannelContainer/ChannelContainer.stories.d.ts → ChannelArticle/ChannelArticle.stories.d.ts} +4 -4
  120. package/dist/types/src/containers/ChannelArticle/ChannelArticle.stories.d.ts.map +1 -0
  121. package/dist/types/src/containers/ChannelArticle/index.d.ts +2 -0
  122. package/dist/types/src/containers/{CallDebugPanel → ChannelArticle}/index.d.ts.map +1 -1
  123. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts +4 -0
  124. package/dist/types/src/containers/ChannelChat/ChannelChat.d.ts.map +1 -1
  125. package/dist/types/src/containers/ThreadCompanion/ThreadCompanion.d.ts.map +1 -1
  126. package/dist/types/src/containers/index.d.ts +1 -3
  127. package/dist/types/src/containers/index.d.ts.map +1 -1
  128. package/dist/types/src/extensions/threads.d.ts +1 -1
  129. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  130. package/dist/types/src/hooks/index.d.ts +0 -4
  131. package/dist/types/src/hooks/index.d.ts.map +1 -1
  132. package/dist/types/src/index.d.ts +3 -5
  133. package/dist/types/src/index.d.ts.map +1 -1
  134. package/dist/types/src/meta.d.ts.map +1 -1
  135. package/dist/types/src/operations/add-message.d.ts +2 -2
  136. package/dist/types/src/operations/add-message.d.ts.map +1 -1
  137. package/dist/types/src/operations/append-channel-message.d.ts +2 -2
  138. package/dist/types/src/operations/append-channel-message.d.ts.map +1 -1
  139. package/dist/types/src/operations/create-channel.d.ts +2 -2
  140. package/dist/types/src/operations/create-channel.d.ts.map +1 -1
  141. package/dist/types/src/operations/create-proposals.d.ts +2 -2
  142. package/dist/types/src/operations/create-proposals.d.ts.map +1 -1
  143. package/dist/types/src/operations/create.d.ts +2 -2
  144. package/dist/types/src/operations/create.d.ts.map +1 -1
  145. package/dist/types/src/operations/delete-message.d.ts +2 -2
  146. package/dist/types/src/operations/delete-message.d.ts.map +1 -1
  147. package/dist/types/src/operations/delete.d.ts +2 -2
  148. package/dist/types/src/operations/delete.d.ts.map +1 -1
  149. package/dist/types/src/operations/index.d.ts +0 -1
  150. package/dist/types/src/operations/index.d.ts.map +1 -1
  151. package/dist/types/src/operations/on-create-space.d.ts +2 -2
  152. package/dist/types/src/operations/on-create-space.d.ts.map +1 -1
  153. package/dist/types/src/operations/restore-message.d.ts +2 -2
  154. package/dist/types/src/operations/restore-message.d.ts.map +1 -1
  155. package/dist/types/src/operations/restore.d.ts +2 -2
  156. package/dist/types/src/operations/restore.d.ts.map +1 -1
  157. package/dist/types/src/operations/select.d.ts +2 -2
  158. package/dist/types/src/operations/select.d.ts.map +1 -1
  159. package/dist/types/src/operations/toggle-resolved.d.ts +2 -2
  160. package/dist/types/src/operations/toggle-resolved.d.ts.map +1 -1
  161. package/dist/types/src/plugin.d.ts +4 -0
  162. package/dist/types/src/plugin.d.ts.map +1 -0
  163. package/dist/types/src/translations.d.ts.map +1 -1
  164. package/dist/types/src/types/ThreadCapabilities.d.ts +13 -0
  165. package/dist/types/src/types/ThreadCapabilities.d.ts.map +1 -0
  166. package/dist/types/src/{operations/definitions.d.ts → types/ThreadOperation.d.ts} +1 -1
  167. package/dist/types/src/types/ThreadOperation.d.ts.map +1 -0
  168. package/dist/types/src/types/index.d.ts +3 -1
  169. package/dist/types/src/types/index.d.ts.map +1 -1
  170. package/dist/types/src/types/types.d.ts +1 -1
  171. package/dist/types/src/types/types.d.ts.map +1 -1
  172. package/dist/types/src/util.d.ts +4 -1
  173. package/dist/types/src/util.d.ts.map +1 -1
  174. package/dist/types/tsconfig.tsbuildinfo +1 -1
  175. package/package.json +123 -99
  176. package/src/ThreadPlugin.node.ts +5 -50
  177. package/src/ThreadPlugin.test.ts +3 -3
  178. package/src/ThreadPlugin.tsx +6 -59
  179. package/src/ThreadPlugin.workerd.ts +20 -0
  180. package/src/blueprints/thread-blueprint.ts +1 -1
  181. package/src/capabilities/app-graph-builder.ts +18 -69
  182. package/src/capabilities/create-object.ts +29 -0
  183. package/src/capabilities/index.ts +1 -2
  184. package/src/capabilities/markdown.ts +1 -1
  185. package/src/capabilities/react-surface.tsx +4 -26
  186. package/src/capabilities/settings.ts +1 -3
  187. package/src/capabilities/undo-mappings.ts +1 -1
  188. package/src/components/Chat/Chat.tsx +52 -12
  189. package/src/components/CommentsPanel/CommentsPanel.stories.tsx +1 -1
  190. package/src/components/CommentsPanel/CommentsPanel.tsx +4 -4
  191. package/src/components/CommentsPanel/CommentsThread.tsx +2 -3
  192. package/src/components/MessagePanel/MessagePanel.tsx +7 -8
  193. package/src/components/ThreadSettings/ThreadSettings.tsx +0 -1
  194. package/src/components/index.ts +0 -1
  195. package/src/containers/{ChannelContainer/ChannelContainer.stories.tsx → ChannelArticle/ChannelArticle.stories.tsx} +10 -10
  196. package/src/containers/ChannelArticle/ChannelArticle.tsx +42 -0
  197. package/src/containers/ChannelArticle/index.ts +5 -0
  198. package/src/containers/ChannelChat/ChannelChat.tsx +12 -2
  199. package/src/containers/ThreadCompanion/ThreadCompanion.tsx +10 -12
  200. package/src/containers/index.ts +1 -3
  201. package/src/extensions/command.ts +1 -1
  202. package/src/extensions/threads.ts +2 -2
  203. package/src/hooks/analytics.ts +1 -1
  204. package/src/hooks/index.ts +0 -5
  205. package/src/index.ts +3 -10
  206. package/src/meta.ts +1 -2
  207. package/src/operations/add-message.ts +4 -4
  208. package/src/operations/append-channel-message.ts +20 -19
  209. package/src/operations/create-channel.ts +2 -2
  210. package/src/operations/create-proposals.ts +2 -2
  211. package/src/operations/create.ts +3 -3
  212. package/src/operations/delete-message.ts +4 -4
  213. package/src/operations/delete.ts +3 -3
  214. package/src/operations/index.ts +0 -2
  215. package/src/operations/on-create-space.ts +3 -3
  216. package/src/operations/restore-message.ts +3 -3
  217. package/src/operations/restore.ts +3 -3
  218. package/src/operations/select.ts +2 -2
  219. package/src/operations/toggle-resolved.ts +3 -3
  220. package/src/plugin.ts +11 -0
  221. package/src/translations.ts +2 -2
  222. package/src/types/ThreadCapabilities.ts +26 -0
  223. package/src/{operations/definitions.ts → types/ThreadOperation.ts} +5 -4
  224. package/src/types/index.ts +4 -1
  225. package/src/types/types.ts +0 -2
  226. package/src/util.ts +36 -4
  227. package/dist/lib/browser/add-message-LRVGIHDH.mjs.map +0 -7
  228. package/dist/lib/browser/append-channel-message-CO3M6FSA.mjs.map +0 -7
  229. package/dist/lib/browser/blueprints/index.mjs.map +0 -7
  230. package/dist/lib/browser/chunk-E4GG3NX2.mjs +0 -29
  231. package/dist/lib/browser/chunk-E4GG3NX2.mjs.map +0 -7
  232. package/dist/lib/browser/chunk-TPNZ43NB.mjs.map +0 -7
  233. package/dist/lib/browser/create-BTGLHLBA.mjs.map +0 -7
  234. package/dist/lib/browser/create-channel-ZXKSLHGN.mjs.map +0 -7
  235. package/dist/lib/browser/create-proposals-AV5CREPV.mjs.map +0 -7
  236. package/dist/lib/browser/delete-GLYEP7NE.mjs.map +0 -7
  237. package/dist/lib/browser/delete-message-RQ72ZY5D.mjs.map +0 -7
  238. package/dist/lib/browser/index.mjs +0 -1821
  239. package/dist/lib/browser/index.mjs.map +0 -7
  240. package/dist/lib/browser/meta.json +0 -1
  241. package/dist/lib/browser/on-create-space-SPE3QVFZ.mjs.map +0 -7
  242. package/dist/lib/browser/operations/index.mjs +0 -13
  243. package/dist/lib/browser/operations/index.mjs.map +0 -7
  244. package/dist/lib/browser/restore-VX7FLZOZ.mjs.map +0 -7
  245. package/dist/lib/browser/restore-message-D65NSWUA.mjs.map +0 -7
  246. package/dist/lib/browser/select-AT4L7EBU.mjs.map +0 -7
  247. package/dist/lib/browser/toggle-resolved-JD3D4WBZ.mjs.map +0 -7
  248. package/dist/lib/browser/translations.mjs.map +0 -7
  249. package/dist/lib/browser/types/index.mjs +0 -10
  250. package/dist/lib/node-esm/add-message-4EAQ2ZPI.mjs +0 -90
  251. package/dist/lib/node-esm/add-message-4EAQ2ZPI.mjs.map +0 -7
  252. package/dist/lib/node-esm/append-channel-message-F7KGBSWP.mjs +0 -41
  253. package/dist/lib/node-esm/append-channel-message-F7KGBSWP.mjs.map +0 -7
  254. package/dist/lib/node-esm/blueprints/index.mjs +0 -38
  255. package/dist/lib/node-esm/blueprints/index.mjs.map +0 -7
  256. package/dist/lib/node-esm/chunk-BVEZBGIY.mjs +0 -30
  257. package/dist/lib/node-esm/chunk-BVEZBGIY.mjs.map +0 -7
  258. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +0 -11
  259. package/dist/lib/node-esm/chunk-XKUMDYGR.mjs +0 -259
  260. package/dist/lib/node-esm/chunk-XKUMDYGR.mjs.map +0 -7
  261. package/dist/lib/node-esm/create-DEZFPN2Y.mjs +0 -56
  262. package/dist/lib/node-esm/create-DEZFPN2Y.mjs.map +0 -7
  263. package/dist/lib/node-esm/create-channel-6VHTC2OR.mjs +0 -20
  264. package/dist/lib/node-esm/create-channel-6VHTC2OR.mjs.map +0 -7
  265. package/dist/lib/node-esm/create-proposals-P5O2ICOL.mjs +0 -57
  266. package/dist/lib/node-esm/create-proposals-P5O2ICOL.mjs.map +0 -7
  267. package/dist/lib/node-esm/delete-QG45QLPY.mjs +0 -60
  268. package/dist/lib/node-esm/delete-QG45QLPY.mjs.map +0 -7
  269. package/dist/lib/node-esm/delete-message-PGNLB6TL.mjs +0 -56
  270. package/dist/lib/node-esm/delete-message-PGNLB6TL.mjs.map +0 -7
  271. package/dist/lib/node-esm/index.mjs +0 -1822
  272. package/dist/lib/node-esm/index.mjs.map +0 -7
  273. package/dist/lib/node-esm/meta.json +0 -1
  274. package/dist/lib/node-esm/on-create-space-TFBSHWQ4.mjs +0 -25
  275. package/dist/lib/node-esm/on-create-space-TFBSHWQ4.mjs.map +0 -7
  276. package/dist/lib/node-esm/operations/index.mjs +0 -14
  277. package/dist/lib/node-esm/operations/index.mjs.map +0 -7
  278. package/dist/lib/node-esm/restore-E27OAIFJ.mjs +0 -33
  279. package/dist/lib/node-esm/restore-E27OAIFJ.mjs.map +0 -7
  280. package/dist/lib/node-esm/restore-message-J3CH6NGI.mjs +0 -34
  281. package/dist/lib/node-esm/restore-message-J3CH6NGI.mjs.map +0 -7
  282. package/dist/lib/node-esm/select-UU6Q2XAB.mjs +0 -27
  283. package/dist/lib/node-esm/select-UU6Q2XAB.mjs.map +0 -7
  284. package/dist/lib/node-esm/toggle-resolved-VS6NKXL3.mjs +0 -37
  285. package/dist/lib/node-esm/toggle-resolved-VS6NKXL3.mjs.map +0 -7
  286. package/dist/lib/node-esm/translations.mjs +0 -91
  287. package/dist/lib/node-esm/translations.mjs.map +0 -7
  288. package/dist/lib/node-esm/types/index.mjs +0 -11
  289. package/dist/types/src/calls/call-manager.d.ts +0 -87
  290. package/dist/types/src/calls/call-manager.d.ts.map +0 -1
  291. package/dist/types/src/calls/call-swarm-synchronizer.d.ts +0 -66
  292. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +0 -1
  293. package/dist/types/src/calls/index.d.ts +0 -7
  294. package/dist/types/src/calls/index.d.ts.map +0 -1
  295. package/dist/types/src/calls/media-manager.d.ts +0 -60
  296. package/dist/types/src/calls/media-manager.d.ts.map +0 -1
  297. package/dist/types/src/calls/speaking-monitor.d.ts +0 -21
  298. package/dist/types/src/calls/speaking-monitor.d.ts.map +0 -1
  299. package/dist/types/src/calls/types.d.ts +0 -45
  300. package/dist/types/src/calls/types.d.ts.map +0 -1
  301. package/dist/types/src/calls/util/audio.d.ts +0 -6
  302. package/dist/types/src/calls/util/audio.d.ts.map +0 -1
  303. package/dist/types/src/calls/util/calls-service.d.ts +0 -77
  304. package/dist/types/src/calls/util/calls-service.d.ts.map +0 -1
  305. package/dist/types/src/calls/util/history-cache.d.ts +0 -11
  306. package/dist/types/src/calls/util/history-cache.d.ts.map +0 -1
  307. package/dist/types/src/calls/util/index.d.ts +0 -5
  308. package/dist/types/src/calls/util/index.d.ts.map +0 -1
  309. package/dist/types/src/calls/util/media.d.ts +0 -6
  310. package/dist/types/src/calls/util/media.d.ts.map +0 -1
  311. package/dist/types/src/calls/util/stub-media-streams.d.ts +0 -18
  312. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +0 -1
  313. package/dist/types/src/calls/util/task-scheduling.d.ts +0 -17
  314. package/dist/types/src/calls/util/task-scheduling.d.ts.map +0 -1
  315. package/dist/types/src/calls-service.stories.d.ts +0 -23
  316. package/dist/types/src/calls-service.stories.d.ts.map +0 -1
  317. package/dist/types/src/capabilities/call-manager.d.ts +0 -6
  318. package/dist/types/src/capabilities/call-manager.d.ts.map +0 -1
  319. package/dist/types/src/capabilities/react-root.d.ts +0 -9
  320. package/dist/types/src/capabilities/react-root.d.ts.map +0 -1
  321. package/dist/types/src/components/Call/Call.d.ts +0 -45
  322. package/dist/types/src/components/Call/Call.d.ts.map +0 -1
  323. package/dist/types/src/components/Call/Toolbar.d.ts +0 -16
  324. package/dist/types/src/components/Call/Toolbar.d.ts.map +0 -1
  325. package/dist/types/src/components/Call/index.d.ts +0 -3
  326. package/dist/types/src/components/Call/index.d.ts.map +0 -1
  327. package/dist/types/src/components/Lobby/Lobby.d.ts +0 -36
  328. package/dist/types/src/components/Lobby/Lobby.d.ts.map +0 -1
  329. package/dist/types/src/components/Lobby/index.d.ts +0 -2
  330. package/dist/types/src/components/Lobby/index.d.ts.map +0 -1
  331. package/dist/types/src/components/Media/AudioStream.d.ts +0 -6
  332. package/dist/types/src/components/Media/AudioStream.d.ts.map +0 -1
  333. package/dist/types/src/components/Media/VideoObject.d.ts +0 -15
  334. package/dist/types/src/components/Media/VideoObject.d.ts.map +0 -1
  335. package/dist/types/src/components/Media/VideoObject.stories.d.ts +0 -22
  336. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +0 -1
  337. package/dist/types/src/components/Media/index.d.ts +0 -3
  338. package/dist/types/src/components/Media/index.d.ts.map +0 -1
  339. package/dist/types/src/components/Participant/Participant.d.ts +0 -6
  340. package/dist/types/src/components/Participant/Participant.d.ts.map +0 -1
  341. package/dist/types/src/components/Participant/ParticipantGrid.d.ts +0 -11
  342. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +0 -1
  343. package/dist/types/src/components/Participant/index.d.ts +0 -3
  344. package/dist/types/src/components/Participant/index.d.ts.map +0 -1
  345. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts +0 -32
  346. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.d.ts.map +0 -1
  347. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +0 -178
  348. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +0 -1
  349. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts +0 -21
  350. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +0 -1
  351. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts +0 -12
  352. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.d.ts.map +0 -1
  353. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts +0 -164
  354. package/dist/types/src/components/ResponsiveGrid/ResponsivePanel.stories.d.ts.map +0 -1
  355. package/dist/types/src/components/ResponsiveGrid/index.d.ts +0 -4
  356. package/dist/types/src/components/ResponsiveGrid/index.d.ts.map +0 -1
  357. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts +0 -15
  358. package/dist/types/src/containers/CallDebugPanel/CallDebugPanel.d.ts.map +0 -1
  359. package/dist/types/src/containers/CallDebugPanel/index.d.ts +0 -2
  360. package/dist/types/src/containers/CallSidebar/CallSidebar.d.ts +0 -3
  361. package/dist/types/src/containers/CallSidebar/CallSidebar.d.ts.map +0 -1
  362. package/dist/types/src/containers/CallSidebar/index.d.ts +0 -2
  363. package/dist/types/src/containers/CallSidebar/index.d.ts.map +0 -1
  364. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts +0 -12
  365. package/dist/types/src/containers/ChannelContainer/ChannelContainer.d.ts.map +0 -1
  366. package/dist/types/src/containers/ChannelContainer/ChannelContainer.stories.d.ts.map +0 -1
  367. package/dist/types/src/containers/ChannelContainer/index.d.ts +0 -2
  368. package/dist/types/src/containers/ChannelContainer/index.d.ts.map +0 -1
  369. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +0 -2
  370. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +0 -1
  371. package/dist/types/src/hooks/useDebugMode.d.ts +0 -2
  372. package/dist/types/src/hooks/useDebugMode.d.ts.map +0 -1
  373. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts +0 -2
  374. package/dist/types/src/hooks/useInaudibleAudioStreamTrack.d.ts.map +0 -1
  375. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +0 -3
  376. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +0 -1
  377. package/dist/types/src/operations/definitions.d.ts.map +0 -1
  378. package/dist/types/src/types/capabilities.d.ts +0 -25
  379. package/dist/types/src/types/capabilities.d.ts.map +0 -1
  380. package/src/calls/call-manager.ts +0 -270
  381. package/src/calls/call-swarm-synchronizer.ts +0 -350
  382. package/src/calls/index.ts +0 -10
  383. package/src/calls/media-manager.ts +0 -378
  384. package/src/calls/speaking-monitor.ts +0 -85
  385. package/src/calls/types.ts +0 -74
  386. package/src/calls/util/audio.ts +0 -58
  387. package/src/calls/util/calls-service.ts +0 -582
  388. package/src/calls/util/history-cache.ts +0 -27
  389. package/src/calls/util/index.ts +0 -8
  390. package/src/calls/util/media.ts +0 -52
  391. package/src/calls/util/stub-media-streams.ts +0 -129
  392. package/src/calls/util/task-scheduling.ts +0 -92
  393. package/src/calls-service.stories.tsx +0 -230
  394. package/src/capabilities/call-manager.ts +0 -27
  395. package/src/capabilities/react-root.tsx +0 -20
  396. package/src/components/Call/Call.tsx +0 -93
  397. package/src/components/Call/Toolbar.tsx +0 -199
  398. package/src/components/Call/index.ts +0 -6
  399. package/src/components/Lobby/Lobby.tsx +0 -123
  400. package/src/components/Lobby/index.ts +0 -5
  401. package/src/components/Media/AudioStream.tsx +0 -67
  402. package/src/components/Media/VideoObject.stories.tsx +0 -59
  403. package/src/components/Media/VideoObject.tsx +0 -58
  404. package/src/components/Media/index.ts +0 -6
  405. package/src/components/Participant/Participant.tsx +0 -77
  406. package/src/components/Participant/ParticipantGrid.tsx +0 -88
  407. package/src/components/Participant/index.ts +0 -6
  408. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +0 -158
  409. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +0 -341
  410. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +0 -134
  411. package/src/components/ResponsiveGrid/ResponsivePanel.stories.tsx +0 -54
  412. package/src/components/ResponsiveGrid/ResponsivePanel.tsx +0 -31
  413. package/src/components/ResponsiveGrid/index.ts +0 -7
  414. package/src/containers/CallDebugPanel/CallDebugPanel.tsx +0 -173
  415. package/src/containers/CallDebugPanel/index.ts +0 -5
  416. package/src/containers/CallSidebar/CallSidebar.tsx +0 -18
  417. package/src/containers/CallSidebar/index.ts +0 -5
  418. package/src/containers/ChannelContainer/ChannelContainer.tsx +0 -223
  419. package/src/containers/ChannelContainer/index.ts +0 -5
  420. package/src/hooks/useBlackCanvasStreamTrack.tsx +0 -27
  421. package/src/hooks/useDebugMode.ts +0 -25
  422. package/src/hooks/useInaudibleAudioStreamTrack.tsx +0 -27
  423. package/src/hooks/useVideoStreamTrack.tsx +0 -36
  424. package/src/types/capabilities.ts +0 -37
  425. package/src/typings/peermetrics-webrtc-stats.d.ts +0 -46
  426. package/src/typings.d.ts +0 -8
  427. /package/dist/lib/{browser/chunk-J5LGTIGS.mjs.map → neutral/ChannelChat-6YTD5HWL.mjs.map} +0 -0
  428. /package/dist/lib/{browser/types → neutral/blueprints}/index.mjs.map +0 -0
  429. /package/dist/lib/{browser → neutral}/chunk-J5LGTIGS.mjs +0 -0
  430. /package/dist/lib/{node-esm/chunk-HSLMI22Q.mjs.map → neutral/chunk-J5LGTIGS.mjs.map} +0 -0
  431. /package/dist/lib/{node-esm/types → neutral/hooks}/index.mjs.map +0 -0
@@ -1,378 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { DeferredTask, Event, sleep, synchronized } from '@dxos/async';
6
- import { type Context, Resource, cancelWithContext } from '@dxos/context';
7
- import { invariant } from '@dxos/invariant';
8
- import { log } from '@dxos/log';
9
-
10
- import { SpeakingMonitor } from './speaking-monitor';
11
- import { type EncodedTrackName, TrackNameCodec, type TrackObject } from './types';
12
- import {
13
- type CallsServiceConfig,
14
- CallsServicePeer,
15
- createBlackCanvasStreamTrack,
16
- createInaudibleAudioStreamTrack,
17
- getScreenshare,
18
- getUserMediaTrack,
19
- } from './util';
20
-
21
- export type MediaState = {
22
- audioDeviceId?: string;
23
- audioEnabled?: boolean;
24
- audioTrack?: MediaStreamTrack;
25
-
26
- videoDeviceId?: string;
27
- videoEnabled?: boolean;
28
- videoTrack?: MediaStreamTrack;
29
- videoStream?: MediaStream;
30
-
31
- screenshareEnabled?: boolean;
32
- screenshareTrack?: MediaStreamTrack;
33
- screenshareVideoStream?: MediaStream;
34
-
35
- pushedVideoTrack?: TrackObject;
36
- pushedAudioTrack?: TrackObject;
37
- pushedScreenshareTrack?: TrackObject;
38
- peer?: CallsServicePeer;
39
-
40
- pulledAudioTracks: Record<EncodedTrackName, { track: MediaStreamTrack; ctx: Context }>;
41
- /**
42
- * Includes video feeds and screenshare feeds of other participants.
43
- */
44
- pulledVideoStreams: Record<EncodedTrackName, { stream: MediaStream; ctx: Context }>;
45
- };
46
-
47
- // TOOD(burdon): Hard coded.
48
- const VIDEO_WIDTH = 1280;
49
- const VIDEO_HEIGHT = 720;
50
- const MAX_WEB_CAM_FRAMERATE = 24;
51
- const MAX_WEB_CAM_BITRATE = 120_0000;
52
- const RETRY_INTERVAL = 100;
53
-
54
- export type MediaManagerProps = {
55
- serviceConfig: CallsServiceConfig;
56
- };
57
-
58
- const USE_INAUDIBLE_AUDIO = true;
59
-
60
- export class MediaManager extends Resource {
61
- public readonly stateUpdated = new Event<MediaState>();
62
-
63
- private readonly _state: MediaState = {
64
- pulledVideoStreams: {},
65
- pulledAudioTracks: {},
66
- };
67
-
68
- private _speakingMonitor?: SpeakingMonitor = undefined;
69
- private _trackToReconcile: EncodedTrackName[] = [];
70
- private _blackCanvasStreamTrack?: MediaStreamTrack = undefined;
71
- private _inaudibleAudioStreamTrack?: MediaStreamTrack = undefined;
72
- private _pushTracksTask?: DeferredTask = undefined;
73
- private _pullTracksTask?: DeferredTask = undefined;
74
-
75
- get isSpeaking() {
76
- return this._speakingMonitor?.isSpeaking;
77
- }
78
-
79
- /**
80
- * @internal
81
- */
82
- _getState(): MediaState {
83
- return this._state;
84
- }
85
-
86
- protected override async _open(): Promise<void> {
87
- this._blackCanvasStreamTrack = await createBlackCanvasStreamTrack({
88
- ctx: this._ctx,
89
- width: VIDEO_WIDTH,
90
- height: VIDEO_HEIGHT,
91
- });
92
-
93
- this._state.videoTrack = this._blackCanvasStreamTrack;
94
- this._state.videoStream = new MediaStream();
95
- this._state.videoStream.addTrack(this._state.videoTrack);
96
-
97
- if (USE_INAUDIBLE_AUDIO) {
98
- this._inaudibleAudioStreamTrack = await createInaudibleAudioStreamTrack({ ctx: this._ctx });
99
- this._state.audioTrack = this._inaudibleAudioStreamTrack;
100
- }
101
-
102
- this._pushTracksTask = new DeferredTask(this._ctx, async () => {
103
- await this._pushTracks();
104
- });
105
- this._pullTracksTask = new DeferredTask(this._ctx, async () => {
106
- await this._reconcilePulledMedia();
107
- });
108
- }
109
-
110
- protected override async _close(): Promise<void> {
111
- void this._speakingMonitor?.close();
112
- this._state.videoTrack && this._state.videoStream?.removeTrack(this._state.videoTrack);
113
- this._state.audioTrack?.stop();
114
- this._state.videoTrack?.stop();
115
- this._state.screenshareTrack?.stop();
116
- this._pushTracksTask = undefined;
117
- this._pullTracksTask = undefined;
118
- }
119
-
120
- @synchronized
121
- async join(serviceConfig: CallsServiceConfig): Promise<void> {
122
- this._state.peer = new CallsServicePeer(serviceConfig);
123
- await this._state.peer!.open();
124
- this._pushTracksTask!.schedule();
125
- }
126
-
127
- @synchronized
128
- async leave(): Promise<void> {
129
- await Promise.all(Object.values(this._state.pulledAudioTracks).map(({ ctx }) => ctx.dispose()));
130
- await Promise.all(Object.values(this._state.pulledVideoStreams).map(({ ctx }) => ctx.dispose()));
131
- this._trackToReconcile = [];
132
- await this._state.peer?.close();
133
- this._state.peer = undefined;
134
- this._state.pushedVideoTrack = undefined;
135
- this._state.pushedAudioTrack = undefined;
136
- this._state.pushedScreenshareTrack = undefined;
137
- this._state.pulledAudioTracks = {};
138
- this._state.pulledVideoStreams = {};
139
- }
140
-
141
- async turnVideoOn(): Promise<void> {
142
- this._state.videoStream!.removeTrack(this._state.videoTrack!);
143
- this._state.videoTrack = await getUserMediaTrack('videoinput', { width: VIDEO_WIDTH, height: VIDEO_HEIGHT });
144
- this._state.videoStream!.addTrack(this._state.videoTrack);
145
-
146
- this._state.videoEnabled = true;
147
- this.stateUpdated.emit(this._state);
148
- this._pushTracksTask!.schedule();
149
- }
150
-
151
- async turnVideoOff(): Promise<void> {
152
- if (this._state.videoTrack !== this._blackCanvasStreamTrack) {
153
- this._state.videoStream!.removeTrack(this._state.videoTrack!);
154
- this._state.videoTrack?.stop();
155
- this._state.videoTrack = this._blackCanvasStreamTrack;
156
- this._state.videoStream!.addTrack(this._state.videoTrack!);
157
- }
158
-
159
- this._state.videoEnabled = false;
160
- this.stateUpdated.emit(this._state);
161
- this._pushTracksTask!.schedule();
162
- }
163
-
164
- // TODO(mykola): Change to `setAudioEnabled(enabled: boolean)`.
165
- async turnAudioOn(): Promise<void> {
166
- void this._speakingMonitor?.close();
167
- this._state.audioEnabled = true;
168
- this._state.audioTrack = await getUserMediaTrack('audioinput', {
169
- echoCancellation: true,
170
- noiseSuppression: true,
171
- autoGainControl: true,
172
- sampleRate: 16_000,
173
- });
174
- this.stateUpdated.emit(this._state);
175
- this._pushTracksTask!.schedule();
176
- this._speakingMonitor = new SpeakingMonitor(this._state.audioTrack!);
177
- this._speakingMonitor.speakingChanged.on(this._ctx, () => this.stateUpdated.emit(this._state));
178
- void this._speakingMonitor.open();
179
- }
180
-
181
- async turnAudioOff(): Promise<void> {
182
- void this._speakingMonitor?.close();
183
- this._speakingMonitor = undefined;
184
- this._state.audioEnabled = false;
185
- if (USE_INAUDIBLE_AUDIO && this._state.audioTrack !== this._inaudibleAudioStreamTrack) {
186
- this._state.audioTrack?.stop();
187
- this._state.audioTrack = this._inaudibleAudioStreamTrack;
188
- } else {
189
- this._state.audioTrack?.stop();
190
- this._state.audioTrack = undefined;
191
- }
192
- this.stateUpdated.emit(this._state);
193
- this._pushTracksTask!.schedule();
194
- }
195
-
196
- async turnScreenshareOn(): Promise<void> {
197
- const ms = await getScreenshare({ contentHint: 'text' });
198
- this._state.screenshareVideoStream = ms;
199
- this._state.screenshareTrack = ms.getVideoTracks()[0];
200
- this._state.screenshareEnabled = true;
201
- this.stateUpdated.emit(this._state);
202
- this._pushTracksTask!.schedule();
203
- }
204
-
205
- async turnScreenshareOff(): Promise<void> {
206
- this._state.screenshareEnabled = false;
207
- this._state.screenshareTrack?.stop();
208
- this._state.screenshareTrack = undefined;
209
- this.stateUpdated.emit(this._state);
210
- this._pushTracksTask!.schedule();
211
- }
212
-
213
- /**
214
- * @internal
215
- */
216
- _schedulePullTracks(tracks?: EncodedTrackName[]): void {
217
- if (
218
- !tracks ||
219
- (this._trackToReconcile.every((name) => tracks.includes(name)) && this._trackToReconcile.length === tracks.length)
220
- ) {
221
- return;
222
- }
223
-
224
- this._trackToReconcile = tracks;
225
- this._pullTracksTask!.schedule();
226
- }
227
-
228
- private async _reconcilePulledMedia(): Promise<void> {
229
- log('reconciling tracks');
230
- // TODO(mykola): Currently cloudflare fails if you try to pull track immediately after pushing it.
231
- // Add retry logic, remove sleep.
232
- // Wait for cloudflare to process the track.
233
- await cancelWithContext(this._ctx, sleep(800));
234
- const trackNames = this._trackToReconcile;
235
- const tracksToPull = trackNames.filter(
236
- (name) => !this._state.pulledAudioTracks[name] && !this._state.pulledVideoStreams[name],
237
- );
238
-
239
- const audioTracksToClose = Object.entries(this._state.pulledAudioTracks).filter(
240
- ([key]) => !trackNames.some((name) => name === key),
241
- );
242
-
243
- const videoStreamsToClose = Object.entries(this._state.pulledVideoStreams).filter(
244
- ([key]) => !trackNames.some((name) => name === key),
245
- );
246
-
247
- log('reconciling tracks', {
248
- trackNames,
249
- tracksToPull,
250
- videoStreamsToClose,
251
- audioTracksToClose,
252
- currentAudioTracks: Object.keys(this._state.pulledAudioTracks),
253
- currentVideoStreams: Object.keys(this._state.pulledVideoStreams),
254
- });
255
-
256
- // Pull new tracks.
257
- const pullResults = await Promise.all(tracksToPull.map((name) => this._pullTrack(name)));
258
-
259
- // Close old tracks.
260
- await Promise.all([...audioTracksToClose, ...videoStreamsToClose].map(([_, { ctx }]) => ctx.dispose()));
261
-
262
- log('reconciled tracks', {
263
- currentAudioTracks: Object.keys(this._state.pulledAudioTracks),
264
- currentVideoStreams: Object.keys(this._state.pulledVideoStreams),
265
- });
266
-
267
- this.stateUpdated.emit(this._state);
268
- if (pullResults.some(({ shouldRetry }) => shouldRetry)) {
269
- await cancelWithContext(this._ctx, sleep(RETRY_INTERVAL));
270
- log.info('retrying pull tracks', { tracksToPull });
271
- invariant(this._pullTracksTask);
272
- this._pullTracksTask.schedule();
273
- }
274
- }
275
-
276
- private async _pushTracks(): Promise<void> {
277
- if (!this._state.peer?.isOpen) {
278
- return;
279
- }
280
-
281
- let updated = false;
282
- const [pushVideoResult, pushAudioResult, pushScreenshareResult] = await Promise.all([
283
- this._maybePushTrack(this._state.videoTrack, this._state.pushedVideoTrack, [
284
- { maxFramerate: MAX_WEB_CAM_FRAMERATE, maxBitrate: MAX_WEB_CAM_BITRATE },
285
- ]),
286
- this._maybePushTrack(this._state.audioTrack, this._state.pushedAudioTrack, [{ networkPriority: 'high' }]),
287
- this._maybePushTrack(this._state.screenshareTrack, this._state.pushedScreenshareTrack),
288
- ]);
289
-
290
- if (pushVideoResult.track !== this._state.pushedVideoTrack) {
291
- this._state.pushedVideoTrack = pushVideoResult.track;
292
- updated = true;
293
- }
294
- if (pushAudioResult.track !== this._state.pushedAudioTrack) {
295
- this._state.pushedAudioTrack = pushAudioResult.track;
296
- updated = true;
297
- }
298
- if (pushScreenshareResult.track !== this._state.pushedScreenshareTrack) {
299
- this._state.pushedScreenshareTrack = pushScreenshareResult.track;
300
- updated = true;
301
- }
302
-
303
- const shouldRetry = pushVideoResult.shouldRetry || pushAudioResult.shouldRetry || pushScreenshareResult.shouldRetry;
304
- if (updated) {
305
- this.stateUpdated.emit(this._state);
306
- }
307
-
308
- if (shouldRetry) {
309
- await cancelWithContext(this._ctx, sleep(RETRY_INTERVAL));
310
- log.info('retrying push tracks', { pushVideoResult, pushAudioResult, pushScreenshareResult });
311
- invariant(this._pushTracksTask);
312
- this._pushTracksTask.schedule();
313
- }
314
- }
315
-
316
- private async _pullTrack(name: EncodedTrackName): Promise<{ shouldRetry: boolean }> {
317
- const ctx = this._ctx.derive();
318
- try {
319
- const trackData = TrackNameCodec.decode(name);
320
- // We need to set mid here to `undefined`, because mid is peer specific.
321
- const track = await this._state.peer!.pullTrack({ trackData: { ...trackData, mid: undefined }, ctx });
322
- if (track?.readyState === 'ended') {
323
- throw new Error('Pulled track ended immediately');
324
- }
325
-
326
- switch (track?.kind) {
327
- case 'audio': {
328
- this._state.pulledAudioTracks[name] = { track, ctx };
329
- ctx.onDispose(() => delete this._state.pulledAudioTracks[name]);
330
- return { shouldRetry: false };
331
- }
332
- case 'video': {
333
- const mediaStream = new MediaStream();
334
- mediaStream.addTrack(track);
335
- this._state.pulledVideoStreams[name] = { stream: mediaStream, ctx };
336
- ctx.onDispose(() => {
337
- mediaStream.removeTrack(track);
338
- track.stop();
339
- delete this._state.pulledVideoStreams[name];
340
- });
341
- return { shouldRetry: false };
342
- }
343
- default:
344
- throw new Error(`Invalid track kind: ${track?.kind}`);
345
- }
346
- } catch (err) {
347
- log.info('failed to pull track', { err, name });
348
- void ctx.dispose();
349
- return { shouldRetry: true };
350
- }
351
- }
352
-
353
- private async _maybePushTrack(
354
- track?: MediaStreamTrack,
355
- previousTrack?: TrackObject,
356
- encodings?: RTCRtpEncodingParameters[],
357
- ): Promise<{ track?: TrackObject; shouldRetry?: boolean }> {
358
- if (!track && !previousTrack) {
359
- return { track: undefined };
360
- }
361
-
362
- const ctx = this._ctx.derive();
363
- try {
364
- return {
365
- track: await this._state.peer!.pushTrack({
366
- ctx,
367
- track: track ?? null,
368
- previousTrack,
369
- encodings,
370
- }),
371
- };
372
- } catch (err) {
373
- log.info('failed to push track', { err, track, previousTrack, encodings });
374
- void ctx.dispose();
375
- return { shouldRetry: true };
376
- }
377
- }
378
- }
@@ -1,85 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { DeferredTask, Event, sleep } from '@dxos/async';
6
- import { Resource } from '@dxos/context';
7
-
8
- import { monitorAudioLevel } from './util';
9
-
10
- const NOT_SPEAKING_AFTER = 500; // [ms]
11
- const START_SPEAKING_THRESHOLD = 0.05;
12
- const CONTINUE_SPEAKING_THRESHOLD = 0.02;
13
- const MIN_EVENT_INTERVAL = 100; // [ms]
14
-
15
- export class SpeakingMonitor extends Resource {
16
- /**
17
- * Event that is emitted when the user starts or stops speaking.
18
- * It is debounced to prevent rapid state changes.
19
- */
20
- public readonly speakingChanged = new Event<boolean>();
21
-
22
- /**
23
- * Real state of the user speaking.
24
- */
25
- private _isSpeaking = false;
26
- private _lastEventTime = 0;
27
- private _deferredUpdate?: DeferredTask | undefined;
28
-
29
- constructor(private readonly _mediaStreamTrack: MediaStreamTrack) {
30
- super();
31
- }
32
-
33
- get isSpeaking(): boolean {
34
- return this._isSpeaking;
35
- }
36
-
37
- protected override async _open(): Promise<void> {
38
- this._deferredUpdate = new DeferredTask(this._ctx, async () => this._emitSpeakingChanged());
39
-
40
- let timeout: NodeJS.Timeout | undefined;
41
- const cleanup = monitorAudioLevel({
42
- mediaStreamTrack: this._mediaStreamTrack,
43
- onMeasure: (vol) => {
44
- // Once the user has been determined to be speaking, we want
45
- // to lower the threshold because speech patterns don't always
46
- // kick up above 0.05.
47
- const audioLevelAboveThreshold =
48
- vol > (this._isSpeaking ? CONTINUE_SPEAKING_THRESHOLD : START_SPEAKING_THRESHOLD);
49
- if (audioLevelAboveThreshold) {
50
- // User is still speaking, clear timeout & reset.
51
- clearTimeout(timeout);
52
- timeout = undefined;
53
- if (!this._isSpeaking) {
54
- this._isSpeaking = true;
55
- this._deferredUpdate?.schedule();
56
- }
57
- } else if (timeout === undefined) {
58
- // User is not speaking and timeout is not set.
59
- timeout = setTimeout(() => {
60
- this._isSpeaking = false;
61
- timeout = undefined;
62
- this._deferredUpdate?.schedule();
63
- }, NOT_SPEAKING_AFTER);
64
- }
65
- },
66
- });
67
- this._ctx.onDispose(() => {
68
- cleanup();
69
- clearTimeout(timeout);
70
- });
71
- }
72
-
73
- /**
74
- * Emits the speaking changed event with debouncing based on timing.
75
- */
76
- private async _emitSpeakingChanged(): Promise<void> {
77
- const timeSinceLastEvent = Date.now() - this._lastEventTime;
78
- const timeToNextEvent = MIN_EVENT_INTERVAL - timeSinceLastEvent;
79
- if (timeToNextEvent > 0) {
80
- await sleep(timeToNextEvent);
81
- }
82
- this._lastEventTime = Date.now();
83
- this.speakingChanged.emit(this._isSpeaking);
84
- }
85
- }
@@ -1,74 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- import { invariant } from '@dxos/invariant';
6
- import { buf } from '@dxos/protocols/buf';
7
- import {
8
- type ActivitySchema,
9
- type UserState as UserStateProto,
10
- UserStateSchema,
11
- } from '@dxos/protocols/buf/dxos/edge/calls_pb';
12
-
13
- /**
14
- * Endpoint to the calls service.
15
- */
16
- export const CALLS_URL = 'https://calls-service.dxos.workers.dev';
17
-
18
- export type UserState = buf.MessageInitShape<typeof UserStateSchema>;
19
-
20
- export type ActivityState = buf.MessageInitShape<typeof ActivitySchema>;
21
-
22
- export const codec = {
23
- encode: (message: UserState): Uint8Array => {
24
- return buf.toBinary(UserStateSchema, buf.create(UserStateSchema, message));
25
- },
26
- decode: (message: Uint8Array): UserStateProto => {
27
- return buf.fromBinary(UserStateSchema, message);
28
- },
29
- };
30
-
31
- export type TrackObject = {
32
- location?: 'local' | 'remote';
33
- trackName?: string;
34
- sessionId?: string;
35
- mid?: string | null;
36
- };
37
-
38
- export type SessionDescription = {
39
- type: 'offer' | 'answer';
40
- sdp: string;
41
- };
42
-
43
- export interface ErrorResponse {
44
- errorCode?: string;
45
- errorDescription?: string;
46
- }
47
-
48
- export interface SessionResponse extends ErrorResponse {
49
- sessionId: string;
50
- sessionDescription: SessionDescription;
51
- }
52
-
53
- export interface TracksResponse extends ErrorResponse {
54
- sessionDescription: SessionDescription;
55
- requiresImmediateRenegotiation: boolean;
56
- tracks?: (TrackObject & ErrorResponse)[];
57
- }
58
-
59
- export interface RenegotiationResponse extends ErrorResponse {}
60
-
61
- export type EncodedTrackName = string & { __brand: 'EncodedTrackName' };
62
-
63
- export const TrackNameCodec = {
64
- encode: (trackData: TrackObject): EncodedTrackName => {
65
- invariant(trackData.sessionId);
66
- invariant(trackData.trackName);
67
- invariant(trackData.mid);
68
- return (trackData.sessionId + '/' + trackData.trackName + '/' + trackData.mid) as EncodedTrackName;
69
- },
70
- decode: (name: EncodedTrackName): TrackObject => {
71
- const [sessionId, trackName, mid] = name.split('/');
72
- return { sessionId, trackName, location: 'remote', mid };
73
- },
74
- };
@@ -1,58 +0,0 @@
1
- //
2
- // Copyright 2025 DXOS.org
3
- //
4
-
5
- export const monitorAudioLevel = ({
6
- mediaStreamTrack,
7
- intervalMs = 1000 / 10, // 12 fps.
8
- onMeasure,
9
- }: {
10
- mediaStreamTrack: MediaStreamTrack;
11
- intervalMs?: number;
12
- onMeasure: (value: number) => void;
13
- }) => {
14
- let timeout = -1;
15
- let interval = -1;
16
- const audioContext = new AudioContext();
17
- const stream = new MediaStream();
18
- stream.addTrack(mediaStreamTrack);
19
- const mediaStreamAudioSourceNode = audioContext.createMediaStreamSource(stream);
20
- const analyserNode = audioContext.createAnalyser();
21
- mediaStreamAudioSourceNode.connect(analyserNode);
22
- // Since we just need a rough approximation and will be measuring
23
- // frequently, we want to drop this down from the default of 2048.
24
- analyserNode.fftSize = 32;
25
-
26
- const pcmData = new Float32Array(analyserNode.fftSize);
27
- let peak = 0;
28
-
29
- interval = window.setInterval(() => {
30
- onMeasure(peak);
31
- peak = 0;
32
- }, intervalMs);
33
-
34
- const tick = () => {
35
- timeout = window.setTimeout(() => {
36
- analyserNode.getFloatTimeDomainData(pcmData);
37
- let sumSquares = 0.0;
38
- for (const amplitude of pcmData) {
39
- sumSquares += amplitude * amplitude;
40
- }
41
- const current = Math.sqrt(sumSquares / pcmData.length);
42
- if (current > peak) {
43
- peak = current;
44
- }
45
- tick();
46
- }, intervalMs);
47
- };
48
- tick();
49
-
50
- return () => {
51
- mediaStreamAudioSourceNode.disconnect();
52
- analyserNode.disconnect();
53
- void audioContext.close();
54
- clearInterval(interval);
55
- clearTimeout(timeout);
56
- stream.removeTrack(mediaStreamTrack);
57
- };
58
- };