{"id":13394548,"url":"https://github.com/bvaughn/redux-search","last_synced_at":"2025-05-15T08:10:12.147Z","repository":{"id":55857379,"uuid":"46806092","full_name":"bvaughn/redux-search","owner":"bvaughn","description":"Redux bindings for client-side search","archived":false,"fork":false,"pushed_at":"2020-12-11T03:28:22.000Z","size":6074,"stargazers_count":1400,"open_issues_count":15,"forks_count":63,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-04-14T14:59:38.795Z","etag":null,"topics":["middleware","redux","resources","search","state"],"latest_commit_sha":null,"homepage":"https://bvaughn.github.io/redux-search/","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bvaughn.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-11-24T17:03:56.000Z","updated_at":"2025-03-25T12:10:31.000Z","dependencies_parsed_at":"2022-08-15T07:51:21.681Z","dependency_job_id":null,"html_url":"https://github.com/bvaughn/redux-search","commit_stats":null,"previous_names":["treasure-data/redux-search"],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvaughn%2Fredux-search","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvaughn%2Fredux-search/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvaughn%2Fredux-search/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bvaughn%2Fredux-search/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bvaughn","download_url":"https://codeload.github.com/bvaughn/redux-search/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254301433,"owners_count":22047904,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["middleware","redux","resources","search","state"],"created_at":"2024-07-30T17:01:23.456Z","updated_at":"2025-05-15T08:10:12.099Z","avatar_url":"https://github.com/bvaughn.png","language":"JavaScript","funding_links":[],"categories":["JavaScript","redux","📦 Legacy \u0026 Inactive Projects"],"sub_categories":[],"readme":"redux-search\n-----\n\n\u003cimg src=\"https://cloud.githubusercontent.com/assets/29597/11708504/c2f637ce-9ec4-11e5-8eb9-c248664e8d3b.png\" alt=\"Redux Search\" data-canonical-src=\"https://cloud.githubusercontent.com/assets/29597/11708504/c2f637ce-9ec4-11e5-8eb9-c248664e8d3b.png\" width=\"364\" height=\"100\" /\u003e\n\n![NPM version](https://img.shields.io/npm/v/redux-search.svg)\n![NPM license](https://img.shields.io/npm/l/redux-search.svg)\n![NPM total downloads](https://img.shields.io/npm/dt/redux-search.svg)\n![NPM monthly downloads](https://img.shields.io/npm/dm/redux-search.svg)\n[![Circle CI badge](https://img.shields.io/circleci/project/bvaughn/redux-search/master.svg)](https://circleci.com/gh/bvaughn/redux-search)\n\nHigher-order Redux library for searching collections of objects. Search algorithms powered by [js-worker-search](https://github.com/bvaughn/js-worker-search).\n\nCheck out the live demo at [bvaughn.github.io/redux-search](http://bvaughn.github.io/redux-search/)\n\nOr install it yourself with NPM:\n\n```\nnpm install --save redux-search\n```\n\nOverview\n---------\n\nThis README provides a quick introduction of redux-search. For more details refer to the [API documentation](https://github.com/bvaughn/redux-search/tree/master/docs).\n\nredux-search searches collections of documents and returns results as an `Array` of document ids. It is important to note that the documents themselves aren't returned. This is because the actual search is performed in a web-worker thread for performance reasons. In order to avoid serializing the documents and passing them back and forth, redux-search simply passes their ids.\n\nBecause of this, each document _must contain an `id` attribute_.\n\nredux-search provides an [action](docs/README.md#createsearchactionresourcename) for searching resources as well as [selectors](docs/README.md#getsearchselectors-filterfunction-resourcename-resourceselector-searchstateselector-) for getting search results and the current search text. It then watches the store for resource changes and automatically updates search results as needed.\n\nNote that redux-search currently depends on the Regenerator runtime. It is recommended that your project require the [`babel-polyfill`](https://babeljs.io/docs/usage/polyfill/) to provide that runtime.\n\nExample\n---------\n\n#### Configuring the Store\n\nredux-search watches the store for changes to searchable collections and automatically builds a search index. To do this, it simply needs to be told which resources to watch and which fields to index.\n\n```javascript\nimport { applyMiddleware, combineReducers, compose, createStore } from 'redux'\nimport { reducer as searchReducer, reduxSearch } from 'redux-search'\n\n// Configure reducer to store state at state.search\n// You can store it elsewhere but you will need to supply your own :searchStateSelector\nconst rootReducer = combineReducers({\n  search: searchReducer\n  // Your other reducers go here...\n})\n\n// Compose :reduxSearch with other store enhancers\nconst enhancer = compose(\n  applyMiddleware(...yourMiddleware),\n  reduxSearch({\n    // Configure redux-search by telling it which resources to index for searching\n    resourceIndexes: {\n      // In this example Books will be searchable by :title and :author\n      books: ['author', 'title']\n    },\n    // This selector is responsible for returning each collection of searchable resources\n    resourceSelector: (resourceName, state) =\u003e {\n      // In our example, all resources are stored in the state under a :resources Map\n      // For example \"books\" are stored under state.resources.books\n      return state.resources.get(resourceName)\n    }\n  })\n)\n\n// Note: passing enhancer as the last argument to createStore requires redux@\u003e=3.1.0\nconst store = createStore(reducer, initialState, enhancer)\n```\n\n#### Customizing Search Index\n\nBy default, redux-search builds an index to match all substrings.\nYou can override this behavior by providing your own, pre-configured `searchApi` param to the middleware like so:\n\n```js\nimport { reduxSearch, SearchApi, INDEX_MODES } from 'redux-search'\n\n// all-substrings match by default; same as current\n// eg \"c\", \"ca\", \"a\", \"at\", \"cat\" match \"cat\"\nconst allSubstringsSearchApi = new SearchApi()\n\n// prefix matching (eg \"c\", \"ca\", \"cat\" match \"cat\")\nconst prefixSearchApi = new SearchApi({\n  indexMode: INDEX_MODES.PREFIXES\n})\n\n// exact words matching (eg only \"cat\" matches \"cat\")\nconst exactWordsSearchApi = new SearchApi({\n  indexMode: INDEX_MODES.EXACT_WORDS\n})\n\nconst finalCreateStore = compose(\n  // Other middleware ...\n  reduxSearch({\n    resourceIndexes: { ... },\n    resourceSelector: (resourceName, state) =\u003e state.resources.get(resourceName),\n    searchApi: allSubstringsSearchApi || prefixSearchApi || exactWordsSearchApi\n  })\n)(createStore)\n```\n\n#### Custom word boundaries (tokenization), case-sensitivity and partial token matching\n\nYou can also pass parameters to the SearchApi constructor that customize the\nway the search splits up the text into words (tokenizes), change the search\nfrom the default case-insensitive to case-sensitive and/or enable matching on\nany search token (changing the search filtering from AND to OR):\n\n```js\nimport { reduxSearch, SearchApi } from 'redux-search'\n\nconst finalCreateStore = compose(\n  // Other middleware ...\n  reduxSearch({\n    resourceIndexes: { ... },\n    resourceSelector: (resourceName, state) =\u003e state.resources.get(resourceName),\n    searchApi: new SearchApi({\n      // split on all non-alphanumeric characters,\n      // so this/that gets split to ['this','that'], for example\n      tokenizePattern: /[^a-z0-9]+/,\n      // make the search case-sensitive\n      caseSensitive: true\n      // return results for documents containing ANY of the search terms.\n      // (by default results are only returned for documents containing ALL of the terms.)\n      // if true, results are sorted so that documents with more matching tokens come first.\n      matchAnyToken: true\n    })\n  })\n)(createStore)\n```\n\n#### Connecting a Component\n\nredux-search provides selectors and action-creators for easily connecting components with the search state. For example, using `reselect` you might connect your component like so:\n\n```javascript\n// Elsewhere, in a smart component module...\nimport { connect } from 'react-redux'\nimport { createSelector } from 'reselect'\nimport { createSearchAction, getSearchSelectors } from 'redux-search'\n\n// :books is a map (Object or Immutable.Map) with ids as keys\n// These ids correspond to :result returned by getSearchSelectors('books')\nconst books = state =\u003e state.getIn(['resources', 'books'])\n\n// :text is a selector that returns the text Books are currently filtered by\n// :result is an Array of Book ids that match the current seach :text (or all Books if there is no search :text)\nconst {\n  text, // search text\n  result // book ids\n} = getSearchSelectors({\n  resourceName: 'books',\n  resourceSelector: (resourceName, state) =\u003e state.resources.get(resourceName)\n})\n\nconst selectors = createSelector(\n  [result, books, text],\n  (bookIds, books, searchText) =\u003e ({\n    bookIds,\n    books,\n    searchText\n  })\n)\n\nconst actions = {\n  searchBooks: createSearchAction('books')\n}\n\nexport default connect(selectors, actions)(YourConnectedComponent)\n```\n\nChangelog\n---------\n\nChanges are tracked in the [changelog](CHANGELOG.md).\n\nLicense\n---------\n\nredux-search is available under the MIT License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbvaughn%2Fredux-search","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbvaughn%2Fredux-search","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbvaughn%2Fredux-search/lists"}