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

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 (304) hide show
  1. package/dist/lib/browser/ChannelContainer-JI3ZRZ5S.mjs +17 -0
  2. package/dist/lib/browser/ChatContainer-6FVFME3R.mjs +16 -0
  3. package/dist/lib/browser/{app-graph-builder-AF3M7UWN.mjs → app-graph-builder-URVQHGMR.mjs} +32 -32
  4. package/dist/lib/browser/app-graph-builder-URVQHGMR.mjs.map +7 -0
  5. package/dist/lib/browser/blueprint-definition-TQ4JFMZZ.mjs +101 -0
  6. package/dist/lib/browser/blueprint-definition-TQ4JFMZZ.mjs.map +7 -0
  7. package/dist/lib/browser/{call-manager-XRRCAVLI.mjs → call-manager-4YFT4XA6.mjs} +8 -7
  8. package/dist/lib/{node-esm/call-manager-EI7FXRAU.mjs.map → browser/call-manager-4YFT4XA6.mjs.map} +1 -1
  9. package/dist/lib/browser/chunk-6LWKNZUV.mjs +377 -0
  10. package/dist/lib/browser/chunk-6LWKNZUV.mjs.map +7 -0
  11. package/dist/lib/browser/chunk-CBUNHCOE.mjs +23 -0
  12. package/dist/lib/browser/chunk-CBUNHCOE.mjs.map +7 -0
  13. package/dist/lib/browser/chunk-CFC7LEPD.mjs +18 -0
  14. package/dist/lib/browser/chunk-CFC7LEPD.mjs.map +7 -0
  15. package/dist/lib/browser/{chunk-GERVMFQW.mjs → chunk-CP7E2HRE.mjs} +2 -2
  16. package/dist/lib/browser/chunk-CP7E2HRE.mjs.map +7 -0
  17. package/dist/lib/browser/{chunk-ZJ7QBXK6.mjs → chunk-F36NHPJG.mjs} +47 -42
  18. package/dist/lib/browser/chunk-F36NHPJG.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-JGKMMI65.mjs → chunk-ISCHODBV.mjs} +54 -4
  20. package/dist/lib/browser/chunk-ISCHODBV.mjs.map +7 -0
  21. package/dist/lib/browser/chunk-J5LGTIGS.mjs +10 -0
  22. package/dist/lib/browser/{chunk-X5PIP5YR.mjs → chunk-KOBXMDCI.mjs} +74 -41
  23. package/dist/lib/browser/chunk-KOBXMDCI.mjs.map +7 -0
  24. package/dist/lib/browser/chunk-QM34EZQK.mjs +20 -0
  25. package/dist/lib/browser/chunk-QM34EZQK.mjs.map +7 -0
  26. package/dist/lib/browser/chunk-R5UOPOO7.mjs +142 -0
  27. package/dist/lib/browser/chunk-R5UOPOO7.mjs.map +7 -0
  28. package/dist/lib/browser/chunk-VIRD2QSK.mjs +611 -0
  29. package/dist/lib/browser/chunk-VIRD2QSK.mjs.map +7 -0
  30. package/dist/lib/browser/{chunk-TUFWPOVS.mjs → chunk-ZCW3NSDZ.mjs} +256 -161
  31. package/dist/lib/browser/chunk-ZCW3NSDZ.mjs.map +7 -0
  32. package/dist/lib/browser/index.mjs +48 -38
  33. package/dist/lib/browser/index.mjs.map +3 -3
  34. package/dist/lib/browser/{intent-resolver-DCY4P4OX.mjs → intent-resolver-YR6W4CRP.mjs} +33 -51
  35. package/dist/lib/browser/intent-resolver-YR6W4CRP.mjs.map +7 -0
  36. package/dist/lib/browser/{markdown-WZSXCEZJ.mjs → markdown-GSOBOXA7.mjs} +26 -24
  37. package/dist/lib/browser/markdown-GSOBOXA7.mjs.map +7 -0
  38. package/dist/lib/browser/meta.json +1 -1
  39. package/dist/lib/browser/react-root-RAWRPF7Z.mjs +29 -0
  40. package/dist/lib/browser/react-root-RAWRPF7Z.mjs.map +7 -0
  41. package/dist/lib/browser/{react-surface-PYAMIADB.mjs → react-surface-GOEFSXQ6.mjs} +38 -36
  42. package/dist/lib/browser/react-surface-GOEFSXQ6.mjs.map +7 -0
  43. package/dist/lib/browser/{settings-AC6YSASL.mjs → settings-JN2HHORY.mjs} +6 -5
  44. package/dist/lib/{node-esm/settings-N52O7MLS.mjs.map → browser/settings-JN2HHORY.mjs.map} +1 -1
  45. package/dist/lib/browser/{state-2T4KDWBX.mjs → state-UYPLBGZJ.mjs} +6 -5
  46. package/dist/lib/{node-esm/state-62TQKQVB.mjs.map → browser/state-UYPLBGZJ.mjs.map} +1 -1
  47. package/dist/lib/browser/types/index.mjs +7 -10
  48. package/dist/lib/node-esm/ChannelContainer-RQY4PR4F.mjs +18 -0
  49. package/dist/lib/node-esm/ChatContainer-KWNON7EN.mjs +17 -0
  50. package/dist/lib/node-esm/ChatContainer-KWNON7EN.mjs.map +7 -0
  51. package/dist/lib/node-esm/{app-graph-builder-OLSJVCWY.mjs → app-graph-builder-2IH5RPR7.mjs} +32 -32
  52. package/dist/lib/node-esm/app-graph-builder-2IH5RPR7.mjs.map +7 -0
  53. package/dist/lib/node-esm/blueprint-definition-TSX5HHW7.mjs +102 -0
  54. package/dist/lib/node-esm/blueprint-definition-TSX5HHW7.mjs.map +7 -0
  55. package/dist/lib/node-esm/{call-manager-EI7FXRAU.mjs → call-manager-UMUXEYH5.mjs} +8 -7
  56. package/dist/lib/{browser/call-manager-XRRCAVLI.mjs.map → node-esm/call-manager-UMUXEYH5.mjs.map} +1 -1
  57. package/dist/lib/node-esm/chunk-2AEIN5MI.mjs +22 -0
  58. package/dist/lib/node-esm/chunk-2AEIN5MI.mjs.map +7 -0
  59. package/dist/lib/node-esm/{chunk-4TME3BR4.mjs → chunk-7KZWZS2U.mjs} +256 -161
  60. package/dist/lib/node-esm/chunk-7KZWZS2U.mjs.map +7 -0
  61. package/dist/lib/node-esm/{chunk-57XR3LEF.mjs → chunk-ABUFOZVX.mjs} +2 -2
  62. package/dist/lib/node-esm/chunk-ABUFOZVX.mjs.map +7 -0
  63. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs +11 -0
  64. package/dist/lib/node-esm/chunk-HSLMI22Q.mjs.map +7 -0
  65. package/dist/lib/node-esm/chunk-I3O6NXMN.mjs +25 -0
  66. package/dist/lib/node-esm/chunk-I3O6NXMN.mjs.map +7 -0
  67. package/dist/lib/node-esm/chunk-MEIWWPR2.mjs +143 -0
  68. package/dist/lib/node-esm/chunk-MEIWWPR2.mjs.map +7 -0
  69. package/dist/lib/node-esm/{chunk-SED3O2XO.mjs → chunk-PZH2EDU5.mjs} +74 -41
  70. package/dist/lib/node-esm/chunk-PZH2EDU5.mjs.map +7 -0
  71. package/dist/lib/node-esm/chunk-QFCIKJOD.mjs +612 -0
  72. package/dist/lib/node-esm/chunk-QFCIKJOD.mjs.map +7 -0
  73. package/dist/lib/node-esm/chunk-RT6NRL2I.mjs +19 -0
  74. package/dist/lib/node-esm/chunk-RT6NRL2I.mjs.map +7 -0
  75. package/dist/lib/node-esm/{chunk-QBHKLWGR.mjs → chunk-VBI32FGI.mjs} +54 -4
  76. package/dist/lib/node-esm/chunk-VBI32FGI.mjs.map +7 -0
  77. package/dist/lib/node-esm/{chunk-YIDU3DXK.mjs → chunk-Y3F2SGNH.mjs} +47 -42
  78. package/dist/lib/node-esm/chunk-Y3F2SGNH.mjs.map +7 -0
  79. package/dist/lib/node-esm/chunk-Z4GUSLWL.mjs +378 -0
  80. package/dist/lib/node-esm/chunk-Z4GUSLWL.mjs.map +7 -0
  81. package/dist/lib/node-esm/index.mjs +48 -38
  82. package/dist/lib/node-esm/index.mjs.map +3 -3
  83. package/dist/lib/node-esm/{intent-resolver-QGTPU6QB.mjs → intent-resolver-SJFABEE7.mjs} +33 -51
  84. package/dist/lib/node-esm/intent-resolver-SJFABEE7.mjs.map +7 -0
  85. package/dist/lib/node-esm/{markdown-3MZXUGUA.mjs → markdown-GG5566TL.mjs} +26 -24
  86. package/dist/lib/node-esm/markdown-GG5566TL.mjs.map +7 -0
  87. package/dist/lib/node-esm/meta.json +1 -1
  88. package/dist/lib/node-esm/react-root-K5OGECUS.mjs +30 -0
  89. package/dist/lib/node-esm/react-root-K5OGECUS.mjs.map +7 -0
  90. package/dist/lib/node-esm/{react-surface-UJFCSFNO.mjs → react-surface-5QDQD7MN.mjs} +38 -36
  91. package/dist/lib/node-esm/react-surface-5QDQD7MN.mjs.map +7 -0
  92. package/dist/lib/node-esm/{settings-N52O7MLS.mjs → settings-VSPM3BIM.mjs} +6 -5
  93. package/dist/lib/{browser/settings-AC6YSASL.mjs.map → node-esm/settings-VSPM3BIM.mjs.map} +1 -1
  94. package/dist/lib/node-esm/{state-62TQKQVB.mjs → state-XNWOLBNE.mjs} +6 -5
  95. package/dist/lib/{browser/state-2T4KDWBX.mjs.map → node-esm/state-XNWOLBNE.mjs.map} +1 -1
  96. package/dist/lib/node-esm/types/index.mjs +7 -10
  97. package/dist/types/src/ThreadPlugin.d.ts +1 -1
  98. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  99. package/dist/types/src/calls/media-manager.d.ts +1 -1
  100. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  101. package/dist/types/src/calls/types.d.ts.map +1 -1
  102. package/dist/types/src/calls/util/calls-service.d.ts +3 -1
  103. package/dist/types/src/calls/util/calls-service.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-service.stories.d.ts +10 -9
  106. package/dist/types/src/calls-service.stories.d.ts.map +1 -1
  107. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
  108. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  109. package/dist/types/src/capabilities/blueprint-definition.d.ts +5 -0
  110. package/dist/types/src/capabilities/blueprint-definition.d.ts.map +1 -0
  111. package/dist/types/src/capabilities/call-manager.d.ts +1 -1
  112. package/dist/types/src/capabilities/capabilities.d.ts +2 -2
  113. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  114. package/dist/types/src/capabilities/index.d.ts +11 -10
  115. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  116. package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
  117. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  118. package/dist/types/src/capabilities/markdown.d.ts +1 -1
  119. package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
  120. package/dist/types/src/capabilities/react-root.d.ts +2 -2
  121. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  122. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  123. package/dist/types/src/capabilities/settings.d.ts +1 -1
  124. package/dist/types/src/capabilities/state.d.ts +2 -2
  125. package/dist/types/src/components/Call/Toolbar.d.ts +2 -2
  126. package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
  127. package/dist/types/src/components/CallDebugPanel.d.ts +7 -0
  128. package/dist/types/src/components/CallDebugPanel.d.ts.map +1 -1
  129. package/dist/types/src/components/ChannelContainer.d.ts +2 -2
  130. package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
  131. package/dist/types/src/components/ChannelContainer.stories.d.ts +155 -5
  132. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
  133. package/dist/types/src/components/Chat.stories.d.ts +158 -5
  134. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  135. package/dist/types/src/components/ChatContainer.d.ts +6 -5
  136. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  137. package/dist/types/src/components/Comments.stories.d.ts +156 -4
  138. package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
  139. package/dist/types/src/components/CommentsContainer.d.ts +2 -2
  140. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  141. package/dist/types/src/components/CommentsThreadContainer.d.ts +9 -9
  142. package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -1
  143. package/dist/types/src/components/Media/VideoObject.d.ts +2 -2
  144. package/dist/types/src/components/Media/VideoObject.d.ts.map +1 -1
  145. package/dist/types/src/components/Media/VideoObject.stories.d.ts +18 -4
  146. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  147. package/dist/types/src/components/MessageContainer.d.ts +6 -3
  148. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  149. package/dist/types/src/components/Participant/Participant.d.ts.map +1 -1
  150. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +155 -3
  151. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
  152. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +157 -4
  153. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  154. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
  155. package/dist/types/src/components/ThreadCompanion.d.ts +5 -0
  156. package/dist/types/src/components/ThreadCompanion.d.ts.map +1 -0
  157. package/dist/types/src/components/ThreadSettings.d.ts +1 -1
  158. package/dist/types/src/components/ThreadSettings.d.ts.map +1 -1
  159. package/dist/types/src/components/command-extension.d.ts.map +1 -1
  160. package/dist/types/src/components/index.d.ts +3 -3
  161. package/dist/types/src/components/index.d.ts.map +1 -1
  162. package/dist/types/src/components/testing.d.ts +3 -2
  163. package/dist/types/src/components/testing.d.ts.map +1 -1
  164. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  165. package/dist/types/src/functions/create-proposals.d.ts +6 -0
  166. package/dist/types/src/functions/create-proposals.d.ts.map +1 -0
  167. package/dist/types/src/functions/index.d.ts +2 -0
  168. package/dist/types/src/functions/index.d.ts.map +1 -0
  169. package/dist/types/src/hooks/analytics.d.ts +2 -2
  170. package/dist/types/src/hooks/analytics.d.ts.map +1 -1
  171. package/dist/types/src/hooks/index.d.ts +2 -1
  172. package/dist/types/src/hooks/index.d.ts.map +1 -1
  173. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +2 -0
  174. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +1 -0
  175. package/dist/types/src/hooks/useVideoStreamTrack.d.ts +1 -1
  176. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -1
  177. package/dist/types/src/meta.d.ts +1 -2
  178. package/dist/types/src/meta.d.ts.map +1 -1
  179. package/dist/types/src/testing/stories.d.ts.map +1 -1
  180. package/dist/types/src/translations.d.ts +75 -7
  181. package/dist/types/src/translations.d.ts.map +1 -1
  182. package/dist/types/src/types/Channel.d.ts +16 -0
  183. package/dist/types/src/types/Channel.d.ts.map +1 -0
  184. package/dist/types/src/types/index.d.ts +1 -1
  185. package/dist/types/src/types/index.d.ts.map +1 -1
  186. package/dist/types/src/types/types.d.ts +206 -210
  187. package/dist/types/src/types/types.d.ts.map +1 -1
  188. package/dist/types/tsconfig.tsbuildinfo +1 -1
  189. package/package.json +65 -59
  190. package/src/ThreadPlugin.tsx +139 -125
  191. package/src/calls/call-manager.ts +1 -1
  192. package/src/calls/media-manager.ts +64 -35
  193. package/src/calls/types.ts +7 -3
  194. package/src/calls/util/calls-service.ts +61 -11
  195. package/src/calls/util/stub-media-streams.ts +62 -5
  196. package/src/calls-service.stories.tsx +76 -63
  197. package/src/capabilities/app-graph-builder.ts +43 -30
  198. package/src/capabilities/blueprint-definition.ts +38 -0
  199. package/src/capabilities/capabilities.ts +7 -7
  200. package/src/capabilities/index.ts +1 -0
  201. package/src/capabilities/intent-resolver.ts +23 -30
  202. package/src/capabilities/markdown.ts +5 -3
  203. package/src/capabilities/react-root.tsx +2 -2
  204. package/src/capabilities/react-surface.tsx +25 -23
  205. package/src/components/Call/Call.tsx +1 -1
  206. package/src/components/Call/Toolbar.tsx +9 -9
  207. package/src/components/CallDebugPanel.tsx +112 -55
  208. package/src/components/CallSidebar.tsx +1 -1
  209. package/src/components/ChannelContainer.stories.tsx +13 -13
  210. package/src/components/ChannelContainer.tsx +19 -15
  211. package/src/components/Chat.stories.tsx +30 -34
  212. package/src/components/ChatContainer.tsx +32 -21
  213. package/src/components/Comments.stories.tsx +36 -39
  214. package/src/components/CommentsContainer.tsx +5 -7
  215. package/src/components/CommentsThreadContainer.tsx +38 -33
  216. package/src/components/Lobby/Lobby.tsx +1 -1
  217. package/src/components/Media/VideoObject.stories.tsx +35 -28
  218. package/src/components/Media/VideoObject.tsx +1 -1
  219. package/src/components/MessageContainer.tsx +45 -12
  220. package/src/components/Participant/Participant.tsx +14 -8
  221. package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +5 -6
  222. package/src/components/ResponsiveGrid/ResponsiveContainer.tsx +2 -2
  223. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +42 -41
  224. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +5 -5
  225. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +5 -2
  226. package/src/components/{ThreadComplementary.tsx → ThreadCompanion.tsx} +72 -35
  227. package/src/components/ThreadSettings.tsx +6 -7
  228. package/src/components/command-extension.ts +4 -1
  229. package/src/components/index.ts +4 -4
  230. package/src/components/testing.ts +26 -6
  231. package/src/extensions/threads.ts +26 -17
  232. package/src/functions/create-proposals.ts +56 -0
  233. package/src/functions/index.ts +5 -0
  234. package/src/hooks/analytics.ts +4 -7
  235. package/src/hooks/index.ts +3 -1
  236. package/src/hooks/useBlackCanvasStreamTrack.tsx +27 -0
  237. package/src/hooks/useVideoStreamTrack.tsx +6 -3
  238. package/src/meta.ts +9 -5
  239. package/src/testing/stories.ts +3 -6
  240. package/src/translations.ts +7 -4
  241. package/src/types/Channel.ts +26 -0
  242. package/src/types/index.ts +1 -1
  243. package/src/types/types.ts +27 -28
  244. package/src/typings/peermetrics-webrtc-stats.d.ts +17 -1
  245. package/src/util.ts +1 -1
  246. package/dist/lib/browser/ChannelContainer-O2SFQJU7.mjs +0 -16
  247. package/dist/lib/browser/ChatContainer-PVT3DUZJ.mjs +0 -15
  248. package/dist/lib/browser/app-graph-builder-AF3M7UWN.mjs.map +0 -7
  249. package/dist/lib/browser/chunk-2CWJBXBH.mjs +0 -21
  250. package/dist/lib/browser/chunk-2CWJBXBH.mjs.map +0 -7
  251. package/dist/lib/browser/chunk-4APCDRSH.mjs +0 -18
  252. package/dist/lib/browser/chunk-4APCDRSH.mjs.map +0 -7
  253. package/dist/lib/browser/chunk-DW7JD64V.mjs +0 -137
  254. package/dist/lib/browser/chunk-DW7JD64V.mjs.map +0 -7
  255. package/dist/lib/browser/chunk-EV4JWI7L.mjs +0 -17
  256. package/dist/lib/browser/chunk-EV4JWI7L.mjs.map +0 -7
  257. package/dist/lib/browser/chunk-FY4ZRD5X.mjs +0 -367
  258. package/dist/lib/browser/chunk-FY4ZRD5X.mjs.map +0 -7
  259. package/dist/lib/browser/chunk-GERVMFQW.mjs.map +0 -7
  260. package/dist/lib/browser/chunk-J3JO5NWO.mjs +0 -477
  261. package/dist/lib/browser/chunk-J3JO5NWO.mjs.map +0 -7
  262. package/dist/lib/browser/chunk-JGKMMI65.mjs.map +0 -7
  263. package/dist/lib/browser/chunk-TUFWPOVS.mjs.map +0 -7
  264. package/dist/lib/browser/chunk-X5PIP5YR.mjs.map +0 -7
  265. package/dist/lib/browser/chunk-ZJ7QBXK6.mjs.map +0 -7
  266. package/dist/lib/browser/intent-resolver-DCY4P4OX.mjs.map +0 -7
  267. package/dist/lib/browser/markdown-WZSXCEZJ.mjs.map +0 -7
  268. package/dist/lib/browser/react-root-QXPALOUQ.mjs +0 -28
  269. package/dist/lib/browser/react-root-QXPALOUQ.mjs.map +0 -7
  270. package/dist/lib/browser/react-surface-PYAMIADB.mjs.map +0 -7
  271. package/dist/lib/node-esm/ChannelContainer-B2ZGAE4P.mjs +0 -17
  272. package/dist/lib/node-esm/ChatContainer-2CT4PJ7I.mjs +0 -16
  273. package/dist/lib/node-esm/app-graph-builder-OLSJVCWY.mjs.map +0 -7
  274. package/dist/lib/node-esm/chunk-4TME3BR4.mjs.map +0 -7
  275. package/dist/lib/node-esm/chunk-57XR3LEF.mjs.map +0 -7
  276. package/dist/lib/node-esm/chunk-6CRHHOST.mjs +0 -23
  277. package/dist/lib/node-esm/chunk-6CRHHOST.mjs.map +0 -7
  278. package/dist/lib/node-esm/chunk-BF4UKS55.mjs +0 -368
  279. package/dist/lib/node-esm/chunk-BF4UKS55.mjs.map +0 -7
  280. package/dist/lib/node-esm/chunk-GRLRWTRU.mjs +0 -19
  281. package/dist/lib/node-esm/chunk-GRLRWTRU.mjs.map +0 -7
  282. package/dist/lib/node-esm/chunk-PYTVBN5J.mjs +0 -19
  283. package/dist/lib/node-esm/chunk-PYTVBN5J.mjs.map +0 -7
  284. package/dist/lib/node-esm/chunk-QBHKLWGR.mjs.map +0 -7
  285. package/dist/lib/node-esm/chunk-SED3O2XO.mjs.map +0 -7
  286. package/dist/lib/node-esm/chunk-VNG6M2IY.mjs +0 -478
  287. package/dist/lib/node-esm/chunk-VNG6M2IY.mjs.map +0 -7
  288. package/dist/lib/node-esm/chunk-XVKWHTH4.mjs +0 -138
  289. package/dist/lib/node-esm/chunk-XVKWHTH4.mjs.map +0 -7
  290. package/dist/lib/node-esm/chunk-YIDU3DXK.mjs.map +0 -7
  291. package/dist/lib/node-esm/intent-resolver-QGTPU6QB.mjs.map +0 -7
  292. package/dist/lib/node-esm/markdown-3MZXUGUA.mjs.map +0 -7
  293. package/dist/lib/node-esm/react-root-7ZFJYVUZ.mjs +0 -29
  294. package/dist/lib/node-esm/react-root-7ZFJYVUZ.mjs.map +0 -7
  295. package/dist/lib/node-esm/react-surface-UJFCSFNO.mjs.map +0 -7
  296. package/dist/types/src/components/ThreadComplementary.d.ts +0 -5
  297. package/dist/types/src/components/ThreadComplementary.d.ts.map +0 -1
  298. package/dist/types/src/types/schema.d.ts +0 -164
  299. package/dist/types/src/types/schema.d.ts.map +0 -1
  300. package/src/types/schema.ts +0 -33
  301. /package/dist/lib/browser/{ChannelContainer-O2SFQJU7.mjs.map → ChannelContainer-JI3ZRZ5S.mjs.map} +0 -0
  302. /package/dist/lib/browser/{ChatContainer-PVT3DUZJ.mjs.map → ChatContainer-6FVFME3R.mjs.map} +0 -0
  303. /package/dist/lib/{node-esm/ChannelContainer-B2ZGAE4P.mjs.map → browser/chunk-J5LGTIGS.mjs.map} +0 -0
  304. /package/dist/lib/node-esm/{ChatContainer-2CT4PJ7I.mjs.map → ChannelContainer-RQY4PR4F.mjs.map} +0 -0
