@dxos/plugin-thread 0.8.4-main.67995b8 → 0.8.4-main.dedc0f3
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.
- package/dist/lib/browser/ChannelContainer-4PYFOIDK.mjs +16 -0
- package/dist/lib/browser/{ChatContainer-AIGIWAUG.mjs → ChatContainer-EXNNREYB.mjs} +4 -4
- package/dist/lib/browser/{app-graph-builder-N7BE5TYW.mjs → app-graph-builder-FHAOPO57.mjs} +5 -5
- package/dist/lib/browser/app-graph-builder-FHAOPO57.mjs.map +7 -0
- package/dist/lib/browser/{call-manager-NIPDYUVD.mjs → call-manager-RMPTWSTF.mjs} +4 -4
- package/dist/lib/browser/call-manager-RMPTWSTF.mjs.map +7 -0
- package/dist/lib/browser/{chunk-LGSDKXPF.mjs → chunk-4APCDRSH.mjs} +1 -1
- package/dist/lib/browser/{chunk-LGSDKXPF.mjs.map → chunk-4APCDRSH.mjs.map} +1 -1
- package/dist/lib/browser/{chunk-KWPRNHTK.mjs → chunk-7W7QK5ZP.mjs} +232 -230
- package/dist/lib/browser/chunk-7W7QK5ZP.mjs.map +7 -0
- package/dist/lib/browser/chunk-G4CNILRR.mjs +23 -0
- package/dist/lib/browser/{chunk-FR7KJPNY.mjs.map → chunk-G4CNILRR.mjs.map} +3 -3
- package/dist/lib/browser/{chunk-GCLD5ESP.mjs → chunk-KTWYVC5X.mjs} +22 -12
- package/dist/lib/browser/chunk-KTWYVC5X.mjs.map +7 -0
- package/dist/lib/browser/chunk-PBMNFG3B.mjs +376 -0
- package/dist/lib/browser/chunk-PBMNFG3B.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ERWASUQK.mjs → chunk-RI3Z6MK3.mjs} +38 -6
- package/dist/lib/{node-esm/chunk-25ABSYP2.mjs.map → browser/chunk-RI3Z6MK3.mjs.map} +4 -4
- package/dist/lib/browser/{chunk-6NSMBO3B.mjs → chunk-XYUJXHYV.mjs} +55 -5
- package/dist/lib/browser/chunk-XYUJXHYV.mjs.map +7 -0
- package/dist/lib/browser/{chunk-ZE7KWN36.mjs → chunk-ZCEU5K23.mjs} +461 -240
- package/dist/lib/browser/chunk-ZCEU5K23.mjs.map +7 -0
- package/dist/lib/browser/chunk-ZH2WPTNP.mjs +618 -0
- package/dist/lib/browser/chunk-ZH2WPTNP.mjs.map +7 -0
- package/dist/lib/browser/index.mjs +20 -9
- package/dist/lib/browser/index.mjs.map +3 -3
- package/dist/lib/browser/{intent-resolver-JFGLZ6VI.mjs → intent-resolver-J7OCP2P6.mjs} +67 -9
- package/dist/lib/browser/intent-resolver-J7OCP2P6.mjs.map +7 -0
- package/dist/lib/browser/{markdown-M3FMR7OD.mjs → markdown-Z677YORA.mjs} +4 -4
- package/dist/lib/browser/markdown-Z677YORA.mjs.map +7 -0
- package/dist/lib/browser/meta.json +1 -1
- package/dist/lib/browser/{react-root-JEUSQXI6.mjs → react-root-XKOD4KRB.mjs} +9 -9
- package/dist/lib/browser/{react-surface-XWS6GIZY.mjs → react-surface-GVGZRBDK.mjs} +9 -9
- package/dist/lib/browser/react-surface-GVGZRBDK.mjs.map +7 -0
- package/dist/lib/browser/{settings-E32MTL7A.mjs → settings-GRKEID73.mjs} +2 -2
- package/dist/lib/browser/{state-H6CYONWE.mjs → state-2T4KDWBX.mjs} +2 -2
- package/dist/lib/browser/{state-H6CYONWE.mjs.map → state-2T4KDWBX.mjs.map} +2 -2
- package/dist/lib/browser/toolkit-KUPIIFC6.mjs +80 -0
- package/dist/lib/browser/toolkit-KUPIIFC6.mjs.map +7 -0
- package/dist/lib/browser/types/index.mjs +1 -1
- package/dist/lib/node-esm/{ChannelContainer-7FXCKO7X.mjs → ChannelContainer-KQQEZWUN.mjs} +7 -7
- package/dist/lib/node-esm/{ChatContainer-IQUWU426.mjs → ChatContainer-QVQKFBWA.mjs} +4 -4
- package/dist/lib/node-esm/{app-graph-builder-VCW76Z6V.mjs → app-graph-builder-XEYWX5FC.mjs} +5 -5
- package/dist/lib/node-esm/app-graph-builder-XEYWX5FC.mjs.map +7 -0
- package/dist/lib/node-esm/{call-manager-D6O5ZJJ4.mjs → call-manager-QAREJFVX.mjs} +4 -4
- package/dist/lib/node-esm/call-manager-QAREJFVX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-OU5BYIDO.mjs → chunk-2V3WSLUZ.mjs} +55 -5
- package/dist/lib/node-esm/chunk-2V3WSLUZ.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-4T45PCKP.mjs +25 -0
- package/dist/lib/node-esm/{chunk-2CXOK2TD.mjs.map → chunk-4T45PCKP.mjs.map} +3 -3
- package/dist/lib/node-esm/chunk-DKCQCENK.mjs +377 -0
- package/dist/lib/node-esm/chunk-DKCQCENK.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-25ABSYP2.mjs → chunk-JNPKMT7O.mjs} +38 -6
- package/dist/lib/node-esm/chunk-JNPKMT7O.mjs.map +7 -0
- package/dist/lib/node-esm/chunk-LE2LIYGX.mjs +619 -0
- package/dist/lib/node-esm/chunk-LE2LIYGX.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-TDFHTCZZ.mjs → chunk-P6E247RF.mjs} +22 -12
- package/dist/lib/node-esm/chunk-P6E247RF.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-75RJ5DJI.mjs → chunk-PYTVBN5J.mjs} +1 -1
- package/dist/lib/node-esm/{chunk-75RJ5DJI.mjs.map → chunk-PYTVBN5J.mjs.map} +1 -1
- package/dist/lib/node-esm/{chunk-C3XFMUAY.mjs → chunk-SNKFZQST.mjs} +232 -230
- package/dist/lib/node-esm/chunk-SNKFZQST.mjs.map +7 -0
- package/dist/lib/node-esm/{chunk-IHDNQLLR.mjs → chunk-TIPIOH2J.mjs} +461 -240
- package/dist/lib/node-esm/chunk-TIPIOH2J.mjs.map +7 -0
- package/dist/lib/node-esm/index.mjs +20 -9
- package/dist/lib/node-esm/index.mjs.map +3 -3
- package/dist/lib/node-esm/{intent-resolver-OXGNQ44Y.mjs → intent-resolver-SR2LW4HF.mjs} +67 -9
- package/dist/lib/node-esm/intent-resolver-SR2LW4HF.mjs.map +7 -0
- package/dist/lib/node-esm/{markdown-INKTE4MH.mjs → markdown-FL4IXLRP.mjs} +4 -4
- package/dist/lib/node-esm/markdown-FL4IXLRP.mjs.map +7 -0
- package/dist/lib/node-esm/meta.json +1 -1
- package/dist/lib/node-esm/{react-root-XYYY2JXZ.mjs → react-root-4JWDRIQB.mjs} +9 -9
- package/dist/lib/node-esm/{react-surface-MJ33KPYE.mjs → react-surface-WLQUVRAX.mjs} +9 -9
- package/dist/lib/node-esm/react-surface-WLQUVRAX.mjs.map +7 -0
- package/dist/lib/node-esm/{settings-SJ24YG7M.mjs → settings-F2ODVNNW.mjs} +2 -2
- package/dist/lib/node-esm/{state-D7WNDT3N.mjs → state-62TQKQVB.mjs} +2 -2
- package/dist/lib/node-esm/{state-D7WNDT3N.mjs.map → state-62TQKQVB.mjs.map} +2 -2
- package/dist/lib/node-esm/toolkit-KZIS7G36.mjs +81 -0
- package/dist/lib/node-esm/toolkit-KZIS7G36.mjs.map +7 -0
- package/dist/lib/node-esm/types/index.mjs +1 -1
- package/dist/types/src/ThreadPlugin.d.ts.map +1 -1
- package/dist/types/src/calls/call-manager.d.ts.map +1 -1
- package/dist/types/src/calls/call-swarm-synchronizer.d.ts.map +1 -1
- package/dist/types/src/calls/media-manager.d.ts +1 -1
- package/dist/types/src/calls/media-manager.d.ts.map +1 -1
- package/dist/types/src/calls/types.d.ts +1 -1
- package/dist/types/src/calls/types.d.ts.map +1 -1
- package/dist/types/src/calls/util/calls-service.d.ts +4 -2
- package/dist/types/src/calls/util/calls-service.d.ts.map +1 -1
- package/dist/types/src/calls/util/stub-media-streams.d.ts.map +1 -1
- package/dist/types/src/calls-service.stories.d.ts +10 -8
- package/dist/types/src/calls-service.stories.d.ts.map +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts +1 -1
- package/dist/types/src/capabilities/app-graph-builder.d.ts.map +1 -1
- package/dist/types/src/capabilities/call-manager.d.ts +1 -1
- package/dist/types/src/capabilities/call-manager.d.ts.map +1 -1
- package/dist/types/src/capabilities/capabilities.d.ts +2 -2
- package/dist/types/src/capabilities/capabilities.d.ts.map +1 -1
- package/dist/types/src/capabilities/index.d.ts +11 -10
- package/dist/types/src/capabilities/index.d.ts.map +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts +1 -1
- package/dist/types/src/capabilities/intent-resolver.d.ts.map +1 -1
- package/dist/types/src/capabilities/markdown.d.ts +1 -1
- package/dist/types/src/capabilities/markdown.d.ts.map +1 -1
- package/dist/types/src/capabilities/react-root.d.ts +2 -2
- package/dist/types/src/capabilities/react-surface.d.ts +1 -1
- package/dist/types/src/capabilities/react-surface.d.ts.map +1 -1
- package/dist/types/src/capabilities/settings.d.ts +1 -1
- package/dist/types/src/capabilities/state.d.ts +2 -2
- package/dist/types/src/capabilities/state.d.ts.map +1 -1
- package/dist/types/src/capabilities/toolkit.d.ts +5 -0
- package/dist/types/src/capabilities/toolkit.d.ts.map +1 -0
- package/dist/types/src/components/Call/Call.d.ts.map +1 -1
- package/dist/types/src/components/Call/Toolbar.d.ts.map +1 -1
- package/dist/types/src/components/CallDebugPanel.d.ts +7 -0
- package/dist/types/src/components/CallDebugPanel.d.ts.map +1 -1
- package/dist/types/src/components/CallSidebar.d.ts.map +1 -1
- package/dist/types/src/components/ChannelContainer.d.ts.map +1 -1
- package/dist/types/src/components/ChannelContainer.stories.d.ts +88 -3
- package/dist/types/src/components/ChannelContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/Chat.stories.d.ts +90 -4
- package/dist/types/src/components/Chat.stories.d.ts.map +1 -1
- package/dist/types/src/components/ChatContainer.d.ts.map +1 -1
- package/dist/types/src/components/Comments.stories.d.ts +156 -3
- package/dist/types/src/components/Comments.stories.d.ts.map +1 -1
- package/dist/types/src/components/CommentsContainer.d.ts.map +1 -1
- package/dist/types/src/components/CommentsThreadContainer.d.ts +2 -2
- package/dist/types/src/components/CommentsThreadContainer.d.ts.map +1 -1
- package/dist/types/src/components/Lobby/Lobby.d.ts.map +1 -1
- package/dist/types/src/components/Media/VideoObject.d.ts +1 -1
- package/dist/types/src/components/Media/VideoObject.stories.d.ts +15 -3
- package/dist/types/src/components/Media/VideoObject.stories.d.ts.map +1 -1
- package/dist/types/src/components/MessageContainer.d.ts +4 -1
- package/dist/types/src/components/MessageContainer.d.ts.map +1 -1
- package/dist/types/src/components/Participant/Participant.d.ts.map +1 -1
- package/dist/types/src/components/Participant/ParticipantGrid.d.ts.map +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts +154 -2
- package/dist/types/src/components/ResponsiveGrid/ResponsiveContainer.stories.d.ts.map +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts +156 -3
- package/dist/types/src/components/ResponsiveGrid/ResponsiveGrid.stories.d.ts.map +1 -1
- package/dist/types/src/components/ResponsiveGrid/ResponsiveGridItem.d.ts.map +1 -1
- package/dist/types/src/components/ThreadComplementary.d.ts.map +1 -1
- package/dist/types/src/components/command-extension.d.ts.map +1 -1
- package/dist/types/src/components/testing.d.ts +1 -0
- package/dist/types/src/components/testing.d.ts.map +1 -1
- package/dist/types/src/extensions/threads.d.ts.map +1 -1
- package/dist/types/src/hooks/index.d.ts +1 -0
- package/dist/types/src/hooks/index.d.ts.map +1 -1
- package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts +2 -0
- package/dist/types/src/hooks/useBlackCanvasStreamTrack.d.ts.map +1 -0
- package/dist/types/src/hooks/useVideoStreamTrack.d.ts.map +1 -1
- package/dist/types/src/translations.d.ts +3 -1
- package/dist/types/src/translations.d.ts.map +1 -1
- package/dist/types/src/types/schema.d.ts +123 -108
- package/dist/types/src/types/schema.d.ts.map +1 -1
- package/dist/types/src/types/types.d.ts +255 -170
- package/dist/types/src/types/types.d.ts.map +1 -1
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +56 -54
- package/src/ThreadPlugin.tsx +9 -2
- package/src/calls/call-manager.ts +2 -2
- package/src/calls/call-swarm-synchronizer.ts +1 -1
- package/src/calls/media-manager.ts +60 -34
- package/src/calls/types.ts +8 -4
- package/src/calls/util/calls-service.ts +65 -14
- package/src/calls/util/stub-media-streams.ts +62 -5
- package/src/calls-service.stories.tsx +76 -60
- package/src/capabilities/app-graph-builder.ts +8 -5
- package/src/capabilities/call-manager.ts +3 -2
- package/src/capabilities/capabilities.ts +2 -2
- package/src/capabilities/index.ts +1 -0
- package/src/capabilities/intent-resolver.ts +38 -4
- package/src/capabilities/markdown.ts +4 -3
- package/src/capabilities/react-surface.tsx +5 -4
- package/src/capabilities/state.ts +2 -1
- package/src/capabilities/toolkit.ts +78 -0
- package/src/components/Call/Call.tsx +3 -2
- package/src/components/Call/Toolbar.tsx +5 -5
- package/src/components/CallDebugPanel.tsx +108 -49
- package/src/components/CallSidebar.tsx +2 -1
- package/src/components/ChannelContainer.stories.tsx +6 -5
- package/src/components/ChannelContainer.tsx +7 -6
- package/src/components/Chat.stories.tsx +28 -26
- package/src/components/ChatContainer.tsx +8 -4
- package/src/components/Comments.stories.tsx +33 -29
- package/src/components/CommentsContainer.tsx +2 -1
- package/src/components/CommentsThreadContainer.tsx +9 -7
- package/src/components/Lobby/Lobby.tsx +1 -1
- package/src/components/Media/VideoObject.stories.tsx +30 -27
- package/src/components/MessageContainer.tsx +43 -9
- package/src/components/Participant/Participant.tsx +13 -7
- package/src/components/Participant/ParticipantGrid.tsx +2 -1
- package/src/components/ResponsiveGrid/ResponsiveContainer.stories.tsx +6 -5
- package/src/components/ResponsiveGrid/ResponsiveGrid.stories.tsx +42 -39
- package/src/components/ResponsiveGrid/ResponsiveGrid.tsx +1 -1
- package/src/components/ResponsiveGrid/ResponsiveGridItem.tsx +2 -2
- package/src/components/ThreadComplementary.tsx +38 -8
- package/src/components/ThreadSettings.tsx +2 -2
- package/src/components/command-extension.ts +5 -2
- package/src/components/testing.ts +22 -0
- package/src/extensions/threads.ts +3 -3
- package/src/hooks/index.ts +1 -0
- package/src/hooks/useBlackCanvasStreamTrack.tsx +27 -0
- package/src/hooks/useDebugMode.ts +1 -1
- package/src/hooks/useVideoStreamTrack.tsx +5 -2
- package/src/testing/stories.ts +2 -2
- package/src/translations.ts +3 -1
- package/src/types/types.ts +21 -12
- package/src/typings/peermetrics-webrtc-stats.d.ts +17 -1
- package/src/typings.d.ts +8 -0
- package/dist/lib/browser/ChannelContainer-3GIE7ASU.mjs +0 -16
- package/dist/lib/browser/app-graph-builder-N7BE5TYW.mjs.map +0 -7
- package/dist/lib/browser/call-manager-NIPDYUVD.mjs.map +0 -7
- package/dist/lib/browser/chunk-3SGRT4NM.mjs +0 -367
- package/dist/lib/browser/chunk-3SGRT4NM.mjs.map +0 -7
- package/dist/lib/browser/chunk-6NSMBO3B.mjs.map +0 -7
- package/dist/lib/browser/chunk-ERWASUQK.mjs.map +0 -7
- package/dist/lib/browser/chunk-FR7KJPNY.mjs +0 -21
- package/dist/lib/browser/chunk-GCLD5ESP.mjs.map +0 -7
- package/dist/lib/browser/chunk-KWPRNHTK.mjs.map +0 -7
- package/dist/lib/browser/chunk-VUWC4IJM.mjs +0 -479
- package/dist/lib/browser/chunk-VUWC4IJM.mjs.map +0 -7
- package/dist/lib/browser/chunk-ZE7KWN36.mjs.map +0 -7
- package/dist/lib/browser/intent-resolver-JFGLZ6VI.mjs.map +0 -7
- package/dist/lib/browser/markdown-M3FMR7OD.mjs.map +0 -7
- package/dist/lib/browser/react-surface-XWS6GIZY.mjs.map +0 -7
- package/dist/lib/node-esm/app-graph-builder-VCW76Z6V.mjs.map +0 -7
- package/dist/lib/node-esm/call-manager-D6O5ZJJ4.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-2CXOK2TD.mjs +0 -23
- package/dist/lib/node-esm/chunk-2MFNK53T.mjs +0 -480
- package/dist/lib/node-esm/chunk-2MFNK53T.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-C3XFMUAY.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-FLBFYGBK.mjs +0 -368
- package/dist/lib/node-esm/chunk-FLBFYGBK.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-IHDNQLLR.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-OU5BYIDO.mjs.map +0 -7
- package/dist/lib/node-esm/chunk-TDFHTCZZ.mjs.map +0 -7
- package/dist/lib/node-esm/intent-resolver-OXGNQ44Y.mjs.map +0 -7
- package/dist/lib/node-esm/markdown-INKTE4MH.mjs.map +0 -7
- package/dist/lib/node-esm/react-surface-MJ33KPYE.mjs.map +0 -7
- /package/dist/lib/browser/{ChannelContainer-3GIE7ASU.mjs.map → ChannelContainer-4PYFOIDK.mjs.map} +0 -0
- /package/dist/lib/browser/{ChatContainer-AIGIWAUG.mjs.map → ChatContainer-EXNNREYB.mjs.map} +0 -0
- /package/dist/lib/browser/{react-root-JEUSQXI6.mjs.map → react-root-XKOD4KRB.mjs.map} +0 -0
- /package/dist/lib/browser/{settings-E32MTL7A.mjs.map → settings-GRKEID73.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ChannelContainer-7FXCKO7X.mjs.map → ChannelContainer-KQQEZWUN.mjs.map} +0 -0
- /package/dist/lib/node-esm/{ChatContainer-IQUWU426.mjs.map → ChatContainer-QVQKFBWA.mjs.map} +0 -0
- /package/dist/lib/node-esm/{react-root-XYYY2JXZ.mjs.map → react-root-4JWDRIQB.mjs.map} +0 -0
- /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.
|
|
3
|
+
"version": "0.8.4-main.dedc0f3",
|
|
4
4
|
"description": "DXOS Threads Surface plugin",
|
|
5
5
|
"homepage": "https://dxos.org",
|
|
6
6
|
"bugs": "https://github.com/dxos/dxos/issues",
|
|
@@ -10,16 +10,16 @@
|
|
|
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
|
-
"node": "./dist/lib/node-esm/index.mjs"
|
|
16
|
-
"source": "./src/index.ts"
|
|
16
|
+
"node": "./dist/lib/node-esm/index.mjs"
|
|
17
17
|
},
|
|
18
18
|
"./types": {
|
|
19
|
+
"source": "./src/types/index.ts",
|
|
19
20
|
"types": "./dist/types/src/types/index.d.ts",
|
|
20
21
|
"browser": "./dist/lib/browser/types/index.mjs",
|
|
21
|
-
"node": "./dist/lib/node-esm/types/index.mjs"
|
|
22
|
-
"source": "./src/types/index.ts"
|
|
22
|
+
"node": "./dist/lib/node-esm/types/index.mjs"
|
|
23
23
|
}
|
|
24
24
|
},
|
|
25
25
|
"types": "dist/types/src/index.d.ts",
|
|
@@ -35,9 +35,10 @@
|
|
|
35
35
|
"src"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@codemirror/language": "^6.
|
|
39
|
-
"@codemirror/state": "^6.
|
|
40
|
-
"@codemirror/view": "^6.
|
|
38
|
+
"@codemirror/language": "^6.11.3",
|
|
39
|
+
"@codemirror/state": "^6.5.2",
|
|
40
|
+
"@codemirror/view": "^6.38.2",
|
|
41
|
+
"@effect/ai": "0.25.2",
|
|
41
42
|
"@peermetrics/webrtc-stats": "5.7.1",
|
|
42
43
|
"@preact-signals/safe-react": "^0.9.0",
|
|
43
44
|
"@preact/signals-core": "^1.9.0",
|
|
@@ -45,58 +46,59 @@
|
|
|
45
46
|
"extendable-media-recorder": "^9.2.19",
|
|
46
47
|
"extendable-media-recorder-wav-encoder": "^7.0.123",
|
|
47
48
|
"md5-hex": "5.0.0",
|
|
48
|
-
"react-resize-detector": "^
|
|
49
|
+
"react-resize-detector": "^11.0.1",
|
|
49
50
|
"wavefile": "^11.0.0",
|
|
50
|
-
"@dxos/app-framework": "0.8.4-main.
|
|
51
|
-
"@dxos/
|
|
52
|
-
"@dxos/
|
|
53
|
-
"@dxos/
|
|
54
|
-
"@dxos/debug": "0.8.4-main.
|
|
55
|
-
"@dxos/
|
|
56
|
-
"@dxos/
|
|
57
|
-
"@dxos/
|
|
58
|
-
"@dxos/
|
|
59
|
-
"@dxos/
|
|
60
|
-
"@dxos/
|
|
61
|
-
"@dxos/
|
|
62
|
-
"@dxos/
|
|
63
|
-
"@dxos/log": "0.8.4-main.
|
|
64
|
-
"@dxos/plugin-attention": "0.8.4-main.
|
|
65
|
-
"@dxos/plugin-client": "0.8.4-main.
|
|
66
|
-
"@dxos/
|
|
67
|
-
"@dxos/plugin-
|
|
68
|
-
"@dxos/plugin-
|
|
69
|
-
"@dxos/
|
|
70
|
-
"@dxos/plugin-observability": "0.8.4-main.
|
|
71
|
-
"@dxos/plugin-space": "0.8.4-main.
|
|
72
|
-
"@dxos/react-client": "0.8.4-main.
|
|
73
|
-
"@dxos/
|
|
74
|
-
"@dxos/react-ui-
|
|
75
|
-
"@dxos/react-ui-form": "0.8.4-main.
|
|
76
|
-
"@dxos/react-ui-sfx": "0.8.4-main.
|
|
77
|
-
"@dxos/react-ui-editor": "0.8.4-main.
|
|
78
|
-
"@dxos/react-ui-
|
|
79
|
-
"@dxos/react-ui-
|
|
80
|
-
"@dxos/react-ui-
|
|
81
|
-
"@dxos/
|
|
82
|
-
"@dxos/react-ui-
|
|
83
|
-
"@dxos/
|
|
84
|
-
"@dxos/
|
|
51
|
+
"@dxos/app-framework": "0.8.4-main.dedc0f3",
|
|
52
|
+
"@dxos/assistant": "0.8.4-main.dedc0f3",
|
|
53
|
+
"@dxos/context": "0.8.4-main.dedc0f3",
|
|
54
|
+
"@dxos/codec-protobuf": "0.8.4-main.dedc0f3",
|
|
55
|
+
"@dxos/debug": "0.8.4-main.dedc0f3",
|
|
56
|
+
"@dxos/devtools": "0.8.4-main.dedc0f3",
|
|
57
|
+
"@dxos/display-name": "0.8.4-main.dedc0f3",
|
|
58
|
+
"@dxos/echo": "0.8.4-main.dedc0f3",
|
|
59
|
+
"@dxos/echo-schema": "0.8.4-main.dedc0f3",
|
|
60
|
+
"@dxos/keys": "0.8.4-main.dedc0f3",
|
|
61
|
+
"@dxos/invariant": "0.8.4-main.dedc0f3",
|
|
62
|
+
"@dxos/local-storage": "0.8.4-main.dedc0f3",
|
|
63
|
+
"@dxos/live-object": "0.8.4-main.dedc0f3",
|
|
64
|
+
"@dxos/log": "0.8.4-main.dedc0f3",
|
|
65
|
+
"@dxos/plugin-attention": "0.8.4-main.dedc0f3",
|
|
66
|
+
"@dxos/plugin-client": "0.8.4-main.dedc0f3",
|
|
67
|
+
"@dxos/async": "0.8.4-main.dedc0f3",
|
|
68
|
+
"@dxos/plugin-deck": "0.8.4-main.dedc0f3",
|
|
69
|
+
"@dxos/plugin-graph": "0.8.4-main.dedc0f3",
|
|
70
|
+
"@dxos/plugin-markdown": "0.8.4-main.dedc0f3",
|
|
71
|
+
"@dxos/plugin-observability": "0.8.4-main.dedc0f3",
|
|
72
|
+
"@dxos/plugin-space": "0.8.4-main.dedc0f3",
|
|
73
|
+
"@dxos/react-client": "0.8.4-main.dedc0f3",
|
|
74
|
+
"@dxos/protocols": "0.8.4-main.dedc0f3",
|
|
75
|
+
"@dxos/react-ui-attention": "0.8.4-main.dedc0f3",
|
|
76
|
+
"@dxos/react-ui-form": "0.8.4-main.dedc0f3",
|
|
77
|
+
"@dxos/react-ui-sfx": "0.8.4-main.dedc0f3",
|
|
78
|
+
"@dxos/react-ui-editor": "0.8.4-main.dedc0f3",
|
|
79
|
+
"@dxos/react-ui-dnd": "0.8.4-main.dedc0f3",
|
|
80
|
+
"@dxos/react-ui-menu": "0.8.4-main.dedc0f3",
|
|
81
|
+
"@dxos/react-ui-stack": "0.8.4-main.dedc0f3",
|
|
82
|
+
"@dxos/react-ui-tabs": "0.8.4-main.dedc0f3",
|
|
83
|
+
"@dxos/react-ui-syntax-highlighter": "0.8.4-main.dedc0f3",
|
|
84
|
+
"@dxos/schema": "0.8.4-main.dedc0f3",
|
|
85
|
+
"@dxos/util": "0.8.4-main.dedc0f3",
|
|
86
|
+
"@dxos/react-ui-thread": "0.8.4-main.dedc0f3"
|
|
85
87
|
},
|
|
86
88
|
"devDependencies": {
|
|
87
89
|
"@effect-rx/rx-react": "0.38.0",
|
|
88
|
-
"@effect/platform": "0.
|
|
90
|
+
"@effect/platform": "0.90.2",
|
|
89
91
|
"@types/react": "~18.2.0",
|
|
90
92
|
"@types/react-dom": "~18.2.0",
|
|
91
|
-
"effect": "3.17.
|
|
93
|
+
"effect": "3.17.7",
|
|
92
94
|
"react": "~18.2.0",
|
|
93
95
|
"react-dom": "~18.2.0",
|
|
94
|
-
"vite": "
|
|
95
|
-
"@dxos/plugin-theme": "0.8.4-main.
|
|
96
|
-
"@dxos/random": "0.8.4-main.
|
|
97
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
98
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
99
|
-
"@dxos/storybook-utils": "0.8.4-main.
|
|
96
|
+
"vite": "7.1.1",
|
|
97
|
+
"@dxos/plugin-theme": "0.8.4-main.dedc0f3",
|
|
98
|
+
"@dxos/random": "0.8.4-main.dedc0f3",
|
|
99
|
+
"@dxos/react-ui": "0.8.4-main.dedc0f3",
|
|
100
|
+
"@dxos/react-ui-theme": "0.8.4-main.dedc0f3",
|
|
101
|
+
"@dxos/storybook-utils": "0.8.4-main.dedc0f3"
|
|
100
102
|
},
|
|
101
103
|
"peerDependencies": {
|
|
102
104
|
"@effect-rx/rx-react": "^0.34.1",
|
|
@@ -104,8 +106,8 @@
|
|
|
104
106
|
"effect": "^3.13.3",
|
|
105
107
|
"react": "~18.2.0",
|
|
106
108
|
"react-dom": "~18.2.0",
|
|
107
|
-
"@dxos/react-ui": "0.8.4-main.
|
|
108
|
-
"@dxos/react-ui-theme": "0.8.4-main.
|
|
109
|
+
"@dxos/react-ui": "0.8.4-main.dedc0f3",
|
|
110
|
+
"@dxos/react-ui-theme": "0.8.4-main.dedc0f3"
|
|
109
111
|
},
|
|
110
112
|
"publishConfig": {
|
|
111
113
|
"access": "public"
|
package/src/ThreadPlugin.tsx
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// Copyright 2023 DXOS.org
|
|
3
3
|
//
|
|
4
4
|
|
|
5
|
-
import { Capabilities, contributes, createIntent, defineModule, definePlugin
|
|
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 {
|
|
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 {
|
|
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
|
|
|
@@ -210,7 +210,7 @@ export class CallManager extends Resource {
|
|
|
210
210
|
|
|
211
211
|
private _onCallStateUpdated(state: CallState): void {
|
|
212
212
|
const tracksToPull = state.users
|
|
213
|
-
?.filter((user) => user.joined && user.id !== state.self
|
|
213
|
+
?.filter((user) => user.joined && user.id !== state.self!.id)
|
|
214
214
|
?.flatMap((user) => [user.tracks?.video, user.tracks?.audio, user.tracks?.screenshare])
|
|
215
215
|
.filter(isNonNullable);
|
|
216
216
|
this._mediaManager._schedulePullTracks(tracksToPull as EncodedTrackName[]);
|
|
@@ -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 {
|
|
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 {
|
|
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 {
|
|
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 =
|
|
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 =
|
|
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,38 +274,47 @@ export class MediaManager extends Resource {
|
|
|
266
274
|
}
|
|
267
275
|
|
|
268
276
|
let updated = false;
|
|
269
|
-
const [
|
|
270
|
-
this.
|
|
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.
|
|
274
|
-
this.
|
|
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 (
|
|
278
|
-
this._state.pushedVideoTrack =
|
|
285
|
+
if (pushVideoResult.track !== this._state.pushedVideoTrack) {
|
|
286
|
+
this._state.pushedVideoTrack = pushVideoResult.track;
|
|
279
287
|
updated = true;
|
|
280
288
|
}
|
|
281
|
-
if (
|
|
282
|
-
this._state.pushedAudioTrack =
|
|
289
|
+
if (pushAudioResult.track !== this._state.pushedAudioTrack) {
|
|
290
|
+
this._state.pushedAudioTrack = pushAudioResult.track;
|
|
283
291
|
updated = true;
|
|
284
292
|
}
|
|
285
|
-
if (
|
|
286
|
-
this._state.pushedScreenshareTrack =
|
|
293
|
+
if (pushScreenshareResult.track !== this._state.pushedScreenshareTrack) {
|
|
294
|
+
this._state.pushedScreenshareTrack = pushScreenshareResult.track;
|
|
287
295
|
updated = true;
|
|
288
296
|
}
|
|
289
|
-
|
|
290
|
-
|
|
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
|
-
|
|
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<
|
|
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);
|
|
300
|
-
|
|
316
|
+
// We need to set mid here to `undefined`, because mid is peer specific.
|
|
317
|
+
const track = await this._state.peer!.pullTrack({ trackData: { ...trackData, mid: undefined }, ctx });
|
|
301
318
|
if (track?.readyState === 'ended') {
|
|
302
319
|
throw new Error('Pulled track ended immediately');
|
|
303
320
|
}
|
|
@@ -306,7 +323,7 @@ export class MediaManager extends Resource {
|
|
|
306
323
|
case 'audio': {
|
|
307
324
|
this._state.pulledAudioTracks[name] = { track, ctx };
|
|
308
325
|
ctx.onDispose(() => delete this._state.pulledAudioTracks[name]);
|
|
309
|
-
|
|
326
|
+
return { shouldRetry: false };
|
|
310
327
|
}
|
|
311
328
|
case 'video': {
|
|
312
329
|
const mediaStream = new MediaStream();
|
|
@@ -317,33 +334,42 @@ export class MediaManager extends Resource {
|
|
|
317
334
|
track.stop();
|
|
318
335
|
delete this._state.pulledVideoStreams[name];
|
|
319
336
|
});
|
|
320
|
-
|
|
337
|
+
return { shouldRetry: false };
|
|
321
338
|
}
|
|
322
339
|
default:
|
|
323
340
|
throw new Error(`Invalid track kind: ${track?.kind}`);
|
|
324
341
|
}
|
|
325
342
|
} catch (err) {
|
|
326
|
-
log.
|
|
343
|
+
log.info('failed to pull track', { err, name });
|
|
327
344
|
void ctx.dispose();
|
|
328
|
-
|
|
329
|
-
log.verbose('retrying pull track', { name });
|
|
330
|
-
this._pullTracksTask!.schedule();
|
|
345
|
+
return { shouldRetry: true };
|
|
331
346
|
}
|
|
332
347
|
}
|
|
333
348
|
|
|
334
|
-
private async
|
|
349
|
+
private async _maybePushTrack(
|
|
335
350
|
track?: MediaStreamTrack,
|
|
336
351
|
previousTrack?: TrackObject,
|
|
337
352
|
encodings?: RTCRtpEncodingParameters[],
|
|
338
|
-
): Promise<TrackObject
|
|
353
|
+
): Promise<{ track?: TrackObject; shouldRetry?: boolean }> {
|
|
339
354
|
if (!track && !previousTrack) {
|
|
340
|
-
return;
|
|
355
|
+
return { track: undefined };
|
|
341
356
|
}
|
|
342
357
|
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
358
|
+
const ctx = this._ctx.derive();
|
|
359
|
+
|
|
360
|
+
try {
|
|
361
|
+
return {
|
|
362
|
+
track: await this._state.peer!.pushTrack({
|
|
363
|
+
ctx,
|
|
364
|
+
track: track ?? null,
|
|
365
|
+
previousTrack,
|
|
366
|
+
encodings,
|
|
367
|
+
}),
|
|
368
|
+
};
|
|
369
|
+
} catch (err) {
|
|
370
|
+
log.info('failed to push track', { err, track, previousTrack, encodings });
|
|
371
|
+
void ctx.dispose();
|
|
372
|
+
return { shouldRetry: true };
|
|
373
|
+
}
|
|
348
374
|
}
|
|
349
375
|
}
|
package/src/calls/types.ts
CHANGED
|
@@ -2,11 +2,12 @@
|
|
|
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,
|
|
8
|
-
UserStateSchema,
|
|
9
9
|
type UserState as UserStateProto,
|
|
10
|
+
UserStateSchema,
|
|
10
11
|
} from '@dxos/protocols/buf/dxos/edge/calls_pb';
|
|
11
12
|
|
|
12
13
|
/**
|
|
@@ -61,10 +62,13 @@ export type EncodedTrackName = string & { __brand: 'EncodedTrackName' };
|
|
|
61
62
|
|
|
62
63
|
export const TrackNameCodec = {
|
|
63
64
|
encode: (trackData: TrackObject): EncodedTrackName => {
|
|
64
|
-
|
|
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,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 = {
|
|
@@ -32,12 +33,14 @@ export type CallsServiceConfig = {
|
|
|
32
33
|
|
|
33
34
|
export type HistoryRecord =
|
|
34
35
|
| {
|
|
36
|
+
endpoint: string;
|
|
35
37
|
type: 'request';
|
|
36
38
|
time: string;
|
|
37
39
|
method: string;
|
|
38
40
|
body: any;
|
|
39
41
|
}
|
|
40
42
|
| {
|
|
43
|
+
endpoint: string;
|
|
41
44
|
type: 'response';
|
|
42
45
|
time: string;
|
|
43
46
|
status: number;
|
|
@@ -115,7 +118,7 @@ export class CallsServicePeer extends Resource {
|
|
|
115
118
|
});
|
|
116
119
|
peerConnection.addEventListener('connectionstatechange', () => {
|
|
117
120
|
if (peerConnection.connectionState === 'failed' || peerConnection.connectionState === 'closed') {
|
|
118
|
-
log.
|
|
121
|
+
log.info('calls connection failed', { state: peerConnection.connectionState });
|
|
119
122
|
void this._persistentLifecycle.scheduleRestart();
|
|
120
123
|
}
|
|
121
124
|
});
|
|
@@ -124,7 +127,7 @@ export class CallsServicePeer extends Resource {
|
|
|
124
127
|
peerConnection.addEventListener('iceconnectionstatechange', () => {
|
|
125
128
|
clearTimeout(iceTimeout);
|
|
126
129
|
if (peerConnection.iceConnectionState === 'failed' || peerConnection.iceConnectionState === 'closed') {
|
|
127
|
-
log.
|
|
130
|
+
log.info('calls connection to ICEs failed', { state: peerConnection.iceConnectionState });
|
|
128
131
|
void this._persistentLifecycle.scheduleRestart();
|
|
129
132
|
} else if (peerConnection.iceConnectionState === 'disconnected') {
|
|
130
133
|
// TODO(mykola): we should start to inspect the connection stats from here on for
|
|
@@ -137,7 +140,7 @@ export class CallsServicePeer extends Resource {
|
|
|
137
140
|
return;
|
|
138
141
|
}
|
|
139
142
|
|
|
140
|
-
log.
|
|
143
|
+
log.info('calls iceConnectionState timed out', { state: peerConnection.iceConnectionState, timeoutSeconds });
|
|
141
144
|
void this._persistentLifecycle.scheduleRestart();
|
|
142
145
|
}, timeoutSeconds * 1_000);
|
|
143
146
|
}
|
|
@@ -154,6 +157,7 @@ export class CallsServicePeer extends Resource {
|
|
|
154
157
|
|
|
155
158
|
private async _fetch<T extends ErrorResponse>(relativePath: string, requestInit?: RequestInit): Promise<T> {
|
|
156
159
|
this.history.push({
|
|
160
|
+
endpoint: relativePath,
|
|
157
161
|
type: 'request',
|
|
158
162
|
time: new Date().toISOString(),
|
|
159
163
|
method: requestInit?.method ?? 'GET',
|
|
@@ -169,6 +173,7 @@ export class CallsServicePeer extends Resource {
|
|
|
169
173
|
try {
|
|
170
174
|
const data = (await response.clone().json()) as T;
|
|
171
175
|
this.history.push({
|
|
176
|
+
endpoint: relativePath,
|
|
172
177
|
type: 'response',
|
|
173
178
|
time: new Date().toISOString(),
|
|
174
179
|
status: response.status,
|
|
@@ -182,6 +187,7 @@ export class CallsServicePeer extends Resource {
|
|
|
182
187
|
} catch (error) {
|
|
183
188
|
const text = await response.text();
|
|
184
189
|
this.history.push({
|
|
190
|
+
endpoint: relativePath,
|
|
185
191
|
type: 'response',
|
|
186
192
|
time: new Date().toISOString(),
|
|
187
193
|
status: response.status,
|
|
@@ -203,11 +209,11 @@ export class CallsServicePeer extends Resource {
|
|
|
203
209
|
sessionId,
|
|
204
210
|
trackName,
|
|
205
211
|
}: {
|
|
212
|
+
ctx: Context;
|
|
206
213
|
peerConnection: RTCPeerConnection;
|
|
207
214
|
transceiver: RTCRtpTransceiver;
|
|
208
215
|
sessionId: string;
|
|
209
216
|
trackName: string;
|
|
210
|
-
ctx?: Context;
|
|
211
217
|
}): Promise<TrackObject | void> {
|
|
212
218
|
log.verbose('pushing track ', trackName);
|
|
213
219
|
const pushedTrackPromise = this.pushTrackDispatcher
|
|
@@ -245,9 +251,13 @@ export class CallsServicePeer extends Resource {
|
|
|
245
251
|
};
|
|
246
252
|
}),
|
|
247
253
|
)
|
|
248
|
-
.then(({ tracks }) => {
|
|
254
|
+
.then(async ({ tracks }) => {
|
|
249
255
|
const trackData = tracks.find((t) => t.mid === transceiver.mid);
|
|
250
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);
|
|
251
261
|
return {
|
|
252
262
|
...trackData,
|
|
253
263
|
sessionId,
|
|
@@ -256,9 +266,6 @@ export class CallsServicePeer extends Resource {
|
|
|
256
266
|
} else {
|
|
257
267
|
log.error('missing track data');
|
|
258
268
|
}
|
|
259
|
-
})
|
|
260
|
-
.catch((err) => {
|
|
261
|
-
log.catch(err);
|
|
262
269
|
});
|
|
263
270
|
|
|
264
271
|
const onDispose = async () => {
|
|
@@ -280,8 +287,8 @@ export class CallsServicePeer extends Resource {
|
|
|
280
287
|
previousTrack,
|
|
281
288
|
}: {
|
|
282
289
|
track: MediaStreamTrack | null;
|
|
290
|
+
ctx: Context;
|
|
283
291
|
encodings?: RTCRtpEncodingParameters[];
|
|
284
|
-
ctx?: Context;
|
|
285
292
|
previousTrack?: TrackObject;
|
|
286
293
|
}): Promise<TrackObject | undefined> {
|
|
287
294
|
await this.waitUntilOpen();
|
|
@@ -404,7 +411,7 @@ export class CallsServicePeer extends Resource {
|
|
|
404
411
|
})
|
|
405
412
|
.catch((err) => log.catch(err));
|
|
406
413
|
} else {
|
|
407
|
-
log.
|
|
414
|
+
log.info('missing track info', { trackData, availableTracks: Array.from(trackMap.keys()) });
|
|
408
415
|
}
|
|
409
416
|
});
|
|
410
417
|
|
|
@@ -528,3 +535,47 @@ const peerConnectionIsConnected = async (peerConnection: RTCPeerConnection) => {
|
|
|
528
535
|
await connected;
|
|
529
536
|
}
|
|
530
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
|
+
};
|