@dxos/plugin-thread 0.8.4-main.2e9d522 → 0.8.4-main.5ea62a8

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 (247) hide show
  1. package/dist/lib/browser/ChannelContainer-GHDNEZT2.mjs +16 -0
  2. package/dist/lib/browser/{ChatContainer-AIGIWAUG.mjs → ChatContainer-42ALOWUA.mjs} +4 -4
  3. package/dist/lib/browser/{app-graph-builder-N7BE5TYW.mjs → app-graph-builder-FHAOPO57.mjs} +5 -5
  4. package/dist/lib/browser/app-graph-builder-FHAOPO57.mjs.map +7 -0
  5. package/dist/lib/browser/{call-manager-NIPDYUVD.mjs → call-manager-EW2QC6Q4.mjs} +4 -4
  6. package/dist/lib/browser/call-manager-EW2QC6Q4.mjs.map +7 -0
  7. package/dist/lib/browser/chunk-2I277V52.mjs +23 -0
  8. package/dist/lib/browser/{chunk-4OYAYON2.mjs.map → chunk-2I277V52.mjs.map} +3 -3
  9. package/dist/lib/browser/{chunk-ERWASUQK.mjs → chunk-2P3GVRHP.mjs} +38 -6
  10. package/dist/lib/{node-esm/chunk-25ABSYP2.mjs.map → browser/chunk-2P3GVRHP.mjs.map} +4 -4
  11. package/dist/lib/browser/{chunk-LGSDKXPF.mjs → chunk-4APCDRSH.mjs} +1 -1
  12. package/dist/lib/browser/{chunk-LGSDKXPF.mjs.map → chunk-4APCDRSH.mjs.map} +1 -1
  13. package/dist/lib/browser/chunk-H63NDV62.mjs +376 -0
  14. package/dist/lib/browser/chunk-H63NDV62.mjs.map +7 -0
  15. package/dist/lib/browser/chunk-J26C57ZY.mjs +548 -0
  16. package/dist/lib/browser/chunk-J26C57ZY.mjs.map +7 -0
  17. package/dist/lib/browser/{chunk-6NSMBO3B.mjs → chunk-KEXJGF2R.mjs} +4 -4
  18. package/dist/lib/browser/chunk-KEXJGF2R.mjs.map +7 -0
  19. package/dist/lib/browser/{chunk-GCLD5ESP.mjs → chunk-KTWYVC5X.mjs} +22 -12
  20. package/dist/lib/browser/chunk-KTWYVC5X.mjs.map +7 -0
  21. package/dist/lib/browser/{chunk-KWPRNHTK.mjs → chunk-TQJYDFBU.mjs} +232 -230
  22. package/dist/lib/browser/chunk-TQJYDFBU.mjs.map +7 -0
  23. package/dist/lib/browser/{chunk-ZE7KWN36.mjs → chunk-TUSBPMNU.mjs} +398 -174
  24. package/dist/lib/browser/chunk-TUSBPMNU.mjs.map +7 -0
  25. package/dist/lib/browser/index.mjs +18 -8
  26. package/dist/lib/browser/index.mjs.map +3 -3
  27. package/dist/lib/browser/{intent-resolver-JFGLZ6VI.mjs → intent-resolver-IB5GYU2D.mjs} +68 -9
  28. package/dist/lib/browser/intent-resolver-IB5GYU2D.mjs.map +7 -0
  29. package/dist/lib/browser/{markdown-GEXBVJYN.mjs → markdown-Z677YORA.mjs} +4 -4
  30. package/dist/lib/browser/markdown-Z677YORA.mjs.map +7 -0
  31. package/dist/lib/browser/meta.json +1 -1
  32. package/dist/lib/browser/{react-root-X4UIVGTX.mjs → react-root-PTTTW2MO.mjs} +9 -9
  33. package/dist/lib/browser/{react-surface-YCYEFBPM.mjs → react-surface-X2VB6P37.mjs} +9 -9
  34. package/dist/lib/browser/react-surface-X2VB6P37.mjs.map +7 -0
  35. package/dist/lib/browser/{settings-E32MTL7A.mjs → settings-GRKEID73.mjs} +2 -2
  36. package/dist/lib/browser/{state-H6CYONWE.mjs → state-2T4KDWBX.mjs} +2 -2
  37. package/dist/lib/browser/{state-H6CYONWE.mjs.map → state-2T4KDWBX.mjs.map} +2 -2
  38. package/dist/lib/browser/toolkit-KUPIIFC6.mjs +80 -0
  39. package/dist/lib/browser/toolkit-KUPIIFC6.mjs.map +7 -0
  40. package/dist/lib/browser/types/index.mjs +1 -1
  41. package/dist/lib/node-esm/{ChannelContainer-DET6T5N2.mjs → ChannelContainer-D5E2S6AI.mjs} +7 -7
  42. package/dist/lib/node-esm/{ChatContainer-IQUWU426.mjs → ChatContainer-4EGHKHIU.mjs} +4 -4
  43. package/dist/lib/node-esm/{app-graph-builder-VCW76Z6V.mjs → app-graph-builder-XEYWX5FC.mjs} +5 -5
  44. package/dist/lib/node-esm/app-graph-builder-XEYWX5FC.mjs.map +7 -0
  45. package/dist/lib/node-esm/{call-manager-D6O5ZJJ4.mjs → call-manager-N3KASRDQ.mjs} +4 -4
  46. package/dist/lib/node-esm/call-manager-N3KASRDQ.mjs.map +7 -0
  47. package/dist/lib/node-esm/{chunk-C3XFMUAY.mjs → chunk-CCE5LHBE.mjs} +232 -230
  48. package/dist/lib/node-esm/chunk-CCE5LHBE.mjs.map +7 -0
  49. package/dist/lib/node-esm/{chunk-25ABSYP2.mjs → chunk-CTZ75IFK.mjs} +38 -6
  50. package/dist/lib/node-esm/chunk-CTZ75IFK.mjs.map +7 -0
  51. package/dist/lib/node-esm/{chunk-IHDNQLLR.mjs → chunk-JR7KESLL.mjs} +398 -174
  52. package/dist/lib/node-esm/chunk-JR7KESLL.mjs.map +7 -0
  53. package/dist/lib/node-esm/chunk-NNKKNW57.mjs +549 -0
  54. package/dist/lib/node-esm/chunk-NNKKNW57.mjs.map +7 -0
  55. package/dist/lib/node-esm/{chunk-TDFHTCZZ.mjs → chunk-P6E247RF.mjs} +22 -12
  56. package/dist/lib/node-esm/chunk-P6E247RF.mjs.map +7 -0
  57. package/dist/lib/node-esm/{chunk-75RJ5DJI.mjs → chunk-PYTVBN5J.mjs} +1 -1
  58. package/dist/lib/node-esm/{chunk-75RJ5DJI.mjs.map → chunk-PYTVBN5J.mjs.map} +1 -1
  59. package/dist/lib/node-esm/{chunk-OU5BYIDO.mjs → chunk-S3D7DTBF.mjs} +4 -4
  60. package/dist/lib/node-esm/chunk-S3D7DTBF.mjs.map +7 -0
  61. package/dist/lib/node-esm/chunk-UHZQTPXU.mjs +377 -0
  62. package/dist/lib/node-esm/chunk-UHZQTPXU.mjs.map +7 -0
  63. package/dist/lib/node-esm/chunk-UJ2QNRLS.mjs +25 -0
  64. package/dist/lib/node-esm/{chunk-GW37AAM4.mjs.map → chunk-UJ2QNRLS.mjs.map} +3 -3
  65. package/dist/lib/node-esm/index.mjs +18 -8
  66. package/dist/lib/node-esm/index.mjs.map +3 -3
  67. package/dist/lib/node-esm/{intent-resolver-OXGNQ44Y.mjs → intent-resolver-VIMI5VLH.mjs} +68 -9
  68. package/dist/lib/node-esm/intent-resolver-VIMI5VLH.mjs.map +7 -0
  69. package/dist/lib/node-esm/{markdown-LIJZDK2J.mjs → markdown-FL4IXLRP.mjs} +4 -4
  70. package/dist/lib/node-esm/markdown-FL4IXLRP.mjs.map +7 -0
  71. package/dist/lib/node-esm/meta.json +1 -1
  72. package/dist/lib/node-esm/{react-root-M7J6PZVW.mjs → react-root-2HHRRUME.mjs} +9 -9
  73. package/dist/lib/node-esm/{react-surface-IRSEKM42.mjs → react-surface-OLN3XNND.mjs} +9 -9
  74. package/dist/lib/node-esm/react-surface-OLN3XNND.mjs.map +7 -0
  75. package/dist/lib/node-esm/{settings-SJ24YG7M.mjs → settings-F2ODVNNW.mjs} +2 -2
  76. package/dist/lib/node-esm/{state-D7WNDT3N.mjs → state-62TQKQVB.mjs} +2 -2
  77. package/dist/lib/node-esm/{state-D7WNDT3N.mjs.map → state-62TQKQVB.mjs.map} +2 -2
  78. package/dist/lib/node-esm/toolkit-KZIS7G36.mjs +81 -0
  79. package/dist/lib/node-esm/toolkit-KZIS7G36.mjs.map +7 -0
  80. package/dist/lib/node-esm/types/index.mjs +1 -1
  81. package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
  82. package/dist/types/src/calls/call-manager.d.ts.map +1 -1
  83. package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +1 -1
  84. package/dist/types/src/calls/media-manager.d.ts +1 -1
  85. package/dist/types/src/calls/media-manager.d.ts.map +1 -1
  86. package/dist/types/src/calls/types.d.ts +1 -1
  87. package/dist/types/src/calls/types.d.ts.map +1 -1
  88. package/dist/types/src/calls/util/calls-service.d.ts +2 -2
  89. package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
  90. package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
  91. package/dist/types/src/calls-service.stories.d.ts +10 -8
  92. package/dist/types/src/calls-service.stories.d.ts.map +1 -1
  93. package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
  94. package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
  95. package/dist/types/src/capabilities/call-manager.d.ts +1 -1
  96. package/dist/types/src/capabilities/call-manager.d.ts.map +1 -1
  97. package/dist/types/src/capabilities/capabilities.d.ts +2 -2
  98. package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
  99. package/dist/types/src/capabilities/index.d.ts +11 -10
  100. package/dist/types/src/capabilities/index.d.ts.map +1 -1
  101. package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
  102. package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
  103. package/dist/types/src/capabilities/markdown.d.ts +1 -1
  104. package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
  105. package/dist/types/src/capabilities/react-root.d.ts +2 -2
  106. package/dist/types/src/capabilities/react-surface.d.ts +1 -1
  107. package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
  108. package/dist/types/src/capabilities/settings.d.ts +1 -1
  109. package/dist/types/src/capabilities/state.d.ts +2 -2
  110. package/dist/types/src/capabilities/state.d.ts.map +1 -1
  111. package/dist/types/src/capabilities/toolkit.d.ts +5 -0
  112. package/dist/types/src/capabilities/toolkit.d.ts.map +1 -0
  113. package/dist/types/src/components/Call/Call.d.ts.map +1 -1
  114. package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
  115. package/dist/types/src/components/CallDebugPanel.d.ts.map +1 -1
  116. package/dist/types/src/components/CallSidebar.d.ts.map +1 -1
  117. package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
  118. package/dist/types/src/components/ChannelContainer.stories.d.ts +87 -3
  119. package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
  120. package/dist/types/src/components/Chat.stories.d.ts +89 -4
  121. package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
  122. package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
  123. package/dist/types/src/components/Comments.stories.d.ts +154 -3
  124. package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
  125. package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
  126. package/dist/types/src/components/CommentsThreadContainer.d.ts +2 -2
  127. package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -1
  128. package/dist/types/src/components/Lobby/Lobby.d.ts.map +1 -1
  129. package/dist/types/src/components/Media/VideoObject.d.ts +1 -1
  130. package/dist/types/src/components/Media/VideoObject.stories.d.ts +15 -3
  131. package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
  132. package/dist/types/src/components/MessageContainer.d.ts +4 -1
  133. package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
  134. package/dist/types/src/components/Participant/Participant.d.ts.map +1 -1
  135. package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +1 -1
  136. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +152 -2
  137. package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
  138. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +154 -3
  139. package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
  140. package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
  141. package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
  142. package/dist/types/src/components/command-extension.d.ts.map +1 -1
  143. package/dist/types/src/components/testing.d.ts +1 -0
  144. package/dist/types/src/components/testing.d.ts.map +1 -1
  145. package/dist/types/src/extensions/threads.d.ts +2 -2
  146. package/dist/types/src/extensions/threads.d.ts.map +1 -1
  147. package/dist/types/src/hooks/index.d.ts +1 -0
  148. package/dist/types/src/hooks/index.d.ts.map +1 -1
  149. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +2 -0
  150. package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +1 -0
  151. package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -1
  152. package/dist/types/src/translations.d.ts +1 -0
  153. package/dist/types/src/translations.d.ts.map +1 -1
  154. package/dist/types/src/types/schema.d.ts +122 -107
  155. package/dist/types/src/types/schema.d.ts.map +1 -1
  156. package/dist/types/src/types/types.d.ts +253 -168
  157. package/dist/types/src/types/types.d.ts.map +1 -1
  158. package/dist/types/tsconfig.tsbuildinfo +1 -1
  159. package/package.json +51 -47
  160. package/src/ThreadPlugin.tsx +9 -2
  161. package/src/calls/call-manager.ts +1 -1
  162. package/src/calls/call-swarm-synchronizer.ts +1 -1
  163. package/src/calls/media-manager.ts +58 -33
  164. package/src/calls/types.ts +1 -1
  165. package/src/calls/util/calls-service.ts +56 -10
  166. package/src/calls/util/stub-media-streams.ts +4 -5
  167. package/src/calls-service.stories.tsx +76 -60
  168. package/src/capabilities/app-graph-builder.ts +8 -5
  169. package/src/capabilities/call-manager.ts +3 -2
  170. package/src/capabilities/capabilities.ts +2 -2
  171. package/src/capabilities/index.ts +1 -0
  172. package/src/capabilities/intent-resolver.ts +39 -4
  173. package/src/capabilities/markdown.ts +4 -3
  174. package/src/capabilities/react-surface.tsx +5 -4
  175. package/src/capabilities/state.ts +2 -1
  176. package/src/capabilities/toolkit.ts +78 -0
  177. package/src/components/Call/Call.tsx +3 -2
  178. package/src/components/Call/Toolbar.tsx +2 -2
  179. package/src/components/CallDebugPanel.tsx +1 -1
  180. package/src/components/CallSidebar.tsx +2 -1
  181. package/src/components/ChannelContainer.stories.tsx +6 -5
  182. package/src/components/ChannelContainer.tsx +7 -6
  183. package/src/components/Chat.stories.tsx +28 -26
  184. package/src/components/ChatContainer.tsx +8 -4
  185. package/src/components/Comments.stories.tsx +33 -29
  186. package/src/components/CommentsContainer.tsx +2 -1
  187. package/src/components/CommentsThreadContainer.tsx +9 -7
  188. package/src/components/Lobby/Lobby.tsx +1 -1
  189. package/src/components/Media/VideoObject.stories.tsx +30 -27
  190. package/src/components/MessageContainer.tsx +43 -9
  191. package/src/components/Participant/Participant.tsx +13 -7
  192. package/src/components/Participant/ParticipantGrid.tsx +2 -1
  193. package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +6 -5
  194. package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +42 -39
  195. package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +1 -1
  196. package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +2 -2
  197. package/src/components/ThreadComplementary.tsx +38 -8
  198. package/src/components/ThreadSettings.tsx +2 -2
  199. package/src/components/command-extension.ts +5 -2
  200. package/src/components/testing.ts +22 -0
  201. package/src/extensions/threads.ts +6 -6
  202. package/src/hooks/index.ts +1 -0
  203. package/src/hooks/useBlackCanvasStreamTrack.tsx +27 -0
  204. package/src/hooks/useDebugMode.ts +1 -1
  205. package/src/hooks/useVideoStreamTrack.tsx +5 -2
  206. package/src/testing/stories.ts +2 -2
  207. package/src/translations.ts +1 -0
  208. package/src/types/types.ts +21 -12
  209. package/src/typings.d.ts +8 -0
  210. package/dist/lib/browser/ChannelContainer-IY2UIRLF.mjs +0 -16
  211. package/dist/lib/browser/app-graph-builder-N7BE5TYW.mjs.map +0 -7
  212. package/dist/lib/browser/call-manager-NIPDYUVD.mjs.map +0 -7
  213. package/dist/lib/browser/chunk-4OYAYON2.mjs +0 -21
  214. package/dist/lib/browser/chunk-6NSMBO3B.mjs.map +0 -7
  215. package/dist/lib/browser/chunk-ERWASUQK.mjs.map +0 -7
  216. package/dist/lib/browser/chunk-GCLD5ESP.mjs.map +0 -7
  217. package/dist/lib/browser/chunk-KWPRNHTK.mjs.map +0 -7
  218. package/dist/lib/browser/chunk-VUWC4IJM.mjs +0 -479
  219. package/dist/lib/browser/chunk-VUWC4IJM.mjs.map +0 -7
  220. package/dist/lib/browser/chunk-XLPJXUKO.mjs +0 -367
  221. package/dist/lib/browser/chunk-XLPJXUKO.mjs.map +0 -7
  222. package/dist/lib/browser/chunk-ZE7KWN36.mjs.map +0 -7
  223. package/dist/lib/browser/intent-resolver-JFGLZ6VI.mjs.map +0 -7
  224. package/dist/lib/browser/markdown-GEXBVJYN.mjs.map +0 -7
  225. package/dist/lib/browser/react-surface-YCYEFBPM.mjs.map +0 -7
  226. package/dist/lib/node-esm/app-graph-builder-VCW76Z6V.mjs.map +0 -7
  227. package/dist/lib/node-esm/call-manager-D6O5ZJJ4.mjs.map +0 -7
  228. package/dist/lib/node-esm/chunk-2MFNK53T.mjs +0 -480
  229. package/dist/lib/node-esm/chunk-2MFNK53T.mjs.map +0 -7
  230. package/dist/lib/node-esm/chunk-C3XFMUAY.mjs.map +0 -7
  231. package/dist/lib/node-esm/chunk-GW37AAM4.mjs +0 -23
  232. package/dist/lib/node-esm/chunk-IHDNQLLR.mjs.map +0 -7
  233. package/dist/lib/node-esm/chunk-J4NSON5Q.mjs +0 -368
  234. package/dist/lib/node-esm/chunk-J4NSON5Q.mjs.map +0 -7
  235. package/dist/lib/node-esm/chunk-OU5BYIDO.mjs.map +0 -7
  236. package/dist/lib/node-esm/chunk-TDFHTCZZ.mjs.map +0 -7
  237. package/dist/lib/node-esm/intent-resolver-OXGNQ44Y.mjs.map +0 -7
  238. package/dist/lib/node-esm/markdown-LIJZDK2J.mjs.map +0 -7
  239. package/dist/lib/node-esm/react-surface-IRSEKM42.mjs.map +0 -7
  240. /package/dist/lib/browser/{ChannelContainer-IY2UIRLF.mjs.map → ChannelContainer-GHDNEZT2.mjs.map} +0 -0
  241. /package/dist/lib/browser/{ChatContainer-AIGIWAUG.mjs.map → ChatContainer-42ALOWUA.mjs.map} +0 -0
  242. /package/dist/lib/browser/{react-root-X4UIVGTX.mjs.map → react-root-PTTTW2MO.mjs.map} +0 -0
  243. /package/dist/lib/browser/{settings-E32MTL7A.mjs.map → settings-GRKEID73.mjs.map} +0 -0
  244. /package/dist/lib/node-esm/{ChannelContainer-DET6T5N2.mjs.map → ChannelContainer-D5E2S6AI.mjs.map} +0 -0
  245. /package/dist/lib/node-esm/{ChatContainer-IQUWU426.mjs.map → ChatContainer-4EGHKHIU.mjs.map} +0 -0
  246. /package/dist/lib/node-esm/{react-root-M7J6PZVW.mjs.map → react-root-2HHRRUME.mjs.map} +0 -0
  247. /package/dist/lib/node-esm/{settings-SJ24YG7M.mjs.map → settings-F2ODVNNW.mjs.map} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dxos/plugin-thread",
