Don't batch per default (#164)

diff --git a/lib/src/usage_impl.dart b/lib/src/usage_impl.dart
index b1ea566..870d123 100644
--- a/lib/src/usage_impl.dart
+++ b/lib/src/usage_impl.dart
@@ -79,12 +79,12 @@
   @override
   AnalyticsOpt analyticsOpt = AnalyticsOpt.optOut;
 
-  late Duration _batchingDelay;
+  final Duration? _batchingDelay;
   final Queue<String> _batchedEvents = Queue<String>();
   bool _isSendingScheduled = false;
 
-  late final String _url;
-  late final String _batchingUrl;
+  final String _url;
+  final String _batchingUrl;
 
   final StreamController<Map<String, dynamic>> _sendController =
       StreamController.broadcast(sync: true);
@@ -98,13 +98,11 @@
     String? analyticsUrl,
     String? analyticsBatchingUrl,
     Duration? batchingDelay,
-  }) {
+  })  : _url = analyticsUrl ?? _defaultAnalyticsUrl,
+        _batchingDelay = batchingDelay,
+        _batchingUrl = analyticsBatchingUrl ?? _defaultAnalyticsBatchingUrl {
     if (applicationName != null) setSessionValue('an', applicationName);
     if (applicationVersion != null) setSessionValue('av', applicationVersion);
-
-    _url = analyticsUrl ?? _defaultAnalyticsUrl;
-    _batchingUrl = analyticsBatchingUrl ?? _defaultAnalyticsBatchingUrl;
-    _batchingDelay = batchingDelay ?? const Duration();
   }
 
   bool? _firstRun;
@@ -271,18 +269,26 @@
 
     _sendController.add(eventArgs);
     _batchedEvents.add(postHandler.encodeHit(eventArgs));
-    // First check if we have a full batch - if so, send them immediately.
-    if (_batchedEvents.length >= _maxHitsPerBatch ||
-        _batchedEvents.fold<int>(0, (s, e) => s + e.length) >=
-            _maxBytesPerBatch) {
+
+    // If [_batchingDelay] is null we don't do batching.
+    // TODO(sigurdm): reconsider this.
+    final batchingDelay = _batchingDelay;
+    if (batchingDelay == null) {
       _trySendBatches(completer);
-    } else if (!_isSendingScheduled) {
-      _isSendingScheduled = true;
-      // ignore: unawaited_futures
-      Future.delayed(_batchingDelay).then((value) {
-        _isSendingScheduled = false;
+    } else {
+      // First check if we have a full batch - if so, send them immediately.
+      if (_batchedEvents.length >= _maxHitsPerBatch ||
+          _batchedEvents.fold<int>(0, (s, e) => s + e.length) >=
+              _maxBytesPerBatch) {
         _trySendBatches(completer);
-      });
+      } else if (!_isSendingScheduled) {
+        _isSendingScheduled = true;
+        // ignore: unawaited_futures
+        Future.delayed(batchingDelay).then((value) {
+          _isSendingScheduled = false;
+          _trySendBatches(completer);
+        });
+      }
     }
     return completer.future;
   }
diff --git a/lib/src/usage_impl_html.dart b/lib/src/usage_impl_html.dart
index b2501aa..59843b0 100644
--- a/lib/src/usage_impl_html.dart
+++ b/lib/src/usage_impl_html.dart
@@ -13,9 +13,12 @@
 /// [analyticsUrl] is an optional replacement for the default Google Analytics
 /// URL (`https://www.google-analytics.com/collect`).
 ///
-/// [batchingDelay] is used to control batching behaviour. It should return a
-/// [Future] that will be awaited before attempting sending the enqueued
-/// messages. If it returns `null` events will not be batched.
+/// [batchingDelay] is used to control batching behaviour. Events will be sent
+/// batches of 20 after the duration is over from when the first message was
+/// sent.
+///
+/// If [batchingDelay] is `Duration()` messages will be sent when control
+/// returns to the event loop.
 ///
 /// Batched messages are sent in batches of up to 20 messages.
 class AnalyticsHtml extends AnalyticsImpl {
diff --git a/lib/src/usage_impl_io.dart b/lib/src/usage_impl_io.dart
index 69dd392..4d770ee 100644
--- a/lib/src/usage_impl_io.dart
+++ b/lib/src/usage_impl_io.dart
@@ -28,8 +28,10 @@
 ///
 /// [batchingDelay] is used to control batching behaviour. Events will be sent
 /// batches of 20 after the duration is over from when the first message was
-/// sent. The default is 0 milliseconds, meaning that messages will be sent when
-/// control returns to the event loop.
+/// sent.
+///
+/// If [batchingDelay] is `Duration()` messages will be sent when control
+/// returns to the event loop.
 ///
 /// Batched messages are sent in batches of up to 20 messages. They will be sent
 /// to [analyticsBatchingUrl] defaulting to
diff --git a/test/usage_impl_io_test.dart b/test/usage_impl_io_test.dart
index 65f6708..c363284 100644
--- a/test/usage_impl_io_test.dart
+++ b/test/usage_impl_io_test.dart
@@ -59,13 +59,12 @@
   });
 
   group('batching', () {
-    test(
-        'with default batch-delay hits from the same sync span are batched together',
+    test('with 0 batch-delay hits from the same sync span are batched together',
         () async {
       var mockClient = MockHttpClient();
 
       final analytics = AnalyticsIO('<TRACKING-ID', 'usage-test', '0.0.1',
-          client: mockClient);
+          client: mockClient, batchingDelay: Duration());
       unawaited(analytics.sendEvent('my-event1', 'something'));
       unawaited(analytics.sendEvent('my-event2', 'something'));
       unawaited(analytics.sendEvent('my-event3', 'something'));