@@ -16,6 +16,7 @@ import 'package:dwds/data/devtools_request.dart';
1616import 'package:dwds/data/extension_request.dart' ;
1717import 'package:dwds/data/serializers.dart' ;
1818import 'package:dwds/src/sockets.dart' ;
19+ import 'package:dwds/src/utilities/batched_stream.dart' ;
1920import 'package:js/js.dart' ;
2021import 'package:js/js_util.dart' as js_util;
2122import 'package:pub_semver/pub_semver.dart' ;
@@ -61,8 +62,6 @@ Tab _mostRecentDartTab;
6162DebuggerTrigger _debuggerTrigger;
6263
6364class DebugSession {
64- final SocketClient socketClient;
65-
6665 // The tab ID that contains the running Dart application.
6766 final int appTabId;
6867
@@ -72,7 +71,38 @@ class DebugSession {
7271 // The tab ID that contains the corresponding Dart DevTools.
7372 int devtoolsTabId;
7473
75- DebugSession (this .socketClient, this .appTabId, this .appId);
74+ // Socket client for communication with dwds extension backend.
75+ final SocketClient _socketClient;
76+
77+ // How often to send batched events.
78+ static const int _batchDelayMilliseconds = 1000 ;
79+
80+ // Collect events into batches to be send periodically to the server.
81+ final _batchController =
82+ BatchedStreamController <ExtensionEvent >(delay: _batchDelayMilliseconds);
83+ StreamSubscription <List <ExtensionEvent >> _batchSubscription;
84+
85+ DebugSession (this ._socketClient, this .appTabId, this .appId) {
86+ // Collect extension events and send them periodically to the server.
87+ _batchSubscription = _batchController.stream.listen ((events) {
88+ _socketClient.sink.add (jsonEncode (serializers.serialize (BatchedEvents (
89+ (b) => b.events = ListBuilder <ExtensionEvent >(events)))));
90+ });
91+ }
92+
93+ void sendEvent (ExtensionEvent event) {
94+ _socketClient.sink.add (jsonEncode (serializers.serialize (event)));
95+ }
96+
97+ void sendBatchedEvent (ExtensionEvent event) {
98+ _batchController.sink.add (event);
99+ }
100+
101+ void close () {
102+ _socketClient.close ();
103+ _batchSubscription.cancel ();
104+ _batchController.close ();
105+ }
76106}
77107
78108class DevToolsPanel {
@@ -101,7 +131,7 @@ void main() {
101131 onMessageAddListener (allowInterop (_handleMessageFromContentScripts));
102132
103133 // Attaches a debug session to the app when the extension receives a
104- // Runtime.executionContextCreated event from DWDS :
134+ // Runtime.executionContextCreated event from Chrome :
105135 addDebuggerListener (allowInterop (_maybeAttachDebugSession));
106136
107137 // When a Dart application tab is closed, detach the corresponding debug
@@ -264,7 +294,7 @@ void _maybeAttachDebugSession(
264294 Object params,
265295) async {
266296 // Return early if it's not a Runtime.executionContextCreated event (sent from
267- // DWDS ):
297+ // Chrome ):
268298 if (method != 'Runtime.executionContextCreated' ) return ;
269299
270300 var context = json.decode (stringify (params))['context' ];
@@ -303,8 +333,8 @@ int _removeDebugSessionForTab(int tabId) {
303333 // https://github.com/dart-lang/webdev/pull/1595#issuecomment-1116773378
304334 final event =
305335 _extensionEventFor ('DebugExtension.detached' , js_util.jsify ({}));
306- session.socketClient.sink. add ( jsonEncode (serializers. serialize ( event)) );
307- session.socketClient. close ();
336+ session.sendEvent ( event);
337+ session.close ();
308338 _debugSessions.remove (session);
309339
310340 // Notify the Dart DevTools panel that the session has been detached by
@@ -590,7 +620,11 @@ void _filterAndForwardToBackend(Debuggee source, String method, Object params) {
590620
591621 var event = _extensionEventFor (method, params);
592622
593- debugSession.socketClient.sink.add (jsonEncode (serializers.serialize (event)));
623+ if (method == 'Debugger.scriptParsed' ) {
624+ debugSession.sendBatchedEvent (event);
625+ } else {
626+ debugSession.sendEvent (event);
627+ }
594628}
595629
596630class Notifier <T > {
0 commit comments