@@ -4,6 +4,7 @@
4
4
 
5
5
  import { DeferredTask, Event, sleep, synchronized } from '@dxos/async';
6
6
  import { type Context, Resource, cancelWithContext } from '@dxos/context';
7
+ import { invariant } from '@dxos/invariant';
7
8
  import { log } from '@dxos/log';
8
9
 
9
10
  import { SpeakingMonitor } from './speaking-monitor';
@@ -48,19 +49,23 @@ const VIDEO_WIDTH = 1280;
48
49
  const VIDEO_HEIGHT = 720;
49
50
  const MAX_WEB_CAM_FRAMERATE = 24;
50
51
  const MAX_WEB_CAM_BITRATE = 120_0000;
51
- const RETRY_INTERVAL = 500;
52
+ const RETRY_INTERVAL = 100;
52
53
 
53
54
  export type MediaManagerParams = {
54
55
  serviceConfig: CallsServiceConfig;
55
56
  };
56
57
 
57
- const USE_INAUDIBLE_AUDIO = false;
58
+ const USE_INAUDIBLE_AUDIO = true;
58
59
 
59
60
  export class MediaManager extends Resource {
60
61
  public readonly stateUpdated = new Event<MediaState>();
61
- private readonly _state: MediaState = { pulledVideoStreams: {}, pulledAudioTracks: {} };
62
- private _speakingMonitor?: SpeakingMonitor = undefined;
63
62
 
63
+ private readonly _state: MediaState = {
64
+ pulledVideoStreams: {},
65
+ pulledAudioTracks: {},
66
+ };
67
+
68
+ private _speakingMonitor?: SpeakingMonitor = undefined;
64
69
  private _trackToReconcile: EncodedTrackName[] = [];
65
70
  private _blackCanvasStreamTrack?: MediaStreamTrack = undefined;
66
71
  private _inaudibleAudioStreamTrack?: MediaStreamTrack = undefined;
@@ -84,6 +89,7 @@ export class MediaManager extends Resource {
84
89
  width: VIDEO_WIDTH,
85
90
  height: VIDEO_HEIGHT,
86
91
  });
