streamSearch method

Stream<List<String>> streamSearch({
  1. required List<String> dataset,
  2. required Stream<String> query,
  3. double? strictThreshold,
  4. double? typoThreshold,
  5. bool? kIsWeb,
})

Stream-based search for fuzzy results

Implementation

Stream<List<String>> streamSearch({
  required List<String> dataset,
  required Stream<String> query,
  double? strictThreshold,
  double? typoThreshold,
  bool? kIsWeb,
}) {
  // Validate inputs
  if (dataset.isEmpty) {
    throw ArgumentError("Dataset cannot be empty.");
  }
  if (strictThreshold != null &&
      (strictThreshold < 0 || strictThreshold > 1)) {
    throw ArgumentError("strictThreshold must be between 0 and 1.");
  }
  if (typoThreshold != null && (typoThreshold < 0 || typoThreshold > 1)) {
    throw ArgumentError("typoThreshold must be between 0 and 1.");
  }

  final controller = StreamController<List<String>>.broadcast();

  // Listen to incoming search terms from the query stream
  final subscription = query.listen(
    (inputQuery) async {
      if (inputQuery.trim().isEmpty) {
        // Emit an empty list for empty queries
        if (!controller.isClosed) {
          controller.add([]);
        }
        return;
      }

      try {
        // Perform the search
        final result = await _performSearch(
          dataset: dataset,
          query: inputQuery,
          strictThreshold:
              strictThreshold ?? Constants.defaultStrictThreshold,
          typoThreshold: typoThreshold ?? Constants.defaultTypoThreshold,
          kIsWeb: kIsWeb ?? false,
        );

        // Emit the search results
        if (!controller.isClosed) {
          controller.add(result);
        }
      } catch (e, stackTrace) {
        if (!controller.isClosed) {
          controller.addError(e, stackTrace);
        }
      }
    },
    onError: (e, stackTrace) {
      if (!controller.isClosed) {
        controller.addError(e, stackTrace);
      }
    },
    onDone: () {
      if (!controller.isClosed) {
        controller.close();
      }
    },
  );

  // Ensure the subscription is canceled when the stream is closed
  controller.onCancel = () async {
    await subscription.cancel();
  };

  return controller.stream;
}