fuzzy_bolt 1.1.9 copy "fuzzy_bolt: ^1.1.9" to clipboard
fuzzy_bolt: ^1.1.9 copied to clipboard

A high-performance fuzzy search algorithm in Dart, designed for intelligent auto-suggestions, typo tolerance, and fast string matching.

Fuzzy Bolt #

An advanced Fuzzy Search Algorithm with intelligent typo correction, adaptive ranking, and lightning-fast performance.

pub package License: BSD-3-Clause

Table of Contents #

Why Fuzzy Bolt ?? #

I've found many packages that just purely does the fuzzy search job but haven't encountered that deals with typo/error in query automatically.

  • Uses Jaro–Winkler Distance for ranking the results.
  • Uses Levenshtein Distance to handle the typo errors in the query if any.
  • Leverage host's Isolate mechanism if the dataset becomes huge.
  • Automatically switch to non-isolate fallback mechanim for Web platform.
  • Allow developers to set their threshold on results for better accuracy.

Use Case Applications #

  • Local Database Search: Perfect for running fuzzy queries directly on local datasets like SQLite, Hive, or Isar.

  • Post-API Result Search: Enhance your UX by adding an extra layer of fuzzy search after fetching data from remote APIs.

  • In-Memory State Search: Great for filtering and ranking results from app state (e.g in-memory lists, BLoC/Cubit states, Provider data, etc.).

  • Search Bars & Autocomplete Fields: Supercharge your TextField or SearchDelegate with typo-tolerant and intent-aware results.

  • Offline-First Applications: Helpful in apps that prioritize offline functionality and require local, fast search.

  • Data Cleaning & Record Linking: Use it for fuzzy matching and deduplication tasks (e.g., merging similar records in datasets).

  • Command Palette / Quick Actions Search: Perfect for developer tools or admin dashboards where users trigger commands via text input.

Installation #

Add FuzzyBolt to your pubspec.yaml:

dependencies:
  fuzzy_bolt: <latest_version>  

Then, run:

flutter pub get

Normal Search Usage #

API Reference #

Future<List<String>> search({
  required List<String> dataset,
  required String query,
  double? strictThreshold,
  double? typoThreshold,
  bool? kIsWeb,
})

Example #

import 'package:fuzzy_bolt/fuzzy_bolt.dart';

void main() async {
  final results = await FuzzyBolt().search(
  dataset: ["encyclopedia", "phenomenon", "philosophy", "psychology"],
  query: "phsychology", // Typo: "phsychology" instead of "psychology"
  strictThreshold: 0.8,
  typoThreshold: 0.7,
  kIsWeb: false,
);

  results.map((e) => print(e)).toList();
}

Output Example: #

psychology 

philosophy 

Normal Search with Ranks #

API Reference #

Future<List<Map<String, dynamic>>> searchWithRanks({
  required List<String> dataset,
  required String query,
  double? strictThreshold,
  double? typoThreshold,
  bool? kIsWeb,
  Function(Object, StackTrace)? onError,
})

Example #

import 'package:fuzzy_bolt/fuzzy_bolt.dart';

void main() async {
  final results = await FuzzyBolt().searchWithRanks(
    dataset: ["encyclopedia", "phenomenon", "philosophy", "psychology"],
    query: "phsychology", // Typo: "phsychology" instead of "psychology"
    strictThreshold: 0.8,
    typoThreshold: 0.7,
    kIsWeb: false,
    Function(Object, StackTrace)? onError,
  );

  print("Results with ranks:");
  for (var result in results) {
    print("${result['value']} (Score: ${result['rank']})");
  }
}

Output Example: #

psychology (Score: 0.92)  ✅  (Fixes minor spelling mistake)
philosophy (Score: 0.75)  ❌  (Less relevant but somewhat similar)

API Reference #

Stream<List<String>> streamSearch({
    required List<String> dataset,
    required Stream<String> query,
    double? strictThreshold,
    double? typoThreshold,
    bool? kIsWeb,
    Function(Object, StackTrace)? onError,
  });

Example #

import 'package:fuzzy_bolt/fuzzy_bolt.dart';