3
- "version": "0.8.4-main.2e9d522",
3
+ "version": "0.8.4-main.5ea62a8",
4
4
  "description": "DXOS Threads Surface plugin",
5
5
  "homepage": "https://dxos.org",
6
6
  "bugs": "https://github.com/dxos/dxos/issues",
@@ -10,11 +10,13 @@
10
10
  "type": "module",
11
11
  "exports": {
12
12
  ".": {
13
+ "source": "./src/index.ts",
13
14
  "types": "./dist/types/src/index.d.ts",
14
15
  "browser": "./dist/lib/browser/index.mjs",
15
16
  "node": "./dist/lib/node-esm/index.mjs"
16
17
  },
17
18
  "./types": {
19
+ "source": "./src/types/index.ts",
18
20
  "types": "./dist/types/src/types/index.d.ts",
19
21
  "browser": "./dist/lib/browser/types/index.mjs",
20
22
  "node": "./dist/lib/node-esm/types/index.mjs"
@@ -36,6 +38,7 @@
36
38
  "@codemirror/language": "^6.10.3",
37
39
  "@codemirror/state": "^6.4.1",
38
40
  "@codemirror/view": "^6.34.1",
41
+ "@effect/ai": "0.25.2",
39
42
  "@peermetrics/webrtc-stats": "5.7.1",
40
43
  "@preact-signals/safe-react": "^0.9.0",
41
44
  "@preact/signals-core": "^1.9.0",
@@ -43,58 +46,59 @@
43
46
  "extendable-media-recorder": "^9.2.19",
44
47
  "extendable-media-recorder-wav-encoder": "^7.0.123",
45
48
  "md5-hex": "5.0.0",
46
- "react-resize-detector": "^12.0.2",
49
+ "react-resize-detector": "^11.0.1",
47
50
  "wavefile": "^11.0.0",
48
- "@dxos/app-framework": "0.8.4-main.2e9d522",
49
- "@dxos/async": "0.8.4-main.2e9d522",
50
- "@dxos/context": "0.8.4-main.2e9d522",
51
- "@dxos/codec-protobuf": "0.8.4-main.2e9d522",
52
- "@dxos/debug": "0.8.4-main.2e9d522",
53
- "@dxos/devtools": "0.8.4-main.2e9d522",
54
- "@dxos/echo": "0.8.4-main.2e9d522",
55
- "@dxos/display-name": "0.8.4-main.2e9d522",
56
- "@dxos/echo-schema": "0.8.4-main.2e9d522",
57
- "@dxos/invariant": "0.8.4-main.2e9d522",
58
- "@dxos/keys": "0.8.4-main.2e9d522",
59
- "@dxos/live-object": "0.8.4-main.2e9d522",
60
- "@dxos/local-storage": "0.8.4-main.2e9d522",
61
- "@dxos/log": "0.8.4-main.2e9d522",
62
- "@dxos/plugin-attention": "0.8.4-main.2e9d522",
63
- "@dxos/plugin-client": "0.8.4-main.2e9d522",
64
- "@dxos/plugin-deck": "0.8.4-main.2e9d522",
65
- "@dxos/plugin-graph": "0.8.4-main.2e9d522",
66
- "@dxos/plugin-markdown": "0.8.4-main.2e9d522",
67
- "@dxos/plugin-observability": "0.8.4-main.2e9d522",
68
- "@dxos/protocols": "0.8.4-main.2e9d522",
69
- "@dxos/plugin-space": "0.8.4-main.2e9d522",
70
- "@dxos/react-client": "0.8.4-main.2e9d522",
71
- "@dxos/react-ui-attention": "0.8.4-main.2e9d522",
72
- "@dxos/react-ui-dnd": "0.8.4-main.2e9d522",
73
- "@dxos/react-ui-editor": "0.8.4-main.2e9d522",
74
- "@dxos/react-ui-form": "0.8.4-main.2e9d522",
75
- "@dxos/react-ui-menu": "0.8.4-main.2e9d522",
76
- "@dxos/react-ui-sfx": "0.8.4-main.2e9d522",
77
- "@dxos/react-ui-stack": "0.8.4-main.2e9d522",
78
- "@dxos/react-ui-tabs": "0.8.4-main.2e9d522",
79
- "@dxos/react-ui-syntax-highlighter": "0.8.4-main.2e9d522",
80
- "@dxos/react-ui-thread": "0.8.4-main.2e9d522",
81
- "@dxos/schema": "0.8.4-main.2e9d522",
82
- "@dxos/util": "0.8.4-main.2e9d522"
51
+ "@dxos/app-framework": "0.8.4-main.5ea62a8",
52
+ "@dxos/assistant": "0.8.4-main.5ea62a8",
53
+ "@dxos/async": "0.8.4-main.5ea62a8",
54
+ "@dxos/debug": "0.8.4-main.5ea62a8",
55
+ "@dxos/devtools": "0.8.4-main.5ea62a8",
56
+ "@dxos/codec-protobuf": "0.8.4-main.5ea62a8",
57
+ "@dxos/display-name": "0.8.4-main.5ea62a8",
58
+ "@dxos/echo": "0.8.4-main.5ea62a8",
59
+ "@dxos/echo-schema": "0.8.4-main.5ea62a8",
60
+ "@dxos/invariant": "0.8.4-main.5ea62a8",
61
+ "@dxos/keys": "0.8.4-main.5ea62a8",
62
+ "@dxos/live-object": "0.8.4-main.5ea62a8",
63
+ "@dxos/context": "0.8.4-main.5ea62a8",
64
+ "@dxos/log": "0.8.4-main.5ea62a8",
65
+ "@dxos/local-storage": "0.8.4-main.5ea62a8",
66
+ "@dxos/plugin-attention": "0.8.4-main.5ea62a8",
67
+ "@dxos/plugin-deck": "0.8.4-main.5ea62a8",
68
+ "@dxos/plugin-graph": "0.8.4-main.5ea62a8",
69
+ "@dxos/plugin-markdown": "0.8.4-main.5ea62a8",
70
+ "@dxos/plugin-observability": "0.8.4-main.5ea62a8",
71
+ "@dxos/plugin-client": "0.8.4-main.5ea62a8",
72
+ "@dxos/plugin-space": "0.8.4-main.5ea62a8",
73
+ "@dxos/protocols": "0.8.4-main.5ea62a8",
74
+ "@dxos/react-client": "0.8.4-main.5ea62a8",
75
+ "@dxos/react-ui-dnd": "0.8.4-main.5ea62a8",
76
+ "@dxos/react-ui-editor": "0.8.4-main.5ea62a8",
77
+ "@dxos/react-ui-form": "0.8.4-main.5ea62a8",
78
+ "@dxos/react-ui-attention": "0.8.4-main.5ea62a8",
79
+ "@dxos/react-ui-menu": "0.8.4-main.5ea62a8",
80
+ "@dxos/react-ui-stack": "0.8.4-main.5ea62a8",
81
+ "@dxos/react-ui-sfx": "0.8.4-main.5ea62a8",
82
+ "@dxos/react-ui-syntax-highlighter": "0.8.4-main.5ea62a8",
83
+ "@dxos/react-ui-tabs": "0.8.4-main.5ea62a8",
84
+ "@dxos/schema": "0.8.4-main.5ea62a8",
85
+ "@dxos/util": "0.8.4-main.5ea62a8",
86
+ "@dxos/react-ui-thread": "0.8.4-main.5ea62a8"
83
87
  },
84
88
  "devDependencies": {
85
89
  "@effect-rx/rx-react": "0.38.0",
86
- "@effect/platform": "0.89.0",
90
+ "@effect/platform": "0.90.2",
87
91
  "@types/react": "~18.2.0",
88
92
  "@types/react-dom": "~18.2.0",
89
- "effect": "3.17.0",
93
+ "effect": "3.17.7",
90
94
  "react": "~18.2.0",
91
95
  "react-dom": "~18.2.0",
92
- "vite": "5.4.7",
93
- "@dxos/plugin-theme": "0.8.4-main.2e9d522",
94
- "@dxos/random": "0.8.4-main.2e9d522",
95
- "@dxos/react-ui": "0.8.4-main.2e9d522",
96
- "@dxos/storybook-utils": "0.8.4-main.2e9d522",
97
- "@dxos/react-ui-theme": "0.8.4-main.2e9d522"
96
+ "vite": "7.1.1",
97
+ "@dxos/plugin-theme": "0.8.4-main.5ea62a8",
98
+ "@dxos/random": "0.8.4-main.5ea62a8",
99
+ "@dxos/react-ui": "0.8.4-main.5ea62a8",
100
+ "@dxos/react-ui-theme": "0.8.4-main.5ea62a8",
101
+ "@dxos/storybook-utils": "0.8.4-main.5ea62a8"
98
102
  },
99
103
  "peerDependencies": {
100
104
  "@effect-rx/rx-react": "^0.34.1",
@@ -102,8 +106,8 @@
102
106
  "effect": "^3.13.3",
103
107
  "react": "~18.2.0",
104
108
  "react-dom": "~18.2.0",
105
- "@dxos/react-ui": "0.8.4-main.2e9d522",
106
- "@dxos/react-ui-theme": "0.8.4-main.2e9d522"
109
+ "@dxos/react-ui": "0.8.4-main.5ea62a8",
110
+ "@dxos/react-ui-theme": "0.8.4-main.5ea62a8"
107
111
  },
108
112
  "publishConfig": {
109
113
  "access": "public"
@@ -2,7 +2,7 @@
2
2
  // Copyright 2023 DXOS.org
3
3
  //
4
4
 
5
- import { Capabilities, contributes, createIntent, defineModule, definePlugin, Events } from '@dxos/app-framework';
5
+ import { Capabilities, Events, contributes, createIntent, defineModule, definePlugin } from '@dxos/app-framework';
6
6
  import { Ref } from '@dxos/echo';
7
7
  import { ClientCapabilities, ClientEvents } from '@dxos/plugin-client';
8
8
  import { MarkdownEvents } from '@dxos/plugin-markdown';
@@ -19,8 +19,9 @@ import {
19
19
  ReactRoot,
20
20
  ReactSurface,
21
21
  ThreadState,
22
+ Toolkit,
22
23
  } from './capabilities';
23
- import { meta, THREAD_ITEM } from './meta';
24
+ import { THREAD_ITEM, meta } from './meta';
24
25
  import { translations } from './translations';
25
26
  import { ChannelType, ThreadAction, ThreadType } from './types';
26
27
 
@@ -152,4 +153,10 @@ export const ThreadPlugin = () =>
152
153
  activatesOn: Events.SetupAppGraph,
153
154
  activate: AppGraphBuilder,
154
155
  }),
