// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. import 'dart:async'; import 'dart:collection'; import 'dart:io'; /// Returns `true` if [error] is a [FileSystemException] for a missing /// directory. bool isDirectoryNotFoundException(Object error) { if (error is! FileSystemException) return false; // See dartbug.com/12461 and tests/standalone/io/directory_error_test.dart. var notFoundCode = Platform.operatingSystem == 'windows' ? 3 : 2; return error.osError?.errorCode == notFoundCode; } /// Returns the union of all elements in each set in [sets]. Set unionAll(Iterable> sets) => sets.fold({}, (union, set) => union.union(set)); extension BatchEvents on Stream { /// Batches all events that are sent at the same time. /// /// When multiple events are synchronously added to a stream controller, the /// [StreamController] implementation uses [scheduleMicrotask] to schedule the /// asynchronous firing of each event. In order to recreate the synchronous /// batches, this collates all the events that are received in "nearby" /// microtasks. Stream> batchEvents() { var batch = Queue(); return StreamTransformer>.fromHandlers( handleData: (event, sink) { batch.add(event); // [Timer.run] schedules an event that runs after any microtasks that have // been scheduled. Timer.run(() { if (batch.isEmpty) return; sink.add(batch.toList()); batch.clear(); }); }, handleDone: (sink) { if (batch.isNotEmpty) { sink.add(batch.toList()); batch.clear(); } sink.close(); }).bind(this); } }