void main() async {
  final queryController = StreamController<String>();
  final searchStream = fuzzyBolt.streamSearch(
    dataset: ["apple", "banana", "berry", "grape", "pineapple"],
    query: queryController.stream,
    Function(Object, StackTrace)? onError,
  );

  searchStream.listen((results) {
    print(results);
  });

  queryController.add("b");
  queryController.add("be");
  queryController.add("ber");
  queryController.add("berr");
  queryController.add("berry");
}

Output Example: #

🚀 Running Stream-Based Search...

⌨️ Typing: 'b'
🔄 Stream Update:
   🔹 banana (Score: 0.750)
   🔹 blueberry (Score: 0.733)
   🔹 blackberry (Score: 0.730)

⌨️ Typing: 'be'
🔄 Stream Update:
   🔹 blueberry (Score: 0.767)

⌨️ Typing: 'ber'
🔄 Stream Update:
   🔹 blueberry (Score: 0.667)
   🔹 tangerine (Score: 0.630)
   🔹 watermelon (Score: 0.622)
   🔹 pomegranate (Score: 0.616)

⌨️ Typing: 'berr'
🔄 Stream Update:
   🔹 blueberry (Score: 0.725)
   🔹 blackberry (Score: 0.610)

⌨️ Typing: 'berry'
🔄 Stream Update:
   🔹 blueberry (Score: 0.680)
   🔹 raspberry (Score: 0.444)
🏁 Stream-based search completed.

Stream-Based Search with Ranks #

API Reference #

Stream<List<Map<String, dynamic>>> streamSearchWithRanks({
    required List<String> dataset,
    required Stream<String> query,
    double? strictThreshold,
    double? typoThreshold,
    bool? kIsWeb,
    Function(Object, StackTrace)? onError,
  });

Example #

import 'package:fuzzy_bolt/fuzzy_bolt.dart';

void main() async {
  final queryController = StreamController<String>();
  final searchStream = fuzzyBolt.streamSearchWithRanks(
    dataset: ["apple", "banana", "berry", "grape", "pineapple"],
    query: queryController.stream,
  );

  searchStream.listen((results) {
    print("Results with ranks:");
    for (var result in results) {
      print("${result['value']} (Score: ${result['rank']})");
    }
  });

  queryController.add("b");
  queryController.add("be");
  queryController.add("ber");
  queryController.add("berr");
  queryController.add("berry");
}

Output Example: #

🚀 Running Stream-Based Search with Ranks...

⌨️ Typing: 'b'
🔄 Stream Update:
   🔹 banana (Score: 0.750)
   🔹 blueberry (Score: 0.733)
   🔹 blackberry (Score: 0.730)

⌨️ Typing: 'be'
🔄 Stream Update:
   🔹 blueberry (Score: 0.767)

⌨️ Typing: 'ber'
🔄 Stream Update:
   🔹 blueberry (Score: 0.667)
   🔹 blackberry (Score: 0.610)

⌨️ Typing: 'berry'
🔄 Stream Update:
   🔹 blueberry (Score: 0.680)
   🔹 raspberry (Score: 0.444)

Platform Support #

Platform Supported
Android ✅ Yes
iOS ✅ Yes
macOS ✅ Yes
Windows ✅ Yes
Linux ✅ Yes
Web ✅ Yes

Web support?
I've added fallback mechanism to use search locally without the help of Isolate mechanism since Flutter web do not support Isolates...

Note on streamSearch Stability #

The onError callback in streamSearch is designed to handle errors gracefully. However, in certain edge cases (e.g., invalid datasets or rapidly changing queries), the behavior may be inconsistent. It is recommended to test thoroughly for your specific use case and handle errors at the application level if needed.

Running Tests #

To run tests, use:

dart test
test/fuzzy_bolt_test.dart
6
likes
160
points
94
downloads

Publisher

verified publishervishwakarthik.in

Weekly Downloads

A high-performance fuzzy search algorithm in Dart, designed for intelligent auto-suggestions, typo tolerance, and fast string matching.

Repository (GitHub)
View/report issues

Topics

#fuzzy-search #search-ranking #text-processing #auto-suggestions #ranking

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

collection

More

Packages that depend on fuzzy_bolt