Giter Club home page Giter Club logo

wafu's Introduction

wafu

npm

Rust port of Fuse.js, a javascript fuzzy searching library, compiled to WebAssembly. Try it out!

Usage

npm install wafu

Should work in any browser that supports WebAssembly, with the same caveats as wasm-bindgen. Otherwise, wafu should be an almost drop-in replacement for Fuse!

import { Wafu } from "wafu";

const books = [
  {
    title: "Old Man's War",
    author: {
      firstName: "John",
      lastName: "Scalzi"
    }
  },
  {
    title: "The Lock Artist",
    author: {
      firstName: "Steve",
      lastName: "Hamilton"
    }
  }
];

const options = {
  keys: ["title", "author.lastName"],
  includeMatches: true
};

const searcher = new Wafu(books, options);
const results = searcher.search("~ query goes here ~");

The options are exactly the same as Fuse, with all changes documented in the section below.

The story for bundling is a moving target, but webpack 4+ has native support for importing wasm if you do it within an async import block. The gist is you put whatever file uses wafu behind an async import, and then you can go about your life as if loading were synchronous.

You can use it with create-react-app using react-app-rewired and this config-overrides.js file in your project root.

module.exports = function override(config, env) {
  const wasmExtensionRegExp = /\.wasm$/;
  config.resolve.extensions.push(".wasm");
  config.module.rules.forEach(rule => {
    (rule.oneOf || []).forEach(oneOf => {
      if (oneOf.loader && oneOf.loader.indexOf("file-loader") >= 0) {
        oneOf.exclude.push(wasmExtensionRegExp);
      }
    });
  });
  return config;
};

Check the demo folder for a full example!

Node support may be coming at some point, but for now, it requires a bundler to translate the imports.

Differences from Fuse

The results returned from Fuse and wafu, given the same options and collection, are close but not exactly the same just yet! Work is still being done here to iron out edge cases, but here are some known differences:

  • Fuse treats leading and trailing whitespace as separate "tokens" which affects match score, but wafu filters them out.
  • Behavior for patterns longer than 32 chars is different than with Fuse. I haven't decided exactly what the plan is here, but hopefully, it doesn't affect too many people.
  • Occasionally scores are different by vanishingly small amounts. I'm chalking this up to differences in floating point arithmetic or minor serialization issues as data crosses back and forth between rust and js.
  • The output of wafu is always structured as { item: T, score: number, matches?: WafuMatch[] }, which means that Fuse's id and includeScore options are removed as the item is always the original item and the score is always included. It's trivial for end users to achieve the same effects as these options, and it simplifies the typescript definitions significantly.
  • Fuse will return the index in place of the item when the original collection is string[]. wafu returns the actual string, because why would you do it the other way.
  • Fuse's findAllMatches option is removed, and wafu behaves as if it's always set to true. This simplifies the internal bitap code a little.
  • Fuse's maxPatternLength option is removed. It's buggy in Fuse and essentially has to be set to 32.
  • Fuse's sortFn is removed. Hopefully, this isn't used much, but the main reason was I couldn't think of a nice way to do it!
  • Not sure how well Fuse does, but wafu should do a good job of handling Unicode. Grapheme clusters are not taken into account; if you've got lots of Unicode text you should probably normalize it first.

Performance

This initial release was written in the most straightforward way I could think of, so there is a lot of low hanging fruit in terms of improvements. Nevertheless, wafu appears to be at least twice as fast as Fuse out of the box in firefox!

However, the compiled wasm code alone is currently 216KB to Fuse's 12KB. This should improve in the future, but for now, that makes this project kind of a toy โ˜บ

Development

Requires rust, wasm-pack (currently using v0.6.0), node, and npm to build. I didn't have a great plan when I was structuring this package, but the rust code is in wafu_rs, the typescript code is in wafu_pkg, and the demo site code is in wafu_demo. The build.sh script builds everything, and also links wafu into the demo node modules.

Project Goals

I'm not trying to make the world's best fuzzy search library. This is first and foremost a port of Fuse. I want it to potentially be a drop in replacement for people who already use Fuse. Thats all!

wafu's People

Contributors

colelawrence avatar dependabot[bot] avatar heyimalex avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

colelawrence

wafu's Issues

Retaining comments

Hi @heyimalex !

I came across your package after it was posted on /r/rust. Thank you for putting in the time to make this. I'm really excited to be able to use it in a simple Language Server implementation I'm working on.

I noticed that the declaration typings that come with the library are having their documentation stripped because of the use of // comments as opposed to docstring comments in the form /** docstring */

Would you accept some help converting that documentation to docstrings so they are retained in the .d.ts files?

Read more about TypeScript's doc expectations here: https://github.com/microsoft/tsdoc

Thanks,

Cole

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.