92
+
87
93
  this._state.videoTrack = this._blackCanvasStreamTrack;
88
94
  this._state.videoStream = new MediaStream();
89
95
  this._state.videoStream.addTrack(this._state.videoTrack);
@@ -136,6 +142,7 @@ export class MediaManager extends Resource {
136
142
  this._state.videoStream!.removeTrack(this._state.videoTrack!);
137
143
  this._state.videoTrack = await getUserMediaTrack('videoinput', { width: VIDEO_WIDTH, height: VIDEO_HEIGHT });
138
144
  this._state.videoStream!.addTrack(this._state.videoTrack);
145
+
139
146
  this._state.videoEnabled = true;
140
147
  this.stateUpdated.emit(this._state);
141
148
  this._pushTracksTask!.schedule();
@@ -225,7 +232,6 @@ export class MediaManager extends Resource {
225
232
  // Wait for cloudflare to process the track.
226
233
  await cancelWithContext(this._ctx, sleep(800));
227
234
  const trackNames = this._trackToReconcile;
228
-
229
235
  const tracksToPull = trackNames.filter(
230
236
  (name) => !this._state.pulledAudioTracks[name] && !this._state.pulledVideoStreams[name],
231
237
  );
@@ -248,7 +254,7 @@ export class MediaManager extends Resource {
248
254
  });
249
255
 
250
256
  // Pull new tracks.
251
- await Promise.all(tracksToPull.map((name) => this._pullTrack(name)));
257
+ const pullResults = await Promise.all(tracksToPull.map((name) => this._pullTrack(name)));
252
258
 
253
259
  // Close old tracks.
254
260
  await Promise.all([...audioTracksToClose, ...videoStreamsToClose].map(([_, { ctx }]) => ctx.dispose()));
@@ -257,7 +263,14 @@ export class MediaManager extends Resource {
257
263
  currentAudioTracks: Object.keys(this._state.pulledAudioTracks),
258
264
  currentVideoStreams: Object.keys(this._state.pulledVideoStreams),
259
265
  });