156
+ defineModule({
157
+ id: `${meta.id}/module/toolkit`,
158
+ // TODO(wittjosiah): Shouldn't use the startup event.
159
+ activatesOn: Events.Startup,
160
+ activate: Toolkit,
161
+ }),
155
162
  ]);
@@ -12,7 +12,7 @@ import { live } from '@dxos/live-object';
12
12
  import { type Tracks } from '@dxos/protocols/proto/dxos/edge/calls';
13
13
  import { isNonNullable } from '@dxos/util';
14
14
 
15
- import { CallSwarmSynchronizer, type CallState } from './call-swarm-synchronizer';
15
+ import { type CallState, CallSwarmSynchronizer } from './call-swarm-synchronizer';
16
16
  import { MediaManager, type MediaState } from './media-manager';
17
17
  import { type ActivityState, CALLS_URL, type EncodedTrackName, TrackNameCodec, type UserState } from './types';
18
18
 
@@ -17,7 +17,7 @@ import { type Device, type NetworkService } from '@dxos/protocols/proto/dxos/cli
17
17
  import { ConnectionState, type SwarmResponse } from '@dxos/protocols/proto/dxos/edge/messenger';
18
18
  import { isNonNullable } from '@dxos/util';
19
19
 
20
- import { codec, type ActivityState, type UserState } from './types';
20
+ import { type ActivityState, type UserState, codec } from './types';
21
21
 
22
22
  export type CallState = {
23
23
  /**
@@ -3,11 +3,12 @@
3
3
  //
4
4
 
5
5
  import { DeferredTask, Event, sleep, synchronized } from '@dxos/async';
6
- import { cancelWithContext, type Context, Resource } from '@dxos/context';
6
+ import { type Context, Resource, cancelWithContext } from '@dxos/context';
7
+ import { invariant } from '@dxos/invariant';
7
8
  import { log } from '@dxos/log';
8
9
 
9
10
  import { SpeakingMonitor } from './speaking-monitor';
10
- import { TrackNameCodec, type EncodedTrackName, type TrackObject } from './types';
11
+ import { type EncodedTrackName, TrackNameCodec, type TrackObject } from './types';
11
12
  import {
12
13
  type CallsServiceConfig,
13
14
  CallsServicePeer,
@@ -48,13 +49,13 @@ 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>();
@@ -248,7 +249,7 @@ export class MediaManager extends Resource {
248
249
  });
249
250
 
250
251
  // Pull new tracks.
251
- await Promise.all(tracksToPull.map((name) => this._pullTrack(name)));
252
+ const pullResults = await Promise.all(tracksToPull.map((name) => this._pullTrack(name)));
252
253
 
253
254
  // Close old tracks.
254
255
  await Promise.all([...audioTracksToClose, ...videoStreamsToClose].map(([_, { ctx }]) => ctx.dispose()));
@@ -258,6 +259,13 @@ export class MediaManager extends Resource {
258
259
  currentVideoStreams: Object.keys(this._state.pulledVideoStreams),
259
260
  });
260
261
  this.stateUpdated.emit(this._state);
262
+
263
+ if (pullResults.some(({ shouldRetry }) => shouldRetry)) {
264
+ await cancelWithContext(this._ctx, sleep(RETRY_INTERVAL));
265
+ log.info('retrying pull tracks', { tracksToPull });
266
+ invariant(this._pullTracksTask);
267
+ this._pullTracksTask.schedule();
268
+ }
261
269
  }
262
270
 
263
271
  private async _pushTracks(): Promise<void> {
@@ -266,34 +274,42 @@ export class MediaManager extends Resource {
266
274
  }
267
275
 
268
276
  let updated = false;
269
- const [pushedVideoTrack, pushedAudioTrack, pushedScreenshareTrack] = await Promise.all([
270
- this._pushTrack(this._state.videoTrack, this._state.pushedVideoTrack, [
277
+ const [pushVideoResult, pushAudioResult, pushScreenshareResult] = await Promise.all([
278
+ this._maybePushTrack(this._state.videoTrack, this._state.pushedVideoTrack, [
271
279
  { maxFramerate: MAX_WEB_CAM_FRAMERATE, maxBitrate: MAX_WEB_CAM_BITRATE },
272
280
  ]),
273
- this._pushTrack(this._state.audioTrack, this._state.pushedAudioTrack, [{ networkPriority: 'high' }]),
274
- this._pushTrack(this._state.screenshareTrack, this._state.pushedScreenshareTrack),
281
+ this._maybePushTrack(this._state.audioTrack, this._state.pushedAudioTrack, [{ networkPriority: 'high' }]),
282
+ this._maybePushTrack(this._state.screenshareTrack, this._state.pushedScreenshareTrack),
275
283
  ]);
276
284
 
277
- if (pushedVideoTrack !== this._state.pushedVideoTrack) {
278
- this._state.pushedVideoTrack = pushedVideoTrack;
285
+ if (pushVideoResult.track !== this._state.pushedVideoTrack) {
286
+ this._state.pushedVideoTrack = pushVideoResult.track;
279
287
  updated = true;
280
288
  }
281
- if (pushedAudioTrack !== this._state.pushedAudioTrack) {
282
- this._state.pushedAudioTrack = pushedAudioTrack;
289
+ if (pushAudioResult.track !== this._state.pushedAudioTrack) {
290
+ this._state.pushedAudioTrack = pushAudioResult.track;
283
291
  updated = true;
284
292
  }
285
- if (pushedScreenshareTrack !== this._state.pushedScreenshareTrack) {
286
- this._state.pushedScreenshareTrack = pushedScreenshareTrack;
293
+ if (pushScreenshareResult.track !== this._state.pushedScreenshareTrack) {
294
+ this._state.pushedScreenshareTrack = pushScreenshareResult.track;
287
295
  updated = true;
288
296
  }
289
- if (!updated) {
290
- return;
297
+
298
+ const shouldRetry = pushVideoResult.shouldRetry || pushAudioResult.shouldRetry || pushScreenshareResult.shouldRetry;
299
+
300
+ if (updated) {
301
+ this.stateUpdated.emit(this._state);
291
302
  }
292
303
 
293
- this.stateUpdated.emit(this._state);
304
+ if (shouldRetry) {
305
+ await cancelWithContext(this._ctx, sleep(RETRY_INTERVAL));
306
+ log.info('retrying push tracks', { pushVideoResult, pushAudioResult, pushScreenshareResult });
307
+ invariant(this._pushTracksTask);
308
+ this._pushTracksTask.schedule();
309
+ }
294
310
  }
295
311
 
296
- private async _pullTrack(name: EncodedTrackName): Promise<void> {
312
+ private async _pullTrack(name: EncodedTrackName): Promise<{ shouldRetry: boolean }> {
297
313
  const ctx = this._ctx.derive();
298
314
  try {
299
315
  const trackData = TrackNameCodec.decode(name);
@@ -306,7 +322,7 @@ export class MediaManager extends Resource {
306
322
  case 'audio': {
307
323
  this._state.pulledAudioTracks[name] = { track, ctx };
308
324
  ctx.onDispose(() => delete this._state.pulledAudioTracks[name]);
309
- break;
325
+ return { shouldRetry: false };
310
326
  }
311
327
  case 'video': {
312
328
  const mediaStream = new MediaStream();
@@ -317,33 +333,42 @@ export class MediaManager extends Resource {
317
333
  track.stop();
318
334
  delete this._state.pulledVideoStreams[name];
319
335
  });
320
- break;
336
+ return { shouldRetry: false };
321
337
  }
322
338
  default:
323
339
  throw new Error(`Invalid track kind: ${track?.kind}`);
324
340
  }
325
341
  } catch (err) {
326
- log.verbose('failed to pull track', { err, name });
342
+ log.info('failed to pull track', { err, name });
327
343
  void ctx.dispose();
328
- await cancelWithContext(this._ctx, sleep(RETRY_INTERVAL));
329
- log.verbose('retrying pull track', { name });
330
- this._pullTracksTask!.schedule();
344
+ return { shouldRetry: true };
331
345
  }
332
346
  }
333
347
 
334
- private async _pushTrack(
348
+ private async _maybePushTrack(
335
349
  track?: MediaStreamTrack,
336
350
  previousTrack?: TrackObject,
337
351
  encodings?: RTCRtpEncodingParameters[],
338
- ): Promise<TrackObject | undefined> {
352
+ ): Promise<{ track?: TrackObject; shouldRetry?: boolean }> {
339
353
  if (!track && !previousTrack) {
340
- return;
354
+ return { track: undefined };
341
355
  }
342
356
 
343
- return this._state.peer!.pushTrack({
344
- track: track ?? null,
345
- previousTrack,
346
- encodings,
347
- });
357
+ const ctx = this._ctx.derive();
358
+
359
+ try {
360
+ return {
361
+ track: await this._state.peer!.pushTrack({
362
+ ctx,
363
+ track: track ?? null,
364
+ previousTrack,
365
+ encodings,
366
+ }),
367
+ };
368
+ } catch (err) {
369
+ log.info('failed to push track', { err, track, previousTrack, encodings });
370
+ void ctx.dispose();
371
+ return { shouldRetry: true };
372
+ }
348
373
  }
349
374
  }
@@ -5,8 +5,8 @@
5
5
  import { buf } from '@dxos/protocols/buf';
6
6
  import {
7
7
  type ActivitySchema,
8
- UserStateSchema,
9
8
  type UserState as UserStateProto,
9
+ UserStateSchema,
10
10
  } from '@dxos/protocols/buf/dxos/edge/calls_pb';
11
11
 
12
12
  /**
@@ -2,21 +2,22 @@
2
2
  // Copyright 2024 DXOS.org
3
3
  //
4
4
 
5
- import { PersistentLifecycle } from '@dxos/async';
5
+ import { PersistentLifecycle, Trigger, scheduleTask } from '@dxos/async';
6
6
  import { type Context, Resource } from '@dxos/context';
7
7
  import { invariant } from '@dxos/invariant';
8
8
  import { log } from '@dxos/log';
9
9
 
10
- import { HistoryCache } from './history-cache';
11
- import { BulkRequestDispatcher, FIFOScheduler } from './task-scheduling';
12
10
  import {
13
- type SessionResponse,
14
11
  type ErrorResponse,
15
12
  type RenegotiationResponse,
13
+ type SessionResponse,
16
14
  type TrackObject,
17
15
  type TracksResponse,
18
16
  } from '../types';
19
17
 
18
+ import { HistoryCache } from './history-cache';
19
+ import { BulkRequestDispatcher, FIFOScheduler } from './task-scheduling';
20
+
20
21
  const NETWORK_TIMEOUT = 5_000;
21
22
 
22
23
  export type Session = {
@@ -203,11 +204,11 @@ export class CallsServicePeer extends Resource {
203
204
  sessionId,
204
205
  trackName,
205
206
  }: {
207
+ ctx: Context;
206
208
  peerConnection: RTCPeerConnection;
207
209
  transceiver: RTCRtpTransceiver;
208
210
  sessionId: string;
209
211
  trackName: string;
210
- ctx?: Context;
211
212
  }): Promise<TrackObject | void> {
212
213
  log.verbose('pushing track ', trackName);
213
214
  const pushedTrackPromise = this.pushTrackDispatcher
@@ -245,9 +246,13 @@ export class CallsServicePeer extends Resource {
245
246
  };
246
247
  }),
247
248
  )
248
- .then(({ tracks }) => {
249
+ .then(async ({ tracks }) => {
249
250
  const trackData = tracks.find((t) => t.mid === transceiver.mid);
250
251
  if (trackData) {
252
+ // we wait for the transceiver to start sending data before we emit
253
+ // the track metadata to ensure that the track will be able to be
254
+ // pulled before making the metadata available to anyone else.
255
+ await waitForTransceiverToSendData(ctx, transceiver);
251
256
  return {
252
257
  ...trackData,
253
258
  sessionId,
@@ -256,9 +261,6 @@ export class CallsServicePeer extends Resource {
256
261
  } else {
257
262
  log.error('missing track data');
258
263
  }
259
- })
260
- .catch((err) => {
261
- log.catch(err);
262
264
  });
263
265
 
264
266
  const onDispose = async () => {
@@ -280,8 +282,8 @@ export class CallsServicePeer extends Resource {
280
282
  previousTrack,
281
283
  }: {
282
284
  track: MediaStreamTrack | null;
285
+ ctx: Context;
283
286
  encodings?: RTCRtpEncodingParameters[];
284
- ctx?: Context;
285
287
  previousTrack?: TrackObject;
286
288
  }): Promise<TrackObject | undefined> {
287
289
  await this.waitUntilOpen();
@@ -528,3 +530,47 @@ const peerConnectionIsConnected = async (peerConnection: RTCPeerConnection) => {
528
530
  await connected;
529
531
  }
530
532
  };
533
+
534
+ const INITIAL_DELAY = 50;
535
+ const MAX_DELAY = 500;
536
+ const MAX_RETRIES = 50;
537
+ const WAIT_FOR_DATA_TIMEOUT = 20_000;
538
+
539
+ const waitForTransceiverToSendData = async (ctx: Context, transceiver: RTCRtpTransceiver): Promise<void> => {
540
+ let delay = INITIAL_DELAY;
541
+ let checks = 0;
542
+ const waitForData = new Trigger();
543
+ ctx.onDispose(() => waitForData.throw(new Error('Transceiver was closed')));
544
+
545
+ const checkStats = async () => {
546
+ if (ctx.disposed) return;
547
+
548
+ try {
549
+ const stats = await transceiver.sender.getStats();
550
+ let dataFound = false;
551
+ stats.forEach((stat) => {
552
+ if (stat.type === 'outbound-rtp' && stat.bytesSent > 0) {
553
+ dataFound = true;
554
+ }
555
+ });
556
+
557
+ if (dataFound) {
558
+ waitForData.wake();
559
+ return;
560
+ }
561
+ } catch {
562
+ // Stats might not be available yet, continue checking
563
+ }
564
+ checks++;
565
+ if (checks > MAX_RETRIES) {
566
+ waitForData.throw(new Error('Transceiver did not send data'));
567
+ return;
568
+ }
569
+
570
+ delay = Math.min(delay * 2, MAX_DELAY); // Exponential backoff with max cap
571
+ scheduleTask(ctx, checkStats, delay);
572
+ };
573
+
574
+ void checkStats();
575
+ return waitForData.wait({ timeout: WAIT_FOR_DATA_TIMEOUT });
576
+ };
@@ -3,8 +3,8 @@
3
3
  //
4
4
  //
5
5
 
6
- import { waitForCondition, scheduleTaskInterval } from '@dxos/async';
7
- import { cancelWithContext, type Context } from '@dxos/context';
6
+ import { scheduleTaskInterval, waitForCondition } from '@dxos/async';
7
+ import { type Context, cancelWithContext } from '@dxos/context';
8
8
  import { invariant } from '@dxos/invariant';
9
9
 
10
10
  /**
@@ -30,7 +30,7 @@ export const createBlackCanvasStreamTrack = async ({
30
30
  canvasCtx.fillStyle = 'black';
31
31
  canvasCtx.fillRect(0, 0, canvas.width, canvas.height);
32
32
  };
33
- scheduleTaskInterval(ctx, async () => drawFrame(), 1_000);
33
+ scheduleTaskInterval(ctx, async () => drawFrame(), 200);
34
34
 
35
35
  const track = canvas.captureStream().getVideoTracks()[0];
36
36
  drawFrame();
@@ -52,8 +52,7 @@ export const createInaudibleAudioStreamTrack = async ({ ctx }: { ctx: Context })
52
52
  oscillator.frequency.setValueAtTime(20, audioContext.currentTime);
53
53
 
54
54
  const gainNode = audioContext.createGain();
55
- // even w/ gain at 0 some packets are sent
56
- gainNode.gain.setValueAtTime(0.02, audioContext.currentTime);
55
+ gainNode.gain.setValueAtTime(0.01, audioContext.currentTime);
57
56
  oscillator.connect(gainNode);
58
57
 
59
58
  const destination = audioContext.createMediaStreamDestination();