266
+
260
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
+ }
261
274
  }
262
275
 
263
276
  private async _pushTracks(): Promise<void> {
@@ -266,38 +279,46 @@ export class MediaManager extends Resource {
266
279
  }
267
280
 
268
281
  let updated = false;
269
- const [pushedVideoTrack, pushedAudioTrack, pushedScreenshareTrack] = await Promise.all([
270
- this._pushTrack(this._state.videoTrack, this._state.pushedVideoTrack, [
282
+ const [pushVideoResult, pushAudioResult, pushScreenshareResult] = await Promise.all([
283
+ this._maybePushTrack(this._state.videoTrack, this._state.pushedVideoTrack, [
271
284
  { maxFramerate: MAX_WEB_CAM_FRAMERATE, maxBitrate: MAX_WEB_CAM_BITRATE },
272
285
  ]),
273
- this._pushTrack(this._state.audioTrack, this._state.pushedAudioTrack, [{ networkPriority: 'high' }]),
274
- this._pushTrack(this._state.screenshareTrack, this._state.pushedScreenshareTrack),
286
+ this._maybePushTrack(this._state.audioTrack, this._state.pushedAudioTrack, [{ networkPriority: 'high' }]),
287
+ this._maybePushTrack(this._state.screenshareTrack, this._state.pushedScreenshareTrack),
275
288
  ]);
276
289
 
277
- if (pushedVideoTrack !== this._state.pushedVideoTrack) {
278
- this._state.pushedVideoTrack = pushedVideoTrack;
290
+ if (pushVideoResult.track !== this._state.pushedVideoTrack) {
291
+ this._state.pushedVideoTrack = pushVideoResult.track;
279
292
  updated = true;
280
293
  }
281
- if (pushedAudioTrack !== this._state.pushedAudioTrack) {
282
- this._state.pushedAudioTrack = pushedAudioTrack;
294
+ if (pushAudioResult.track !== this._state.pushedAudioTrack) {
295
+ this._state.pushedAudioTrack = pushAudioResult.track;
283
296
  updated = true;
284
297
  }
285
- if (pushedScreenshareTrack !== this._state.pushedScreenshareTrack) {
286
- this._state.pushedScreenshareTrack = pushedScreenshareTrack;
298
+ if (pushScreenshareResult.track !== this._state.pushedScreenshareTrack) {
299
+ this._state.pushedScreenshareTrack = pushScreenshareResult.track;
287
300
  updated = true;
288
301
  }
289
- if (!updated) {
290
- return;
302
+
303
+ const shouldRetry = pushVideoResult.shouldRetry || pushAudioResult.shouldRetry || pushScreenshareResult.shouldRetry;
304
+ if (updated) {
305
+ this.stateUpdated.emit(this._state);
291
306
  }
292
307
 
293
- this.stateUpdated.emit(this._state);
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
+ }
294
314
  }
295
315
 
296
- private async _pullTrack(name: EncodedTrackName): Promise<void> {
316
+ private async _pullTrack(name: EncodedTrackName): Promise<{ shouldRetry: boolean }> {
297
317
  const ctx = this._ctx.derive();
298
318
  try {
299
319
  const trackData = TrackNameCodec.decode(name);
300
- const track = await this._state.peer!.pullTrack({ trackData, ctx });
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 });
301
322
  if (track?.readyState === 'ended') {
302
323
  throw new Error('Pulled track ended immediately');
303
324
  }
@@ -306,7 +327,7 @@ export class MediaManager extends Resource {
306
327
  case 'audio': {
307
328
  this._state.pulledAudioTracks[name] = { track, ctx };
308
329
  ctx.onDispose(() => delete this._state.pulledAudioTracks[name]);
309
- break;
330
+ return { shouldRetry: false };
310
331
  }
311
332
  case 'video': {
312
333
  const mediaStream = new MediaStream();
@@ -317,33 +338,41 @@ export class MediaManager extends Resource {
317
338
  track.stop();
318
339
  delete this._state.pulledVideoStreams[name];
319
340
  });
320
- break;
341
+ return { shouldRetry: false };
321
342
  }
322
343
  default:
323
344
  throw new Error(`Invalid track kind: ${track?.kind}`);
324
345
  }
325
346
  } catch (err) {
326
- log.verbose('failed to pull track', { err, name });
347
+ log.info('failed to pull track', { err, name });
327
348
  void ctx.dispose();
328
- await cancelWithContext(this._ctx, sleep(RETRY_INTERVAL));
329
- log.verbose('retrying pull track', { name });
330
- this._pullTracksTask!.schedule();
349
+ return { shouldRetry: true };
331
350
  }
332
351
  }
333
352
 
334
- private async _pushTrack(
353
+ private async _maybePushTrack(
335
354
  track?: MediaStreamTrack,
336
355
  previousTrack?: TrackObject,
337
356
  encodings?: RTCRtpEncodingParameters[],
338
- ): Promise<TrackObject | undefined> {
357
+ ): Promise<{ track?: TrackObject; shouldRetry?: boolean }> {
339
358
  if (!track && !previousTrack) {
340
- return;
359
+ return { track: undefined };
341
360
  }
342
361
 
343
- return this._state.peer!.pushTrack({
344
- track: track ?? null,
345
- previousTrack,
346
- encodings,
347
- });
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
+ }
348
377
  }
349
378
  }
@@ -2,6 +2,7 @@
2
2
  // Copyright 2025 DXOS.org
3
3
  //
4
4
 
5
+ import { invariant } from '@dxos/invariant';
5
6
  import { buf } from '@dxos/protocols/buf';
6
7
  import {
7
8
  type ActivitySchema,
@@ -61,10 +62,13 @@ export type EncodedTrackName = string & { __brand: 'EncodedTrackName' };
61
62
 
62
63
  export const TrackNameCodec = {
63
64
  encode: (trackData: TrackObject): EncodedTrackName => {
64
- return (trackData.sessionId + '/' + trackData.trackName) as EncodedTrackName;
65
+ invariant(trackData.sessionId);
66
+ invariant(trackData.trackName);
67
+ invariant(trackData.mid);
68
+ return (trackData.sessionId + '/' + trackData.trackName + '/' + trackData.mid) as EncodedTrackName;
65
69
  },
66
70
  decode: (name: EncodedTrackName): TrackObject => {
67
- const [sessionId, trackName] = name.split('/');
68
- return { sessionId, trackName, location: 'remote' };
71
+ const [sessionId, trackName, mid] = name.split('/');
72
+ return { sessionId, trackName, location: 'remote', mid };
69
73
  },
70
74
  };
@@ -2,7 +2,7 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { PersistentLifecycle } from '@dxos/async';
5
+ import { PersistentLifecycle, Trigger, scheduleTask } from '@dxos/async';
6
6
  import { type Context, Resource } from '@dxos/context';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import { log } from '@dxos/log';
@@ -33,12 +33,14 @@ export type CallsServiceConfig = {
33
33
 
34
34
  export type HistoryRecord =
35
35
  | {
36
+ endpoint: string;
36
37
  type: 'request';
37
38
  time: string;
38
39
  method: string;
39
40
  body: any;
40
41
  }
41
42
  | {
43
+ endpoint: string;
42
44
  type: 'response';
43
45
  time: string;
44
46
  status: number;
@@ -116,7 +118,7 @@ export class CallsServicePeer extends Resource {
116
118
  });
117
119
  peerConnection.addEventListener('connectionstatechange', () => {
118
120
  if (peerConnection.connectionState === 'failed' || peerConnection.connectionState === 'closed') {
119
- log.warn('calls connection failed', { state: peerConnection.connectionState });
121
+ log.info('calls connection failed', { state: peerConnection.connectionState });
120
122
  void this._persistentLifecycle.scheduleRestart();
121
123
  }
122
124
  });
@@ -125,7 +127,7 @@ export class CallsServicePeer extends Resource {
125
127
  peerConnection.addEventListener('iceconnectionstatechange', () => {
126
128
  clearTimeout(iceTimeout);
127
129
  if (peerConnection.iceConnectionState === 'failed' || peerConnection.iceConnectionState === 'closed') {
128
- log.warn('calls connection to ICEs failed', { state: peerConnection.iceConnectionState });
130
+ log.info('calls connection to ICEs failed', { state: peerConnection.iceConnectionState });
129
131
  void this._persistentLifecycle.scheduleRestart();
130
132
  } else if (peerConnection.iceConnectionState === 'disconnected') {
131
133
  // TODO(mykola): we should start to inspect the connection stats from here on for
@@ -138,7 +140,7 @@ export class CallsServicePeer extends Resource {
138
140
  return;
139
141
  }
140
142
 
141
- log.warn('calls iceConnectionState timed out', { state: peerConnection.iceConnectionState, timeoutSeconds });
143
+ log.info('calls iceConnectionState timed out', { state: peerConnection.iceConnectionState, timeoutSeconds });
142
144
  void this._persistentLifecycle.scheduleRestart();
143
145
  }, timeoutSeconds * 1_000);
144
146
  }
@@ -155,6 +157,7 @@ export class CallsServicePeer extends Resource {
155
157
 
156
158
  private async _fetch<T extends ErrorResponse>(relativePath: string, requestInit?: RequestInit): Promise<T> {
157
159
  this.history.push({
160
+ endpoint: relativePath,
158
161
  type: 'request',
159
162
  time: new Date().toISOString(),
160
163
  method: requestInit?.method ?? 'GET',
@@ -170,6 +173,7 @@ export class CallsServicePeer extends Resource {
170
173
  try {
171
174
  const data = (await response.clone().json()) as T;
172
175
  this.history.push({
176
+ endpoint: relativePath,
173
177
  type: 'response',
174
178
  time: new Date().toISOString(),
175
179
  status: response.status,
@@ -183,6 +187,7 @@ export class CallsServicePeer extends Resource {
183
187
  } catch (error) {
184
188
  const text = await response.text();
185
189
  this.history.push({
190
+ endpoint: relativePath,
186
191
  type: 'response',
187
192
  time: new Date().toISOString(),
188
193
  status: response.status,
@@ -204,11 +209,11 @@ export class CallsServicePeer extends Resource {
204
209
  sessionId,
205
210
  trackName,
206
211
  }: {
212
+ ctx: Context;
207
213
  peerConnection: RTCPeerConnection;
208
214
  transceiver: RTCRtpTransceiver;
209
215
  sessionId: string;
210
216
  trackName: string;
211
- ctx?: Context;
212
217
  }): Promise<TrackObject | void> {
213
218
  log.verbose('pushing track ', trackName);
214
219
  const pushedTrackPromise = this.pushTrackDispatcher
@@ -246,9 +251,13 @@ export class CallsServicePeer extends Resource {
246
251
  };
247
252
  }),
248
253
  )
249
- .then(({ tracks }) => {
254
+ .then(async ({ tracks }) => {
250
255
  const trackData = tracks.find((t) => t.mid === transceiver.mid);
251
256
  if (trackData) {
257
+ // we wait for the transceiver to start sending data before we emit
258
+ // the track metadata to ensure that the track will be able to be
259
+ // pulled before making the metadata available to anyone else.
260
+ // await waitForTransceiverToSendData(ctx, transceiver);
252
261
  return {
253
262
  ...trackData,
254
263
  sessionId,
@@ -257,9 +266,6 @@ export class CallsServicePeer extends Resource {
257
266
  } else {
258
267
  log.error('missing track data');
259
268
  }
260
- })
261
- .catch((err) => {
262
- log.catch(err);
263
269
  });
264
270
 
265
271
  const onDispose = async () => {
@@ -281,8 +287,8 @@ export class CallsServicePeer extends Resource {
281
287
  previousTrack,
282
288
  }: {
283
289
  track: MediaStreamTrack | null;
290
+ ctx: Context;
284
291
  encodings?: RTCRtpEncodingParameters[];
285
- ctx?: Context;
286
292
  previousTrack?: TrackObject;
287
293
  }): Promise<TrackObject | undefined> {
288
294
  await this.waitUntilOpen();
@@ -405,7 +411,7 @@ export class CallsServicePeer extends Resource {
405
411
  })
406
412
  .catch((err) => log.catch(err));
407
413
  } else {
408
- log.warn('missing track info', { trackData, availableTracks: Array.from(trackMap.keys()) });
414
+ log.info('missing track info', { trackData, availableTracks: Array.from(trackMap.keys()) });
409
415
  }
410
416
  });
411
417
 
@@ -529,3 +535,47 @@ const peerConnectionIsConnected = async (peerConnection: RTCPeerConnection) => {
529
535
  await connected;
530
536
  }
531
537
  };
538
+
539
+ const INITIAL_DELAY = 50;
540
+ const MAX_DELAY = 500;
541
+ const MAX_RETRIES = 20;
542
+ const WAIT_FOR_DATA_TIMEOUT = 10_000;
543
+
544
+ const waitForTransceiverToSendData = async (ctx: Context, transceiver: RTCRtpTransceiver): Promise<void> => {
545
+ let delay = INITIAL_DELAY;
546
+ let checks = 0;
547
+ const waitForData = new Trigger();
548
+ ctx.onDispose(() => waitForData.throw(new Error('Transceiver was closed')));
549
+
550
+ const checkStats = async () => {
551
+ if (ctx.disposed) return;
552
+
553
+ try {
554
+ const stats = await transceiver.sender.getStats();
555
+ let dataFound = false;
556
+ stats.forEach((stat) => {
557
+ if (stat.type === 'outbound-rtp' && stat.bytesSent > 0) {
558
+ dataFound = true;
559
+ }
560
+ });
561
+
562
+ if (dataFound) {
563
+ waitForData.wake();
564
+ return;
565
+ }
566
+ } catch {
567
+ // Stats might not be available yet, continue checking
568
+ }
569
+ checks++;
570
+ if (checks > MAX_RETRIES) {
571
+ waitForData.throw(new Error('Transceiver did not send data'));
572
+ return;
573
+ }
574
+
575
+ delay = Math.min(delay * 2, MAX_DELAY); // Exponential backoff with max cap
576
+ scheduleTask(ctx, checkStats, delay);
577
+ };
578
+
579
+ void checkStats();
580
+ return waitForData.wait({ timeout: WAIT_FOR_DATA_TIMEOUT });
581
+ };
@@ -30,7 +30,7 @@ export const createBlackCanvasStreamTrack = async ({
30
30
  canvasCtx.fillStyle = 'black';
31
31
  canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
32
32
  };
33
- scheduleTaskInterval(ctx, async () => drawFrame(), 1_000);
33
+ scheduleTaskInterval(ctx, async () => drawFrame(), 200);
34
34
 
35
35
  const track = canvas.captureStream().getVideoTracks()[0];
36
36
  drawFrame();
@@ -40,27 +40,84 @@ export const createBlackCanvasStreamTrack = async ({
40
40
  return track;
41
41
  };
42
42
 
43
+ let audioContextStartedPreviously = false;
44
+ const userGestureEvents = [
45
+ 'click',
46
+ 'contextmenu',
47
+ 'auxclick',
48
+ 'dblclick',
49
+ 'mousedown',
50
+ 'mouseup',
51
+ 'pointerup',
52
+ 'touchend',
53
+ 'keydown',
54
+ 'keyup',
55
+ ];
56
+
43
57
  /**
44
58
  * Creates an inaudible audio stream track.
45
59
  * We need this to have audio track available when audio is disabled.
46
60
  */
47
61
  export const createInaudibleAudioStreamTrack = async ({ ctx }: { ctx: Context }): Promise<MediaStreamTrack> => {
48
62
  const audioContext = new window.AudioContext();
63
+
49
64
  const oscillator = audioContext.createOscillator();
50
65
  oscillator.type = 'triangle';
51
- // roughly sounds like a box fan
52
66
  oscillator.frequency.setValueAtTime(20, audioContext.currentTime);
53
67
 
54
68
  const gainNode = audioContext.createGain();
55
- // even w/ gain at 0 some packets are sent
56
- gainNode.gain.setValueAtTime(0.02, audioContext.currentTime);
69
+ gainNode.gain.setValueAtTime(0, audioContext.currentTime);
57
70
  oscillator.connect(gainNode);
58
71
 
59
72
  const destination = audioContext.createMediaStreamDestination();
60
73
  gainNode.connect(destination);
61
- oscillator.start();
74
+
75
+ let oscillatorStarted = false;
76
+ const ensureOscillatorStarted = () => {
77
+ if (oscillatorStarted) return;
78
+ oscillator.start();
79
+ oscillatorStarted = true;
80
+ };
81
+
82
+ const stateChangeHandler = () => {
83
+ if (audioContext.state === 'running') {
84
+ audioContextStartedPreviously = true;
85
+ ensureOscillatorStarted();
86
+ }
87
+
88
+ if (audioContext.state === 'suspended' || (audioContext.state as string) === 'interrupted') {
89
+ resumeAudioContext();
90
+ }
91
+ };
92
+
93
+ audioContext.addEventListener('statechange', stateChangeHandler);
94
+
95
+ const resumeAudioContext = () => {
96
+ void audioContext.resume().then(() => {
97
+ cleanUpUserGestureListeners();
98
+ });
99
+ };
100
+
101
+ const cleanUpUserGestureListeners = () => {
102
+ userGestureEvents.forEach((gesture) => {
103
+ document.removeEventListener(gesture, resumeAudioContext, {
104
+ capture: true,
105
+ });
106
+ });
107
+ };
108
+
109
+ if (audioContextStartedPreviously) {
110
+ resumeAudioContext();
111
+ } else {
112
+ userGestureEvents.forEach((gesture) => {
113
+ document.addEventListener(gesture, resumeAudioContext, {
114
+ capture: true,
115
+ });
116
+ });
117
+ }
62
118
 
63
119
  ctx.onDispose(async () => {
120
+ cleanUpUserGestureListeners();
64
121
  oscillator.disconnect();
65
122
  oscillator.stop();
66
123
  await audioContext.close();