├── recent-searches ├── RecentSearchesUX.gif ├── .npmignore ├── docs ├── RecentSearchesUX.gif ├── assets │ ├── images │ │ ├── icons.png │ │ ├── icons@2x.png │ │ ├── widgets.png │ │ └── widgets@2x.png │ └── js │ │ └── search.js ├── modules │ ├── ___tests___memorystorage_test_.html │ ├── ___tests___safelocalstorage_test_.html │ ├── _memorystorage_.html │ ├── _index_.html │ ├── ___tests___recentsearches_test_.html │ └── _safelocalstorage_.html ├── globals.html ├── interfaces │ ├── _safelocalstorage_.safelocalstorageconfig.html │ ├── _index_.recentsearchesconfig.html │ ├── _safelocalstorage_.isafelocalstorage.html │ └── _memorystorage_.imemorystorage.html └── classes │ └── _safelocalstorage_.safelocalstorage.html ├── .gitignore ├── tslint.json ├── jest.setup.js ├── lib ├── utils │ ├── string.ts │ ├── __tests__ │ │ └── string.test.ts │ └── score.ts ├── __tests__ │ ├── MemoryStorage.test.ts │ ├── SafeLocalStorage.test.ts │ └── index.test.ts ├── MemoryStorage.ts ├── SafeLocalStorage.ts └── index.ts ├── .babelrc ├── jest.config.js ├── .circleci └── config.yml ├── tsconfig.json ├── webpack.config.js ├── package.json └── README.md /recent-searches: -------------------------------------------------------------------------------- 1 | node_modules/recent-searches -------------------------------------------------------------------------------- /RecentSearchesUX.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JonasBa/recent-searches/HEAD/RecentSearchesUX.gif -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Ignore lib folder 2 | lib/ 3 | .circleci/ 4 | coverage/ 5 | jest.config.js 6 | jest.setup.js -------------------------------------------------------------------------------- /docs/RecentSearchesUX.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JonasBa/recent-searches/HEAD/docs/RecentSearchesUX.gif -------------------------------------------------------------------------------- /docs/assets/images/icons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JonasBa/recent-searches/HEAD/docs/assets/images/icons.png -------------------------------------------------------------------------------- /docs/assets/images/icons@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JonasBa/recent-searches/HEAD/docs/assets/images/icons@2x.png -------------------------------------------------------------------------------- /docs/assets/images/widgets.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JonasBa/recent-searches/HEAD/docs/assets/images/widgets.png -------------------------------------------------------------------------------- /docs/assets/images/widgets@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JonasBa/recent-searches/HEAD/docs/assets/images/widgets@2x.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # dependencies 3 | /node_modules 4 | 5 | # production 6 | /dist 7 | 8 | # tests 9 | /coverage 10 | 11 | # misc 12 | .DS_Store 13 | .env 14 | npm-debug.log 15 | 16 | # errors 17 | yarn-error.log 18 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "defaultSeverity": "error", 3 | "extends": [ 4 | "tslint:recommended", 5 | "tslint-config-prettier" 6 | ], 7 | "jsRules": {}, 8 | "rules": {}, 9 | "rulesDirectory": [] 10 | } -------------------------------------------------------------------------------- /jest.setup.js: -------------------------------------------------------------------------------- 1 | const DATE_TO_USE = new Date(1554477808049); 2 | const _Date = Date; 3 | 4 | global.Date = jest.fn(() => DATE_TO_USE); 5 | global.Date.UTC = _Date.UTC; 6 | global.Date.parse = _Date.parse; 7 | global.Date.now = _Date.now; 8 | global.Date.getTime = _Date.getTime -------------------------------------------------------------------------------- /lib/utils/string.ts: -------------------------------------------------------------------------------- 1 | const isBlank = (str: string = ""): boolean => { 2 | return /^\s*$/.test(str); 3 | }; 4 | 5 | const isValidQuery = (query?: any): query is string | number => { 6 | return ( 7 | (typeof query === "string" && !isBlank(query)) || typeof query === "number" 8 | ); 9 | }; 10 | 11 | export default isValidQuery; 12 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { 4 | "corejs": 3, 5 | "targets": { 6 | "ie": "11" 7 | } 8 | }], 9 | "@babel/typescript" 10 | ], 11 | "plugins": [ 12 | ["module-resolver", { 13 | "root": ["./lib"] 14 | }], 15 | "@babel/proposal-class-properties", 16 | "@babel/proposal-object-rest-spread" 17 | ], 18 | "ignore": [ 19 | "**/*/__tests__/*" 20 | ] 21 | } -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // "collectCoverage": true, 3 | "roots": [ 4 | "/lib" 5 | ], 6 | "transform": { 7 | "^.+\\.tsx?$": "ts-jest" 8 | }, 9 | "setupFiles": [ 10 | "./jest.setup.js", 11 | "jest-localstorage-mock" 12 | ], 13 | "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.tsx?$", 14 | "moduleFileExtensions": [ 15 | "ts", 16 | "tsx", 17 | "js", 18 | "jsx", 19 | "json", 20 | "node" 21 | ], 22 | } -------------------------------------------------------------------------------- /lib/utils/__tests__/string.test.ts: -------------------------------------------------------------------------------- 1 | import isValidQuery from "../string"; 2 | 3 | describe("isValidQuery", () => { 4 | it("valid", () => { 5 | expect(expect(isValidQuery(" some data ")).toBe(true)); 6 | expect(expect(isValidQuery(0)).toBe(true)); 7 | expect(expect(isValidQuery(1000)).toBe(true)); 8 | }); 9 | 10 | it("invalid", () => { 11 | expect(isValidQuery("")).toBe(false); 12 | expect(isValidQuery(" ")).toBe(false); 13 | expect(isValidQuery(undefined)).toBe(false); 14 | expect(isValidQuery(null as any)).toBe(false); 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /lib/__tests__/MemoryStorage.test.ts: -------------------------------------------------------------------------------- 1 | import MemoryStorage from "./../MemoryStorage"; 2 | 3 | describe("MemoryStorage", () => { 4 | describe("setItem", () => { 5 | const storage = new MemoryStorage({ 6 | defaultValue: ["test"], 7 | key: "some_key" 8 | }); 9 | 10 | it("default value", () => { 11 | expect(storage.getItem()).toEqual(["test"]); 12 | }); 13 | }); 14 | 15 | describe("setItem", () => { 16 | const storage = new MemoryStorage({ 17 | defaultValue: ["test"], 18 | key: "some_key" 19 | }); 20 | 21 | expect(storage.setItem(["test", "new_test"])).toBe(true); 22 | expect(storage.getItem()).toEqual(["test", "new_test"]); 23 | }); 24 | }); 25 | -------------------------------------------------------------------------------- /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Javascript Node CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-javascript/ for more details 4 | # 5 | version: 2 6 | jobs: 7 | build: 8 | docker: 9 | # specify the version you desire here 10 | - image: circleci/node:latest 11 | working_directory: ~/repo 12 | 13 | steps: 14 | - checkout 15 | 16 | # Download and cache dependencies 17 | - restore_cache: 18 | keys: 19 | - v1-dependencies-{{ checksum "package.json" }} 20 | # fallback to using the latest cache if no exact match is found 21 | - v1-dependencies- 22 | 23 | - run: yarn install 24 | 25 | - save_cache: 26 | paths: 27 | - node_modules 28 | key: v1-dependencies-{{ checksum "package.json" }} 29 | 30 | # run tests! 31 | - run: yarn lint 32 | - run: yarn test -------------------------------------------------------------------------------- /lib/MemoryStorage.ts: -------------------------------------------------------------------------------- 1 | import { 2 | DEFAULT_STORAGE_KEY, 3 | ISafeLocalStorage, 4 | ISafeLocalStorageConfig 5 | } from "./SafeLocalStorage"; 6 | 7 | interface IMemoryStorage extends ISafeLocalStorage { 8 | readonly DATA: { [key: string]: T }; 9 | } 10 | 11 | class MemoryStorage implements IMemoryStorage { 12 | public readonly DATA: { [key: string]: T } = {}; 13 | private readonly KEY: string; 14 | private readonly DEFAULT_VALUE: T; 15 | 16 | constructor(config: ISafeLocalStorageConfig) { 17 | const { key, defaultValue } = config; 18 | 19 | this.DATA = {}; 20 | this.KEY = key || DEFAULT_STORAGE_KEY; 21 | this.DEFAULT_VALUE = defaultValue; 22 | } 23 | 24 | public getItem = (): T => this.DATA[this.KEY] || this.DEFAULT_VALUE; 25 | public setItem = (data: T): boolean => { 26 | this.DATA[this.KEY] = data; 27 | return true; 28 | }; 29 | } 30 | 31 | export default MemoryStorage; 32 | -------------------------------------------------------------------------------- /lib/utils/score.ts: -------------------------------------------------------------------------------- 1 | import { ISearch, RankingStrategy } from "./../"; 2 | 3 | const computeMatchScore = ( 4 | search: ISearch, 5 | query: string | number, 6 | rankBy: RankingStrategy, 7 | ttl: number 8 | ): number => { 9 | const normalizedQuery = String(query); 10 | 11 | switch (rankBy) { 12 | case "PROXIMITY": 13 | return search.query.indexOf(normalizedQuery); 14 | case "TIME": 15 | return Math.log10(new Date().getTime() - search.timestamp); 16 | default: 17 | const matchDistance = search.query.indexOf(normalizedQuery); 18 | const timeDelta = Math.log2( 19 | (new Date().getTime() - search.timestamp) / ttl + 1 20 | ); 21 | const proximity = Math.log2(matchDistance + 1) || 1; 22 | 23 | if (matchDistance === -1) { 24 | return matchDistance; 25 | } 26 | 27 | return (0.01 + 0.49 * proximity + 0.49 * timeDelta) / 1; 28 | } 29 | }; 30 | 31 | export default computeMatchScore; 32 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */ 4 | "module": "umd", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ 5 | "declaration": true, /* Generates corresponding '.d.ts' file. */ 6 | "emitDeclarationOnly": true, /* Emit declarations only, babel emits js files */ 7 | "outDir": "./dist", /* Redirect output structure to the directory. */ 8 | "strict": true, /* Enable all strict type-checking options. */ 9 | "esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */ 10 | }, 11 | "exclude": [ 12 | "**/__tests__/*.test.ts" 13 | ] 14 | } -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); 2 | 3 | const baseConfig = targetOptions => ({ 4 | target: "web", 5 | entry: { 6 | index: "./lib/index.ts", 7 | "index.min": "./lib/index.ts" 8 | }, 9 | output: { 10 | filename: 11 | targetOptions.libraryTarget === "umd" 12 | ? `./[name].js` 13 | : `./[name].${targetOptions.libraryTarget}.js`, 14 | library: "RecentSearches", 15 | globalObject: "this", 16 | ...targetOptions 17 | }, 18 | mode: "production", 19 | devtool: "source-map", 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.ts$/, 24 | use: ["babel-loader"] 25 | } 26 | ] 27 | }, 28 | optimization: { 29 | minimize: true, 30 | minimizer: [ 31 | new UglifyJsPlugin({ 32 | include: /\.min\.js$/, 33 | uglifyOptions: { 34 | output: { 35 | comments: false 36 | } 37 | } 38 | }) 39 | ] 40 | }, 41 | resolve: { 42 | extensions: [".ts", ".js"] 43 | } 44 | }); 45 | 46 | module.exports = [ 47 | baseConfig({ libraryTarget: "umd" }), 48 | baseConfig({ libraryTarget: "var" }) 49 | ]; 50 | -------------------------------------------------------------------------------- /lib/SafeLocalStorage.ts: -------------------------------------------------------------------------------- 1 | import MemoryStorage from "./MemoryStorage"; 2 | 3 | export const DEFAULT_STORAGE_KEY = "__RECENT_SEARCHES__"; 4 | export const isLocalStorageSupported = (): boolean => { 5 | const key = "__TEST__KEY__"; 6 | 7 | try { 8 | localStorage.setItem(key, ""); 9 | localStorage.removeItem(key); 10 | return true; 11 | } catch (error) { 12 | return false; 13 | } 14 | }; 15 | 16 | export const safeDataParse = (data: string | null, defaultValue: T): T => { 17 | if (!data) { 18 | return defaultValue; 19 | } 20 | 21 | try { 22 | return JSON.parse(data); 23 | } catch (e) { 24 | return defaultValue; 25 | } 26 | }; 27 | 28 | export interface ISafeLocalStorageConfig { 29 | defaultValue: T; 30 | key?: string; 31 | limit?: number; 32 | } 33 | 34 | export interface ISafeLocalStorage { 35 | getItem: () => T; 36 | setItem: (item: T) => boolean; 37 | } 38 | 39 | export class SafeLocalStorage implements ISafeLocalStorage { 40 | private readonly KEY: string; 41 | private readonly DEFAULT_VALUE: T; 42 | 43 | constructor(config: ISafeLocalStorageConfig) { 44 | const { key, defaultValue } = config; 45 | 46 | this.KEY = key || DEFAULT_STORAGE_KEY; 47 | this.DEFAULT_VALUE = defaultValue; 48 | } 49 | 50 | public getItem = (): T => { 51 | const data = localStorage.getItem(this.KEY); 52 | return safeDataParse(data, this.DEFAULT_VALUE); 53 | }; 54 | 55 | public setItem = (items: T): boolean => { 56 | try { 57 | localStorage.setItem(this.KEY, JSON.stringify(items)); 58 | return true; 59 | } catch (e) { 60 | return false; 61 | } 62 | }; 63 | } 64 | 65 | const NewSafeLocalStorage = ( 66 | config: ISafeLocalStorageConfig 67 | ): SafeLocalStorage | MemoryStorage => { 68 | if (!isLocalStorageSupported()) { 69 | return new MemoryStorage(config); 70 | } 71 | 72 | return new SafeLocalStorage(config); 73 | }; 74 | 75 | export default NewSafeLocalStorage; 76 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "recent-searches", 3 | "version": "1.0.3", 4 | "repository": { 5 | "type": "git", 6 | "url": "git+https://github.com/JonasBa/recent-searches.git" 7 | }, 8 | "author": "Jonas Badalic ", 9 | "main": "dist/index.js", 10 | "scripts": { 11 | "build": "npm run clean && npm run build:types && npm run build:webpack", 12 | "build:webpack": "webpack --config webpack.config.js", 13 | "build:types": "tsc --p tsconfig.json", 14 | "clean": "rm -rf ./dist", 15 | "docgen": "typedoc --out docs ./lib", 16 | "lint": "tslint ./lib/**/*.ts -e \"./**/*/__tests__/*.ts\"", 17 | "release": "npm run lint && npm run clean && npm run build && npm version && npm publish", 18 | "release:beta": "npm run lint && npm run clean && npm run build && npm version && npm publish --tag beta", 19 | "postversion": "git push && git push --tags", 20 | "test": "jest --coverage", 21 | "test:watch": "jest --watch" 22 | }, 23 | "keywords": [ 24 | "search", 25 | "algolia", 26 | "elasticsearch", 27 | "swiftype" 28 | ], 29 | "types": "dist/index.d.ts", 30 | "license": "MIT", 31 | "bugs": { 32 | "url": "https://github.com/JonasBa/recent-searches/issues" 33 | }, 34 | "homepage": "https://github.com/JonasBa/recent-searches#readme", 35 | "description": "A JavaScript module to help anyone easily build recent searches functionality into their search.", 36 | "directories": { 37 | "lib": "lib" 38 | }, 39 | "devDependencies": { 40 | "@babel/cli": "^7.5.5", 41 | "@babel/core": "^7.5.5", 42 | "@babel/plugin-proposal-class-properties": "^7.5.5", 43 | "@babel/plugin-proposal-object-rest-spread": "^7.5.5", 44 | "@babel/preset-env": "^7.5.5", 45 | "@babel/preset-typescript": "^7.3.3", 46 | "@types/jest": "^24.0.18", 47 | "babel-loader": "^8.0.6", 48 | "babel-plugin-module-resolver": "^3.2.0", 49 | "core-js": "^3.2.1", 50 | "jest": "^24.9.0", 51 | "jest-localstorage-mock": "^2.4.0", 52 | "ts-jest": "^24.0.2", 53 | "tslint": "^5.19.0", 54 | "tslint-config-prettier": "^1.18.0", 55 | "typescript": "^3.5.3", 56 | "uglifyjs-webpack-plugin": "^2.2.0", 57 | "webpack": "^4.39.2", 58 | "webpack-cli": "^3.3.7" 59 | }, 60 | "dependencies": {} 61 | } 62 | -------------------------------------------------------------------------------- /lib/__tests__/SafeLocalStorage.test.ts: -------------------------------------------------------------------------------- 1 | import MemoryStorage from "../MemoryStorage"; 2 | import SafeLocalStorage, { 3 | DEFAULT_STORAGE_KEY, 4 | isLocalStorageSupported, 5 | SafeLocalStorage as SafeLocalStorageClass 6 | } from "./../SafeLocalStorage"; 7 | 8 | describe("SafeLocalStorage", () => { 9 | beforeEach(() => { 10 | localStorage.clear(); 11 | jest.clearAllMocks(); 12 | }); 13 | 14 | describe("isLocalStorageSupported", () => { 15 | it("is supported", () => { 16 | expect(isLocalStorageSupported()).toBe(true); 17 | }); 18 | 19 | it("not supported", () => { 20 | const spy = jest.spyOn(localStorage, "setItem"); 21 | 22 | spy.mockImplementationOnce(() => { 23 | throw new Error("Dead"); 24 | }); 25 | 26 | expect(isLocalStorageSupported()).toBe(false); 27 | expect(localStorage.setItem).toHaveBeenCalled(); 28 | expect(localStorage.removeItem).not.toHaveBeenCalled(); 29 | }); 30 | }); 31 | 32 | describe("storage", () => { 33 | it("supports localStorage", () => { 34 | expect( 35 | SafeLocalStorage({ key: "test", defaultValue: ["test"] }) 36 | ).toBeInstanceOf(SafeLocalStorageClass); 37 | }); 38 | 39 | it("has defaults", () => { 40 | const storage = SafeLocalStorage({ defaultValue: [] }); 41 | expect((storage as any).KEY).toBe(DEFAULT_STORAGE_KEY); 42 | expect((storage as any).DEFAULT_VALUE).toEqual([]); 43 | }); 44 | 45 | it("does not support localStorage -> uses memorystorage", () => { 46 | const spy = jest.spyOn(localStorage, "setItem"); 47 | 48 | spy.mockImplementationOnce(() => { 49 | throw new Error("Dead"); 50 | }); 51 | 52 | expect( 53 | SafeLocalStorage({ key: "test", defaultValue: ["test"] }) 54 | ).toBeInstanceOf(MemoryStorage); 55 | }); 56 | }); 57 | 58 | describe("getItem", () => { 59 | const storage = SafeLocalStorage({ key: "test", defaultValue: ["test"] }); 60 | 61 | it("has default", () => { 62 | expect(storage.getItem()).toEqual(["test"]); 63 | }); 64 | 65 | it("handles error", () => { 66 | localStorage.setItem("test", "some\\werror"); 67 | 68 | expect(storage.getItem).not.toThrowError(); 69 | expect(storage.getItem()).toEqual(["test"]); 70 | }); 71 | }); 72 | 73 | describe("setItem", () => { 74 | const storage = SafeLocalStorage>({ 75 | defaultValue: [], 76 | key: "some_key" 77 | }); 78 | 79 | it("stringifies to storage", () => { 80 | storage.setItem([{ query: "something" }]); 81 | expect(localStorage.__STORE__).toEqual({ 82 | some_key: '[{"query":"something"}]' 83 | }); 84 | }); 85 | 86 | it("calls removeItem if storage is full", () => { 87 | const spy = jest.spyOn(localStorage, "setItem"); 88 | spy.mockImplementation(() => { 89 | throw new Error("Dead"); 90 | }); 91 | 92 | expect(storage.setItem([])).toBe(false); 93 | }); 94 | }); 95 | }); 96 | -------------------------------------------------------------------------------- /lib/index.ts: -------------------------------------------------------------------------------- 1 | import MemoryStorage from "./MemoryStorage"; 2 | import LocalStorage, { SafeLocalStorage } from "./SafeLocalStorage"; 3 | 4 | import computeMatchScore from "./utils/score"; 5 | import isValidQuery from "./utils/string"; 6 | 7 | export interface ISearch { 8 | query: string; 9 | timestamp: number; 10 | data?: { 11 | [key: string]: string; 12 | }; 13 | } 14 | 15 | export type ScoredSearch = ISearch & { 16 | score: number; 17 | }; 18 | 19 | export type RankingStrategy = "PROXIMITY" | "TIME" | "PROXIMITY_AND_TIME"; 20 | 21 | export interface IRecentSearchesConfig { 22 | ttl?: number; 23 | limit?: number; 24 | namespace?: string; 25 | ranking?: RankingStrategy; 26 | } 27 | 28 | export type RecentSearchesStorage = 29 | | SafeLocalStorage 30 | | MemoryStorage; 31 | 32 | export class RecentSearches { 33 | private readonly TTL: number; 34 | private readonly LIMIT: number; 35 | private readonly STORAGE: RecentSearchesStorage; 36 | private readonly RANKING: RankingStrategy; 37 | 38 | private RECENT_SEARCHES: ISearch[] = []; 39 | 40 | constructor(config: IRecentSearchesConfig = {}) { 41 | this.TTL = config.ttl || 1000 * 60 * 60 * 24; 42 | this.LIMIT = config.limit || 50; 43 | this.STORAGE = LocalStorage({ 44 | defaultValue: [], 45 | key: config.namespace 46 | }); 47 | this.RECENT_SEARCHES = this.initializeStorageData(); 48 | this.RANKING = config.ranking || "PROXIMITY_AND_TIME"; 49 | } 50 | 51 | /** 52 | * Retrieve recent searches for a given query. 53 | * If no query is passed, returns all recent searches 54 | * 55 | * @param {string} query? 56 | * @returns Search[] 57 | */ 58 | public getRecentSearches = (query?: string | number): ISearch[] => { 59 | if (!isValidQuery(query)) { 60 | return this.RECENT_SEARCHES; 61 | } 62 | 63 | const matchedSearches = this.RECENT_SEARCHES.map(search => { 64 | const score = computeMatchScore(search, query, this.RANKING, this.TTL); 65 | 66 | return { 67 | data: search.data, 68 | query: search.query, 69 | score, 70 | timestamp: search.timestamp 71 | }; 72 | }) 73 | .filter(this.filterScoredResults) 74 | .sort(this.sortScoredResults) 75 | .map(search => ({ 76 | data: search.data, 77 | query: search.query, 78 | timestamp: search.timestamp 79 | })); 80 | 81 | return matchedSearches; 82 | }; 83 | 84 | /** 85 | * Set a recent search and data related to it. 86 | * 87 | * @param {string} query 88 | * @param {object} data? 89 | * @returns Search[] 90 | */ 91 | public setRecentSearch = ( 92 | query: string | number, 93 | data?: ISearch["data"] 94 | ): ISearch[] => { 95 | if (!isValidQuery(query)) { 96 | return this.RECENT_SEARCHES; 97 | } 98 | 99 | const search: ISearch = { 100 | data, 101 | query: String(query), 102 | timestamp: new Date().getTime() 103 | }; 104 | 105 | const existingQueryIndex = this.RECENT_SEARCHES.findIndex( 106 | searchEntry => searchEntry.query === query 107 | ); 108 | 109 | if (existingQueryIndex > -1) { 110 | this.RECENT_SEARCHES.splice(existingQueryIndex, 1); 111 | } 112 | 113 | this.RECENT_SEARCHES.unshift(search); 114 | this.RECENT_SEARCHES = this.RECENT_SEARCHES.slice(0, this.LIMIT); 115 | this.STORAGE.setItem(this.RECENT_SEARCHES); 116 | 117 | return this.RECENT_SEARCHES; 118 | }; 119 | 120 | private filterScoredResults = (search: ScoredSearch): boolean => { 121 | if (this.RANKING === "TIME") { 122 | return true; 123 | } 124 | 125 | return search.score > -1; 126 | }; 127 | 128 | private sortScoredResults = (a: ScoredSearch, b: ScoredSearch): number => { 129 | return a.score - b.score; 130 | }; 131 | 132 | private initializeStorageData = (): ISearch[] => { 133 | const currentTimestamp = new Date().getTime(); 134 | 135 | const items = this.STORAGE.getItem() 136 | .filter(search => search.timestamp + this.TTL >= currentTimestamp) 137 | .slice(0, this.LIMIT); 138 | 139 | this.STORAGE.setItem(items); 140 | this.RECENT_SEARCHES = items; 141 | return items; 142 | }; 143 | } 144 | 145 | export default RecentSearches; 146 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | recent-searches 🕵️‍♀️🕵️‍♂️ 3 |
4 |
5 |

6 |

A zero dependency JavaScript module that helps anyone build recent searches functionality into their search bar. 7 |

8 | 9 | 10 |
11 | 12 | [![Build Status][build-badge]][build] 13 | [![downloads][downloads-badge]][npmcharts] [![version][version-badge]][package] 14 | [![MIT License][license-badge]][license] 15 | [![PRs Welcome][prs-badge]][prs] 16 | [![size][size-badge]][unpkg-dist] [![gzip size][gzip-badge]][unpkg-dist] 17 | 18 | ![Example implementation](https://raw.githubusercontent.com/JonasBa/recent-searches/master/RecentSearchesUX.gif) 19 | 20 | ## The problem 21 | 22 | Building recent searches experience can be trickier than you think (expiry of queries, ranking of recent queries, handling storage etc...) 23 | 24 | ## Solution 25 | recent-searches module helps you build that experience without having to focus on the edge cases and technical details. If available, uses [localStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage) to store suggestions cross sessions and in the rare cases where it might not be available uses a fallback memory storage, thus loosing it's cross session functionality. 26 | 27 | __The module handles:__ 28 | - Searching and retrieving recent searches 29 | - Ranking of searches and decaying their popularity (with different ranking options) 30 | - Saving and expiring of searches through LocalStorage or MemoryStorage 31 | - LocalStorage feature detection (with fallback to MemoryStorage) 32 | - Safe LocalStorage usage (feature detection, limiting storage) 33 | 34 | ## Table of Contents 35 | 36 | 37 | 38 | 39 | - [Installation](#installation) 40 | - [Usage](#usage) 41 | - [LICENSE](#license) 42 | 43 | 44 | 45 | ## Installation 46 | 47 | recent-searches is published on npm's public registry, you can install it as a dependancy of your project with the following command. 48 | ``` 49 | npm install --save recent-searches 50 | ``` 51 | 52 | ## Usage 53 | 54 | > [Standalone codesandbox example](https://codesandbox.io/s/8k21924m5l)
55 | > [Algolia react-instantsearch codesandbox example](https://codesandbox.io/s/m18wjy69)
56 | > [Algolia InstantSearch.js codesandbox example](https://codesandbox.io/s/62j3k7097r) 57 | Initializing the module 58 | 59 | ```ts 60 | import RecentSearches from 'recent-searches' 61 | 62 | const searches = new RecentSearches({ 63 | ttl: number, // Optional: ttl of searches in milliseconds, default to 24h (1000 * 60 * 60 * 24) 64 | limit: number, // Optional: max number of entries that will be persisted, default is 50 65 | namespace: string, // Optional: custom localStorage namespace 66 | ranking: string // Optional: ranking strategy of recent searches, "PROXIMITY" | "TIME" | "PROXIMITY_AND_TIME", default is "PROXIMITY_AND_TIME" 67 | }) 68 | 69 | ``` 70 | 71 | Setting and retrieving relevant searches. 72 | 73 | ```ts 74 | // Retrieve searches for a given query 75 | const previousSearchesForJohn = searches.getRecentSearches("John") 76 | /* 77 | [ 78 | {query: "John", data: {...}, timestamp: ...}, 79 | {query: "Marc John", data: {...}, timestamp: ...} 80 | ] 81 | */ 82 | 83 | // To set a recent search 84 | searches.setRecentSearch("John", resultData) 85 | 86 | ``` 87 | 88 | If you built something using recent-searches that you want to show, feel free to send us a link and we'll include it to the documentation! 89 | 90 | ## Contributing 91 | 92 | This project is open to contributions, if you have a question, proposal or feedback please open a pull request or issue, we only ask you to be kind and respectful :) 93 | 94 | Special thanks to [Kent C. Dodds](https://twitter.com/kentcdodds?ref_src=twsrc%5Egoogle%7Ctwcamp%5Eserp%7Ctwgr%5Eauthor) for building downshift (making that demo was much easier) 95 | 96 | ## LICENSE 97 | 98 | MIT 99 | 100 | [npm]: https://www.npmjs.com/ 101 | [node]: https://nodejs.org 102 | [build-badge]: https://circleci.com/gh/JonasBa/recent-searches/tree/master.svg?style=svg 103 | [build]: https://circleci.com/gh/JonasBa/recent-searches 104 | [coverage-badge]: https://img.shields.io/codecov/c/github/recent-searches/recent-searches.svg?style=flat-square 105 | [coverage]: https://codecov.io/github/recent-searches/recent-searches 106 | [version-badge]: https://img.shields.io/npm/v/recent-searches.svg?style=flat-square 107 | [package]: https://www.npmjs.com/package/recent-searches 108 | [downloads-badge]: https://img.shields.io/npm/dm/recent-searches.svg?style=flat-square 109 | [npmcharts]: http://npmcharts.com/compare/recent-searches 110 | [license-badge]: https://img.shields.io/npm/l/recent-searches.svg?style=flat-square 111 | [license]: https://github.com/recent-searches/recent-searches/blob/master/LICENSE 112 | [prs-badge]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square 113 | [prs]: http://makeapullrequest.com 114 | [react-badge]: https://img.shields.io/badge/%E2%9A%9B%EF%B8%8F-(p)react-00d8ff.svg?style=flat-square 115 | [react]: https://facebook.github.io/react/ 116 | [gzip-badge]: http://img.badgesize.io/https://unpkg.com/recent-searches/dist/index.min.js?compression=gzip&label=gzip%20size&style=flat-square 117 | [size-badge]: http://img.badgesize.io/https://unpkg.com/recent-searches/dist/index.min.js?label=size&style=flat-square 118 | [unpkg-dist]: https://unpkg.com/recent-searches/dist/ 119 | [module-formats-badge]: https://img.shields.io/badge/module%20formats-umd%2C%20cjs%2C%20es-green.svg?style=flat-square 120 | [spectrum-badge]: https://withspectrum.github.io/badge/badge.svg 121 | [spectrum]: https://spectrum.chat/recent-searches 122 | [emojis]: https://github.com/kentcdodds/all-contributors#emoji-key 123 | [all-contributors]: https://github.com/kentcdodds/all-contributors 124 | [ryan]: https://github.com/ryanflorence 125 | [compound-components-lecture]: https://courses.reacttraining.com/courses/advanced-react/lectures/3060560 126 | [react-autocomplete]: https://www.npmjs.com/package/react-autocomplete 127 | [jquery-complete]: https://jqueryui.com/autocomplete/ 128 | [examples]: https://codesandbox.io/search?refinementList%5Btags%5D%5B0%5D=recent-searches%3Aexample&page=1 129 | [yt-playlist]: https://www.youtube.com/playlist?list=PLV5CVI1eNcJh5CTgArGVwANebCrAh2OUE -------------------------------------------------------------------------------- /docs/modules/___tests___memorystorage_test_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "__tests__/MemoryStorage.test" | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "__tests__/MemoryStorage.test"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 101 |
102 |
103 |
104 |
105 |

Legend

106 |
107 |
    108 |
  • Module
  • 109 |
  • Object literal
  • 110 |
  • Variable
  • 111 |
  • Function
  • 112 |
  • Function with type parameter
  • 113 |
  • Index signature
  • 114 |
  • Type alias
  • 115 |
116 |
    117 |
  • Enumeration
  • 118 |
  • Enumeration member
  • 119 |
  • Property
  • 120 |
  • Method
  • 121 |
122 |
    123 |
  • Interface
  • 124 |
  • Interface with type parameter
  • 125 |
  • Constructor
  • 126 |
  • Property
  • 127 |
  • Method
  • 128 |
  • Index signature
  • 129 |
130 |
    131 |
  • Class
  • 132 |
  • Class with type parameter
  • 133 |
  • Constructor
  • 134 |
  • Property
  • 135 |
  • Method
  • 136 |
  • Accessor
  • 137 |
  • Index signature
  • 138 |
139 |
    140 |
  • Inherited constructor
  • 141 |
  • Inherited property
  • 142 |
  • Inherited method
  • 143 |
  • Inherited accessor
  • 144 |
145 |
    146 |
  • Protected property
  • 147 |
  • Protected method
  • 148 |
  • Protected accessor
  • 149 |
150 |
    151 |
  • Private property
  • 152 |
  • Private method
  • 153 |
  • Private accessor
  • 154 |
155 |
    156 |
  • Static property
  • 157 |
  • Static method
  • 158 |
159 |
160 |
161 |
162 |
163 |

Generated using TypeDoc

164 |
165 |
166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/modules/___tests___safelocalstorage_test_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "__tests__/SafeLocalStorage.test" | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "__tests__/SafeLocalStorage.test"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 101 |
102 |
103 |
104 |
105 |

Legend

106 |
107 |
    108 |
  • Module
  • 109 |
  • Object literal
  • 110 |
  • Variable
  • 111 |
  • Function
  • 112 |
  • Function with type parameter
  • 113 |
  • Index signature
  • 114 |
  • Type alias
  • 115 |
116 |
    117 |
  • Enumeration
  • 118 |
  • Enumeration member
  • 119 |
  • Property
  • 120 |
  • Method
  • 121 |
122 |
    123 |
  • Interface
  • 124 |
  • Interface with type parameter
  • 125 |
  • Constructor
  • 126 |
  • Property
  • 127 |
  • Method
  • 128 |
  • Index signature
  • 129 |
130 |
    131 |
  • Class
  • 132 |
  • Class with type parameter
  • 133 |
  • Constructor
  • 134 |
  • Property
  • 135 |
  • Method
  • 136 |
  • Accessor
  • 137 |
  • Index signature
  • 138 |
139 |
    140 |
  • Inherited constructor
  • 141 |
  • Inherited property
  • 142 |
  • Inherited method
  • 143 |
  • Inherited accessor
  • 144 |
145 |
    146 |
  • Protected property
  • 147 |
  • Protected method
  • 148 |
  • Protected accessor
  • 149 |
150 |
    151 |
  • Private property
  • 152 |
  • Private method
  • 153 |
  • Private accessor
  • 154 |
155 |
    156 |
  • Static property
  • 157 |
  • Static method
  • 158 |
159 |
160 |
161 |
162 |
163 |

Generated using TypeDoc

164 |
165 |
166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /docs/globals.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 59 |

recent-searches

60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |

Index

68 |
69 | 82 |
83 |
84 |
85 | 116 |
117 |
118 |
119 |
120 |

Legend

121 |
122 |
    123 |
  • Module
  • 124 |
  • Object literal
  • 125 |
  • Variable
  • 126 |
  • Function
  • 127 |
  • Function with type parameter
  • 128 |
  • Index signature
  • 129 |
  • Type alias
  • 130 |
131 |
    132 |
  • Enumeration
  • 133 |
  • Enumeration member
  • 134 |
  • Property
  • 135 |
  • Method
  • 136 |
137 |
    138 |
  • Interface
  • 139 |
  • Interface with type parameter
  • 140 |
  • Constructor
  • 141 |
  • Property
  • 142 |
  • Method
  • 143 |
  • Index signature
  • 144 |
145 |
    146 |
  • Class
  • 147 |
  • Class with type parameter
  • 148 |
  • Constructor
  • 149 |
  • Property
  • 150 |
  • Method
  • 151 |
  • Accessor
  • 152 |
  • Index signature
  • 153 |
154 |
    155 |
  • Inherited constructor
  • 156 |
  • Inherited property
  • 157 |
  • Inherited method
  • 158 |
  • Inherited accessor
  • 159 |
160 |
    161 |
  • Protected property
  • 162 |
  • Protected method
  • 163 |
  • Protected accessor
  • 164 |
165 |
    166 |
  • Private property
  • 167 |
  • Private method
  • 168 |
  • Private accessor
  • 169 |
170 |
    171 |
  • Static property
  • 172 |
  • Static method
  • 173 |
174 |
175 |
176 |
177 |
178 |

Generated using TypeDoc

179 |
180 |
181 | 182 | 183 | 184 | -------------------------------------------------------------------------------- /docs/modules/_memorystorage_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "MemoryStorage" | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "MemoryStorage"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |

Interfaces

81 | 84 |
85 |
86 |
87 |
88 |
89 | 126 |
127 |
128 |
129 |
130 |

Legend

131 |
132 |
    133 |
  • Module
  • 134 |
  • Object literal
  • 135 |
  • Variable
  • 136 |
  • Function
  • 137 |
  • Function with type parameter
  • 138 |
  • Index signature
  • 139 |
  • Type alias
  • 140 |
141 |
    142 |
  • Enumeration
  • 143 |
  • Enumeration member
  • 144 |
  • Property
  • 145 |
  • Method
  • 146 |
147 |
    148 |
  • Interface
  • 149 |
  • Interface with type parameter
  • 150 |
  • Constructor
  • 151 |
  • Property
  • 152 |
  • Method
  • 153 |
  • Index signature
  • 154 |
155 |
    156 |
  • Class
  • 157 |
  • Class with type parameter
  • 158 |
  • Constructor
  • 159 |
  • Property
  • 160 |
  • Method
  • 161 |
  • Accessor
  • 162 |
  • Index signature
  • 163 |
164 |
    165 |
  • Inherited constructor
  • 166 |
  • Inherited property
  • 167 |
  • Inherited method
  • 168 |
  • Inherited accessor
  • 169 |
170 |
    171 |
  • Protected property
  • 172 |
  • Protected method
  • 173 |
  • Protected accessor
  • 174 |
175 |
    176 |
  • Private property
  • 177 |
  • Private method
  • 178 |
  • Private accessor
  • 179 |
180 |
    181 |
  • Static property
  • 182 |
  • Static method
  • 183 |
184 |
185 |
186 |
187 |
188 |

Generated using TypeDoc

189 |
190 |
191 | 192 | 193 | 194 | -------------------------------------------------------------------------------- /lib/__tests__/index.test.ts: -------------------------------------------------------------------------------- 1 | import RecentSearches from ".."; 2 | 3 | const memoryStorageEnvironment = { 4 | after: () => void 0, 5 | before: () => { 6 | const spy = jest.spyOn(localStorage, "setItem"); 7 | 8 | spy.mockImplementationOnce(() => { 9 | throw new Error("Dead"); 10 | }); 11 | }, 12 | label: "MemoryStorage" 13 | }; 14 | 15 | const localStorageEnvironment = { 16 | after: () => { 17 | localStorage.clear(); 18 | }, 19 | before: () => void 0, 20 | label: "LocalStorage" 21 | }; 22 | 23 | const defaultTTL = 1000 * 60 * 60; 24 | 25 | describe("RecentSearches", () => { 26 | [memoryStorageEnvironment /*localStorageEnvironment*/].map(environment => { 27 | describe(environment.label, () => { 28 | beforeEach(() => { 29 | environment.before(); 30 | }); 31 | 32 | afterEach(() => { 33 | environment.after(); 34 | }); 35 | 36 | describe("setRecentSearch", () => { 37 | it("saves to storage", () => { 38 | const searches = new RecentSearches(); 39 | 40 | const spy = jest.spyOn((searches as any).STORAGE, "setItem"); 41 | searches.setRecentSearch("test", { se: "test" }); 42 | expect(spy).toHaveBeenCalledTimes(1); 43 | }); 44 | 45 | it("protects falsey queries", () => { 46 | const searches = new RecentSearches(); 47 | expect(searches.setRecentSearch(undefined as any, {})).toEqual([]); 48 | expect(searches.setRecentSearch("", {})).toEqual([]); 49 | expect(searches.setRecentSearch(0 as any, {})).not.toEqual([]); 50 | }); 51 | 52 | it("does not exceed limit", () => { 53 | const limit = 5; 54 | const searches = new RecentSearches({ limit }); 55 | (searches as any).initializeStorageData(); 56 | const newSearches = new Array(limit + 10).fill("query"); 57 | 58 | newSearches.forEach(search => { 59 | expect(searches.setRecentSearch(search).length).toBeLessThanOrEqual( 60 | limit 61 | ); 62 | }); 63 | 64 | expect( 65 | (searches as any).RECENT_SEARCHES.some( 66 | (search: any) => typeof search.timestamp !== "number" 67 | ) 68 | ).toBe(false); 69 | }); 70 | 71 | it("saves additional data", () => { 72 | const searches = new RecentSearches({ ttl: defaultTTL }); 73 | 74 | expect( 75 | searches.setRecentSearch("query", { data: "something" })[0].data 76 | ).toEqual({ data: "something" }); 77 | expect(searches.getRecentSearches()[0].data).toEqual({ 78 | data: "something" 79 | }); 80 | }); 81 | 82 | it("appends new queries to start", () => { 83 | const searches = new RecentSearches({ ttl: defaultTTL }); 84 | (searches as any).initializeStorageData(); 85 | const newSearches = ["query", "newQuery"]; 86 | 87 | newSearches.forEach(search => { 88 | searches.setRecentSearch(search); 89 | }); 90 | 91 | expect((searches as any).RECENT_SEARCHES[0].query).toBe( 92 | newSearches[1] 93 | ); 94 | expect((searches as any).RECENT_SEARCHES[1].query).toBe( 95 | newSearches[0] 96 | ); 97 | }); 98 | 99 | it("handles duplicates", () => { 100 | const data = [ 101 | { 102 | query: "new", 103 | timestamp: new Date().getTime() - 1000 * 60 * 15 104 | }, 105 | { 106 | query: "old", 107 | timestamp: new Date().getTime() - 1000 * 60 * 60 * 20 108 | }, 109 | { 110 | query: "new_2", 111 | timestamp: new Date().getTime() - 1000 * 60 * 60 * 30 112 | } 113 | ]; 114 | 115 | const searches = new RecentSearches({ namespace: "CUSTOM" }); 116 | (searches as any).STORAGE.setItem(data); 117 | (searches as any).initializeStorageData(); 118 | 119 | searches.setRecentSearch("old"); 120 | expect(searches.getRecentSearches().length).toBe(2); 121 | }); 122 | }); 123 | 124 | describe("initializeStorageData", () => { 125 | it("filters expired searches", () => { 126 | const searches = new RecentSearches({ 127 | limit: 5, 128 | namespace: "CUSTOM", 129 | ttl: 1000 * 60 * 60 130 | }); 131 | 132 | (searches as any).initializeStorageData(); 133 | 134 | const storedData = [ 135 | { 136 | query: "new", 137 | timestamp: new Date().getTime() - 1000 * 60 * 15 138 | }, 139 | { 140 | query: "old", 141 | timestamp: new Date().getTime() - 1000 * 60 * 60 * 2 142 | } 143 | ]; 144 | (searches as any).STORAGE.setItem(storedData); 145 | expect((searches as any).initializeStorageData()).toEqual([ 146 | storedData[0] 147 | ]); 148 | }); 149 | 150 | it("respects limits", () => { 151 | const searches = new RecentSearches({ 152 | limit: 2, 153 | namespace: "CUSTOM", 154 | ttl: 1000 * 60 * 60 155 | }); 156 | (searches as any).initializeStorageData(); 157 | 158 | const storedData = [ 159 | { 160 | query: "new", 161 | timestamp: new Date().getTime() - 1000 * 60 * 15 162 | }, 163 | { 164 | query: "new_2", 165 | timestamp: new Date().getTime() - 1000 * 60 * 15 166 | }, 167 | { 168 | query: "new_3", 169 | timestamp: new Date().getTime() - 1000 * 60 * 15 170 | }, 171 | { 172 | query: "old", 173 | timestamp: new Date().getTime() - 1000 * 60 * 60 * 2 174 | } 175 | ]; 176 | (searches as any).STORAGE.setItem(storedData); 177 | expect((searches as any).initializeStorageData()).toEqual( 178 | storedData.slice(0, 2) 179 | ); 180 | }); 181 | }); 182 | 183 | describe("getRecentSearches", () => { 184 | const storedData = [ 185 | { 186 | query: "some_new", 187 | data: undefined, 188 | timestamp: new Date().getTime() - 1000 * 60 * 15 189 | }, 190 | { 191 | query: "new", 192 | data: undefined, 193 | timestamp: new Date().getTime() - 1000 * 60 * 15 194 | }, 195 | { 196 | query: "other", 197 | data: undefined, 198 | timestamp: new Date().getTime() - 1000 * 60 * 15 199 | }, 200 | { 201 | query: "old", 202 | data: undefined, 203 | timestamp: new Date().getTime() - 1000 * 60 * 60 * 2 204 | } 205 | ]; 206 | 207 | const searches = new RecentSearches({ 208 | namespace: "CUSTOM", 209 | ttl: defaultTTL 210 | }); 211 | 212 | (searches as any).STORAGE.setItem(storedData); 213 | (searches as any).initializeStorageData(); 214 | 215 | it("returns all searches when no query is sent", () => { 216 | expect(searches.getRecentSearches()).toEqual(storedData.slice(0, 3)); 217 | }); 218 | 219 | it("returns all searches when no query is sent ranked by indexOf", () => { 220 | expect(searches.getRecentSearches("ne")).toEqual([ 221 | storedData[1], 222 | storedData[0] 223 | ]); 224 | }); 225 | 226 | describe("rank_by", () => { 227 | const storedData = [ 228 | { 229 | query: "some_new", 230 | timestamp: new Date().getTime() - 1000 * 60 * 10 231 | }, 232 | { query: "new", timestamp: new Date().getTime() - 1000 * 60 * 5 }, 233 | { 234 | query: "other", 235 | timestamp: new Date().getTime() - 1000 * 60 * 2 236 | }, 237 | { 238 | query: "old", 239 | timestamp: new Date().getTime() - 1000 * 60 * 60 * 2 240 | } 241 | ]; 242 | 243 | it("TIME", () => { 244 | const searches = new RecentSearches({ 245 | ttl: defaultTTL, 246 | namespace: "CUSTOM", 247 | ranking: "TIME" 248 | }); 249 | 250 | (searches as any).STORAGE.setItem(storedData); 251 | (searches as any).initializeStorageData(); 252 | 253 | expect(searches.getRecentSearches("ne")).toEqual([ 254 | storedData[2], 255 | storedData[1], 256 | storedData[0] 257 | ]); 258 | }); 259 | 260 | it("PROXIMITY", () => { 261 | const searches = new RecentSearches({ 262 | ttl: defaultTTL, 263 | namespace: "CUSTOM", 264 | ranking: "PROXIMITY" 265 | }); 266 | 267 | (searches as any).STORAGE.setItem(storedData); 268 | (searches as any).initializeStorageData(); 269 | 270 | expect(searches.getRecentSearches("ne")).toEqual([ 271 | storedData[1], 272 | storedData[0] 273 | ]); 274 | }); 275 | 276 | it("PROXIMITY_AND_TIME", () => { 277 | const storedData = [ 278 | { 279 | query: "___query", 280 | timestamp: new Date().getTime() - 1000 * 60 * 1 281 | }, 282 | { 283 | query: "_t_query", 284 | timestamp: new Date().getTime() - 1000 * 60 * 30 285 | }, 286 | { 287 | query: "query", 288 | timestamp: new Date().getTime() - 1000 * 60 * 55 289 | }, 290 | { 291 | query: "__query", 292 | timestamp: new Date().getTime() - 1000 * 60 * 30 293 | } 294 | ]; 295 | 296 | const searches = new RecentSearches({ 297 | namespace: "CUSTOM", 298 | ranking: "PROXIMITY_AND_TIME", 299 | ttl: 1000 * 60 * 60 300 | }); 301 | 302 | (searches as any).STORAGE.setItem(storedData); 303 | (searches as any).initializeStorageData(); 304 | 305 | const results = searches 306 | .getRecentSearches("query") 307 | .map(q => q.query); 308 | 309 | expect(results).toEqual([ 310 | "query", 311 | "___query", 312 | "__query", 313 | "_t_query" 314 | ]); 315 | }); 316 | }); 317 | }); 318 | }); 319 | }); 320 | }); 321 | -------------------------------------------------------------------------------- /docs/interfaces/_safelocalstorage_.safelocalstorageconfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SafeLocalStorageConfig | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Interface SafeLocalStorageConfig<T>

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Type parameters

74 |
    75 |
  • 76 |

    T

    77 |
  • 78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | SafeLocalStorageConfig 85 |
  • 86 |
87 |
88 |
89 |

Index

90 |
91 |
92 |
93 |

Properties

94 | 99 |
100 |
101 |
102 |
103 |
104 |

Properties

105 |
106 | 107 |

defaultValue

108 |
defaultValue: T
109 | 114 |
115 |
116 | 117 |

Optional key

118 |
key: undefined | string
119 | 124 |
125 |
126 | 127 |

Optional limit

128 |
limit: undefined | number
129 | 134 |
135 |
136 |
137 | 204 |
205 |
206 |
207 |
208 |

Legend

209 |
210 |
    211 |
  • Module
  • 212 |
  • Object literal
  • 213 |
  • Variable
  • 214 |
  • Function
  • 215 |
  • Function with type parameter
  • 216 |
  • Index signature
  • 217 |
  • Type alias
  • 218 |
219 |
    220 |
  • Enumeration
  • 221 |
  • Enumeration member
  • 222 |
  • Property
  • 223 |
  • Method
  • 224 |
225 |
    226 |
  • Interface
  • 227 |
  • Interface with type parameter
  • 228 |
  • Constructor
  • 229 |
  • Property
  • 230 |
  • Method
  • 231 |
  • Index signature
  • 232 |
233 |
    234 |
  • Class
  • 235 |
  • Class with type parameter
  • 236 |
  • Constructor
  • 237 |
  • Property
  • 238 |
  • Method
  • 239 |
  • Accessor
  • 240 |
  • Index signature
  • 241 |
242 |
    243 |
  • Inherited constructor
  • 244 |
  • Inherited property
  • 245 |
  • Inherited method
  • 246 |
  • Inherited accessor
  • 247 |
248 |
    249 |
  • Protected property
  • 250 |
  • Protected method
  • 251 |
  • Protected accessor
  • 252 |
253 |
    254 |
  • Private property
  • 255 |
  • Private method
  • 256 |
  • Private accessor
  • 257 |
258 |
    259 |
  • Static property
  • 260 |
  • Static method
  • 261 |
262 |
263 |
264 |
265 |
266 |

Generated using TypeDoc

267 |
268 |
269 | 270 | 271 | 272 | -------------------------------------------------------------------------------- /docs/assets/js/search.js: -------------------------------------------------------------------------------- 1 | var typedoc = typedoc || {}; 2 | typedoc.search = typedoc.search || {}; 3 | typedoc.search.data = {"kinds":{"1":"External module","32":"Variable","64":"Function","128":"Class","256":"Interface","512":"Constructor","1024":"Property","2048":"Method","65536":"Type literal","2097152":"Object literal","4194304":"Type alias"},"rows":[{"id":0,"kind":1,"name":"\"SafeLocalStorage\"","url":"modules/_safelocalstorage_.html","classes":"tsd-kind-external-module"},{"id":1,"kind":256,"name":"SafeLocalStorageConfig","url":"interfaces/_safelocalstorage_.safelocalstorageconfig.html","classes":"tsd-kind-interface tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"SafeLocalStorage\""},{"id":2,"kind":1024,"name":"defaultValue","url":"interfaces/_safelocalstorage_.safelocalstorageconfig.html#defaultvalue","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"SafeLocalStorage\".SafeLocalStorageConfig"},{"id":3,"kind":1024,"name":"key","url":"interfaces/_safelocalstorage_.safelocalstorageconfig.html#key","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"SafeLocalStorage\".SafeLocalStorageConfig"},{"id":4,"kind":1024,"name":"limit","url":"interfaces/_safelocalstorage_.safelocalstorageconfig.html#limit","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"SafeLocalStorage\".SafeLocalStorageConfig"},{"id":5,"kind":256,"name":"ISafeLocalStorage","url":"interfaces/_safelocalstorage_.isafelocalstorage.html","classes":"tsd-kind-interface tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"SafeLocalStorage\""},{"id":6,"kind":1024,"name":"getItem","url":"interfaces/_safelocalstorage_.isafelocalstorage.html#getitem","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"SafeLocalStorage\".ISafeLocalStorage"},{"id":7,"kind":65536,"name":"__type","url":"interfaces/_safelocalstorage_.isafelocalstorage.html#getitem.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property tsd-is-not-exported","parent":"\"SafeLocalStorage\".ISafeLocalStorage.getItem"},{"id":8,"kind":1024,"name":"setItem","url":"interfaces/_safelocalstorage_.isafelocalstorage.html#setitem","classes":"tsd-kind-property tsd-parent-kind-interface","parent":"\"SafeLocalStorage\".ISafeLocalStorage"},{"id":9,"kind":65536,"name":"__type","url":"interfaces/_safelocalstorage_.isafelocalstorage.html#setitem.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-property tsd-is-not-exported","parent":"\"SafeLocalStorage\".ISafeLocalStorage.setItem"},{"id":10,"kind":128,"name":"SafeLocalStorage","url":"classes/_safelocalstorage_.safelocalstorage.html","classes":"tsd-kind-class tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"SafeLocalStorage\""},{"id":11,"kind":1024,"name":"KEY","url":"classes/_safelocalstorage_.safelocalstorage.html#key","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"SafeLocalStorage\".SafeLocalStorage"},{"id":12,"kind":1024,"name":"DEFAULT_VALUE","url":"classes/_safelocalstorage_.safelocalstorage.html#default_value","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"SafeLocalStorage\".SafeLocalStorage"},{"id":13,"kind":512,"name":"constructor","url":"classes/_safelocalstorage_.safelocalstorage.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"SafeLocalStorage\".SafeLocalStorage"},{"id":14,"kind":2048,"name":"getItem","url":"classes/_safelocalstorage_.safelocalstorage.html#getitem","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SafeLocalStorage\".SafeLocalStorage"},{"id":15,"kind":2048,"name":"setItem","url":"classes/_safelocalstorage_.safelocalstorage.html#setitem","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"SafeLocalStorage\".SafeLocalStorage"},{"id":16,"kind":32,"name":"DEFAULT_STORAGE_KEY","url":"modules/_safelocalstorage_.html#default_storage_key","classes":"tsd-kind-variable tsd-parent-kind-external-module","parent":"\"SafeLocalStorage\""},{"id":17,"kind":64,"name":"isLocalStorageSupported","url":"modules/_safelocalstorage_.html#islocalstoragesupported","classes":"tsd-kind-function tsd-parent-kind-external-module","parent":"\"SafeLocalStorage\""},{"id":18,"kind":64,"name":"safeDataParse","url":"modules/_safelocalstorage_.html#safedataparse","classes":"tsd-kind-function tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"SafeLocalStorage\""},{"id":19,"kind":64,"name":"NewSafeLocalStorage","url":"modules/_safelocalstorage_.html#newsafelocalstorage","classes":"tsd-kind-function tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"SafeLocalStorage\""},{"id":20,"kind":1,"name":"\"MemoryStorage\"","url":"modules/_memorystorage_.html","classes":"tsd-kind-external-module"},{"id":21,"kind":256,"name":"IMemoryStorage","url":"interfaces/_memorystorage_.imemorystorage.html","classes":"tsd-kind-interface tsd-parent-kind-external-module tsd-has-type-parameter tsd-is-not-exported","parent":"\"MemoryStorage\""},{"id":22,"kind":1024,"name":"DATA","url":"interfaces/_memorystorage_.imemorystorage.html#data","classes":"tsd-kind-property tsd-parent-kind-interface tsd-is-not-exported","parent":"\"MemoryStorage\".IMemoryStorage"},{"id":23,"kind":65536,"name":"__type","url":"interfaces/_memorystorage_.imemorystorage.html#data.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property tsd-is-not-exported","parent":"\"MemoryStorage\".IMemoryStorage.DATA"},{"id":24,"kind":1024,"name":"getItem","url":"interfaces/_memorystorage_.imemorystorage.html#getitem","classes":"tsd-kind-property tsd-parent-kind-interface tsd-is-inherited tsd-is-not-exported","parent":"\"MemoryStorage\".IMemoryStorage"},{"id":25,"kind":65536,"name":"__type","url":"interfaces/_memorystorage_.imemorystorage.html#getitem.__type-1","classes":"tsd-kind-type-literal tsd-parent-kind-property tsd-is-not-exported","parent":"\"MemoryStorage\".IMemoryStorage.getItem"},{"id":26,"kind":1024,"name":"setItem","url":"interfaces/_memorystorage_.imemorystorage.html#setitem","classes":"tsd-kind-property tsd-parent-kind-interface tsd-is-inherited tsd-is-not-exported","parent":"\"MemoryStorage\".IMemoryStorage"},{"id":27,"kind":65536,"name":"__type","url":"interfaces/_memorystorage_.imemorystorage.html#setitem.__type-2","classes":"tsd-kind-type-literal tsd-parent-kind-property tsd-is-not-exported","parent":"\"MemoryStorage\".IMemoryStorage.setItem"},{"id":28,"kind":128,"name":"MemoryStorage","url":"classes/_memorystorage_.memorystorage.html","classes":"tsd-kind-class tsd-parent-kind-external-module tsd-has-type-parameter","parent":"\"MemoryStorage\""},{"id":29,"kind":1024,"name":"DATA","url":"classes/_memorystorage_.memorystorage.html#data","classes":"tsd-kind-property tsd-parent-kind-class","parent":"\"MemoryStorage\".MemoryStorage"},{"id":30,"kind":65536,"name":"__type","url":"classes/_memorystorage_.memorystorage.html#data.__type","classes":"tsd-kind-type-literal tsd-parent-kind-property","parent":"\"MemoryStorage\".MemoryStorage.DATA"},{"id":31,"kind":1024,"name":"KEY","url":"classes/_memorystorage_.memorystorage.html#key","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"MemoryStorage\".MemoryStorage"},{"id":32,"kind":1024,"name":"DEFAULT_VALUE","url":"classes/_memorystorage_.memorystorage.html#default_value","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"MemoryStorage\".MemoryStorage"},{"id":33,"kind":512,"name":"constructor","url":"classes/_memorystorage_.memorystorage.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"MemoryStorage\".MemoryStorage"},{"id":34,"kind":2048,"name":"getItem","url":"classes/_memorystorage_.memorystorage.html#getitem","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MemoryStorage\".MemoryStorage"},{"id":35,"kind":2048,"name":"setItem","url":"classes/_memorystorage_.memorystorage.html#setitem","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"MemoryStorage\".MemoryStorage"},{"id":36,"kind":1,"name":"\"__tests__/MemoryStorage.test\"","url":"modules/___tests___memorystorage_test_.html","classes":"tsd-kind-external-module"},{"id":37,"kind":1,"name":"\"index\"","url":"modules/_index_.html","classes":"tsd-kind-external-module"},{"id":38,"kind":256,"name":"RecentSearchesConfig","url":"interfaces/_index_.recentsearchesconfig.html","classes":"tsd-kind-interface tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"index\""},{"id":39,"kind":1024,"name":"ttl","url":"interfaces/_index_.recentsearchesconfig.html#ttl","classes":"tsd-kind-property tsd-parent-kind-interface tsd-is-not-exported","parent":"\"index\".RecentSearchesConfig"},{"id":40,"kind":1024,"name":"limit","url":"interfaces/_index_.recentsearchesconfig.html#limit","classes":"tsd-kind-property tsd-parent-kind-interface tsd-is-not-exported","parent":"\"index\".RecentSearchesConfig"},{"id":41,"kind":1024,"name":"namespace","url":"interfaces/_index_.recentsearchesconfig.html#namespace","classes":"tsd-kind-property tsd-parent-kind-interface tsd-is-not-exported","parent":"\"index\".RecentSearchesConfig"},{"id":42,"kind":1024,"name":"rankBy","url":"interfaces/_index_.recentsearchesconfig.html#rankby","classes":"tsd-kind-property tsd-parent-kind-interface tsd-is-not-exported","parent":"\"index\".RecentSearchesConfig"},{"id":43,"kind":128,"name":"RecentSearches","url":"classes/_index_.recentsearches.html","classes":"tsd-kind-class tsd-parent-kind-external-module","parent":"\"index\""},{"id":44,"kind":1024,"name":"TTL","url":"classes/_index_.recentsearches.html#ttl","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":45,"kind":1024,"name":"LIMIT","url":"classes/_index_.recentsearches.html#limit","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":46,"kind":1024,"name":"STORAGE","url":"classes/_index_.recentsearches.html#storage","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":47,"kind":1024,"name":"RANK_BY","url":"classes/_index_.recentsearches.html#rank_by","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":48,"kind":1024,"name":"RECENT_SEARCHES","url":"classes/_index_.recentsearches.html#recent_searches","classes":"tsd-kind-property tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":49,"kind":512,"name":"constructor","url":"classes/_index_.recentsearches.html#constructor","classes":"tsd-kind-constructor tsd-parent-kind-class","parent":"\"index\".RecentSearches"},{"id":50,"kind":2048,"name":"computeMatchScore","url":"classes/_index_.recentsearches.html#computematchscore","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":51,"kind":2048,"name":"filterScoredResults","url":"classes/_index_.recentsearches.html#filterscoredresults","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":52,"kind":2048,"name":"sortScoredResults","url":"classes/_index_.recentsearches.html#sortscoredresults","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":53,"kind":2048,"name":"initializeStorageData","url":"classes/_index_.recentsearches.html#initializestoragedata","classes":"tsd-kind-method tsd-parent-kind-class tsd-is-private","parent":"\"index\".RecentSearches"},{"id":54,"kind":2048,"name":"getRecentSearches","url":"classes/_index_.recentsearches.html#getrecentsearches","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"index\".RecentSearches"},{"id":55,"kind":2048,"name":"setRecentSearch","url":"classes/_index_.recentsearches.html#setrecentsearch","classes":"tsd-kind-method tsd-parent-kind-class","parent":"\"index\".RecentSearches"},{"id":56,"kind":4194304,"name":"Search","url":"modules/_index_.html#search","classes":"tsd-kind-type-alias tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"index\""},{"id":57,"kind":65536,"name":"__type","url":"modules/_index_.html#search.__type","classes":"tsd-kind-type-literal tsd-parent-kind-type-alias tsd-is-not-exported","parent":"\"index\".Search"},{"id":58,"kind":32,"name":"query","url":"modules/_index_.html#search.__type.query","classes":"tsd-kind-variable tsd-parent-kind-type-literal tsd-is-not-exported","parent":"\"index\".Search.__type"},{"id":59,"kind":32,"name":"timestamp","url":"modules/_index_.html#search.__type.timestamp","classes":"tsd-kind-variable tsd-parent-kind-type-literal tsd-is-not-exported","parent":"\"index\".Search.__type"},{"id":60,"kind":32,"name":"meta","url":"modules/_index_.html#search.__type.meta","classes":"tsd-kind-variable tsd-parent-kind-type-literal tsd-is-not-exported","parent":"\"index\".Search.__type"},{"id":61,"kind":4194304,"name":"ScoredSearch","url":"modules/_index_.html#scoredsearch","classes":"tsd-kind-type-alias tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"index\""},{"id":62,"kind":64,"name":"isExpired","url":"modules/_index_.html#isexpired","classes":"tsd-kind-function tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"index\""},{"id":63,"kind":4194304,"name":"RecentSearchesStorage","url":"modules/_index_.html#recentsearchesstorage","classes":"tsd-kind-type-alias tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"index\""},{"id":64,"kind":1,"name":"\"__tests__/RecentSearches.test\"","url":"modules/___tests___recentsearches_test_.html","classes":"tsd-kind-external-module"},{"id":65,"kind":2097152,"name":"memoryStorageEnvironment","url":"modules/___tests___recentsearches_test_.html#memorystorageenvironment","classes":"tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\""},{"id":66,"kind":32,"name":"label","url":"modules/___tests___recentsearches_test_.html#memorystorageenvironment.label-1","classes":"tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\".memoryStorageEnvironment"},{"id":67,"kind":64,"name":"before","url":"modules/___tests___recentsearches_test_.html#memorystorageenvironment.before-1","classes":"tsd-kind-function tsd-parent-kind-object-literal tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\".memoryStorageEnvironment"},{"id":68,"kind":64,"name":"after","url":"modules/___tests___recentsearches_test_.html#memorystorageenvironment.after-1","classes":"tsd-kind-function tsd-parent-kind-object-literal tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\".memoryStorageEnvironment"},{"id":69,"kind":2097152,"name":"localStorageEnvironment","url":"modules/___tests___recentsearches_test_.html#localstorageenvironment","classes":"tsd-kind-object-literal tsd-parent-kind-external-module tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\""},{"id":70,"kind":32,"name":"label","url":"modules/___tests___recentsearches_test_.html#localstorageenvironment.label","classes":"tsd-kind-variable tsd-parent-kind-object-literal tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\".localStorageEnvironment"},{"id":71,"kind":64,"name":"before","url":"modules/___tests___recentsearches_test_.html#localstorageenvironment.before","classes":"tsd-kind-function tsd-parent-kind-object-literal tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\".localStorageEnvironment"},{"id":72,"kind":64,"name":"after","url":"modules/___tests___recentsearches_test_.html#localstorageenvironment.after","classes":"tsd-kind-function tsd-parent-kind-object-literal tsd-is-not-exported","parent":"\"__tests__/RecentSearches.test\".localStorageEnvironment"},{"id":73,"kind":1,"name":"\"__tests__/SafeLocalStorage.test\"","url":"modules/___tests___safelocalstorage_test_.html","classes":"tsd-kind-external-module"}]}; -------------------------------------------------------------------------------- /docs/interfaces/_index_.recentsearchesconfig.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | RecentSearchesConfig | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Interface RecentSearchesConfig

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Hierarchy

74 |
    75 |
  • 76 | RecentSearchesConfig 77 |
  • 78 |
79 |
80 |
81 |

Index

82 |
83 |
84 |
85 |

Properties

86 | 92 |
93 |
94 |
95 |
96 |
97 |

Properties

98 |
99 | 100 |

Optional limit

101 |
limit: undefined | number
102 | 107 |
108 |
109 | 110 |

Optional namespace

111 |
namespace: undefined | string
112 | 117 |
118 |
119 | 120 |

Optional rankBy

121 |
rankBy: "PROXIMITY" | "TIME" | "PROXIMITY_AND_TIME"
122 | 127 |
128 |
129 | 130 |

Optional ttl

131 |
ttl: undefined | number
132 | 137 |
138 |
139 |
140 | 207 |
208 |
209 |
210 |
211 |

Legend

212 |
213 |
    214 |
  • Module
  • 215 |
  • Object literal
  • 216 |
  • Variable
  • 217 |
  • Function
  • 218 |
  • Function with type parameter
  • 219 |
  • Index signature
  • 220 |
  • Type alias
  • 221 |
222 |
    223 |
  • Enumeration
  • 224 |
  • Enumeration member
  • 225 |
  • Property
  • 226 |
  • Method
  • 227 |
228 |
    229 |
  • Interface
  • 230 |
  • Interface with type parameter
  • 231 |
  • Constructor
  • 232 |
  • Property
  • 233 |
  • Method
  • 234 |
  • Index signature
  • 235 |
236 |
    237 |
  • Class
  • 238 |
  • Class with type parameter
  • 239 |
  • Constructor
  • 240 |
  • Property
  • 241 |
  • Method
  • 242 |
  • Accessor
  • 243 |
  • Index signature
  • 244 |
245 |
    246 |
  • Inherited constructor
  • 247 |
  • Inherited property
  • 248 |
  • Inherited method
  • 249 |
  • Inherited accessor
  • 250 |
251 |
    252 |
  • Protected property
  • 253 |
  • Protected method
  • 254 |
  • Protected accessor
  • 255 |
256 |
    257 |
  • Private property
  • 258 |
  • Private method
  • 259 |
  • Private accessor
  • 260 |
261 |
    262 |
  • Static property
  • 263 |
  • Static method
  • 264 |
265 |
266 |
267 |
268 |
269 |

Generated using TypeDoc

270 |
271 |
272 | 273 | 274 | 275 | -------------------------------------------------------------------------------- /docs/interfaces/_safelocalstorage_.isafelocalstorage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | ISafeLocalStorage | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Interface ISafeLocalStorage<T>

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Type parameters

74 |
    75 |
  • 76 |

    T

    77 |
  • 78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | ISafeLocalStorage 85 | 90 |
  • 91 |
92 |
93 |
94 |

Implemented by

95 | 98 |
99 |
100 |

Index

101 |
102 |
103 |
104 |

Properties

105 | 109 |
110 |
111 |
112 |
113 |
114 |

Properties

115 |
116 | 117 |

getItem

118 |
getItem: function
119 | 124 |
125 |

Type declaration

126 |
    127 |
  • 128 |
      129 |
    • (): T
    • 130 |
    131 |
      132 |
    • 133 |

      Returns T

      134 |
    • 135 |
    136 |
  • 137 |
138 |
139 |
140 |
141 | 142 |

setItem

143 |
setItem: function
144 | 149 |
150 |

Type declaration

151 |
    152 |
  • 153 |
      154 |
    • (item: T): boolean
    • 155 |
    156 |
      157 |
    • 158 |

      Parameters

      159 |
        160 |
      • 161 |
        item: T
        162 |
      • 163 |
      164 |

      Returns boolean

      165 |
    • 166 |
    167 |
  • 168 |
169 |
170 |
171 |
172 |
173 | 237 |
238 |
239 |
240 |
241 |

Legend

242 |
243 |
    244 |
  • Module
  • 245 |
  • Object literal
  • 246 |
  • Variable
  • 247 |
  • Function
  • 248 |
  • Function with type parameter
  • 249 |
  • Index signature
  • 250 |
  • Type alias
  • 251 |
252 |
    253 |
  • Enumeration
  • 254 |
  • Enumeration member
  • 255 |
  • Property
  • 256 |
  • Method
  • 257 |
258 |
    259 |
  • Interface
  • 260 |
  • Interface with type parameter
  • 261 |
  • Constructor
  • 262 |
  • Property
  • 263 |
  • Method
  • 264 |
  • Index signature
  • 265 |
266 |
    267 |
  • Class
  • 268 |
  • Class with type parameter
  • 269 |
  • Constructor
  • 270 |
  • Property
  • 271 |
  • Method
  • 272 |
  • Accessor
  • 273 |
  • Index signature
  • 274 |
275 |
    276 |
  • Inherited constructor
  • 277 |
  • Inherited property
  • 278 |
  • Inherited method
  • 279 |
  • Inherited accessor
  • 280 |
281 |
    282 |
  • Protected property
  • 283 |
  • Protected method
  • 284 |
  • Protected accessor
  • 285 |
286 |
    287 |
  • Private property
  • 288 |
  • Private method
  • 289 |
  • Private accessor
  • 290 |
291 |
    292 |
  • Static property
  • 293 |
  • Static method
  • 294 |
295 |
296 |
297 |
298 |
299 |

Generated using TypeDoc

300 |
301 |
302 | 303 | 304 | 305 | -------------------------------------------------------------------------------- /docs/interfaces/_memorystorage_.imemorystorage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | IMemoryStorage | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Interface IMemoryStorage<T>

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Type parameters

74 |
    75 |
  • 76 |

    T

    77 |
  • 78 |
79 |
80 |
81 |

Hierarchy

82 | 92 |
93 |
94 |

Implemented by

95 | 98 |
99 |
100 |

Index

101 |
102 |
103 |
104 |

Properties

105 | 110 |
111 |
112 |
113 |
114 |
115 |

Properties

116 |
117 | 118 |

DATA

119 |
DATA: object
120 | 125 |
126 |

Type declaration

127 |
    128 |
  • 129 |
    [key: string]: T
    130 |
  • 131 |
132 |
133 |
134 |
135 | 136 |

getItem

137 |
getItem: function
138 | 144 |
145 |

Type declaration

146 |
    147 |
  • 148 |
      149 |
    • (): T
    • 150 |
    151 |
      152 |
    • 153 |

      Returns T

      154 |
    • 155 |
    156 |
  • 157 |
158 |
159 |
160 |
161 | 162 |

setItem

163 |
setItem: function
164 | 170 |
171 |

Type declaration

172 |
    173 |
  • 174 |
      175 |
    • (item: T): boolean
    • 176 |
    177 |
      178 |
    • 179 |

      Parameters

      180 |
        181 |
      • 182 |
        item: T
        183 |
      • 184 |
      185 |

      Returns boolean

      186 |
    • 187 |
    188 |
  • 189 |
190 |
191 |
192 |
193 |
194 | 246 |
247 |
248 |
249 |
250 |

Legend

251 |
252 |
    253 |
  • Module
  • 254 |
  • Object literal
  • 255 |
  • Variable
  • 256 |
  • Function
  • 257 |
  • Function with type parameter
  • 258 |
  • Index signature
  • 259 |
  • Type alias
  • 260 |
261 |
    262 |
  • Enumeration
  • 263 |
  • Enumeration member
  • 264 |
  • Property
  • 265 |
  • Method
  • 266 |
267 |
    268 |
  • Interface
  • 269 |
  • Interface with type parameter
  • 270 |
  • Constructor
  • 271 |
  • Property
  • 272 |
  • Method
  • 273 |
  • Index signature
  • 274 |
275 |
    276 |
  • Class
  • 277 |
  • Class with type parameter
  • 278 |
  • Constructor
  • 279 |
  • Property
  • 280 |
  • Method
  • 281 |
  • Accessor
  • 282 |
  • Index signature
  • 283 |
284 |
    285 |
  • Inherited constructor
  • 286 |
  • Inherited property
  • 287 |
  • Inherited method
  • 288 |
  • Inherited accessor
  • 289 |
290 |
    291 |
  • Protected property
  • 292 |
  • Protected method
  • 293 |
  • Protected accessor
  • 294 |
295 |
    296 |
  • Private property
  • 297 |
  • Private method
  • 298 |
  • Private accessor
  • 299 |
300 |
    301 |
  • Static property
  • 302 |
  • Static method
  • 303 |
304 |
305 |
306 |
307 |
308 |

Generated using TypeDoc

309 |
310 |
311 | 312 | 313 | 314 | -------------------------------------------------------------------------------- /docs/modules/_index_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "index" | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "index"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |

Interfaces

81 | 84 |
85 |
86 |

Type aliases

87 | 92 |
93 |
94 |

Functions

95 | 98 |
99 |
100 |
101 |
102 |
103 |

Type aliases

104 |
105 | 106 |

RecentSearchesStorage

107 |
RecentSearchesStorage: SafeLocalStorage<Search[]> | MemoryStorage<Search[]>
108 | 113 |
114 |
115 | 116 |

ScoredSearch

117 |
ScoredSearch: Search & object
118 | 123 |
124 |
125 | 126 |

Search

127 |
Search: object
128 | 133 |
134 |

Type declaration

135 |
    136 |
  • 137 |
    Optional meta?: undefined | object
    138 |
  • 139 |
  • 140 |
    query: string
    141 |
  • 142 |
  • 143 |
    timestamp: number
    144 |
  • 145 |
146 |
147 |
148 |
149 |
150 |

Functions

151 |
152 | 153 |

Const isExpired

154 |
    155 |
  • isExpired(timestamp: number, currentTimestamp: number, ttl: number): void
  • 156 |
157 |
    158 |
  • 159 | 164 |

    Parameters

    165 |
      166 |
    • 167 |
      timestamp: number
      168 |
    • 169 |
    • 170 |
      currentTimestamp: number
      171 |
    • 172 |
    • 173 |
      ttl: number
      174 |
    • 175 |
    176 |

    Returns void

    177 |
  • 178 |
179 |
180 |
181 |
182 | 231 |
232 |
233 |
234 |
235 |

Legend

236 |
237 |
    238 |
  • Module
  • 239 |
  • Object literal
  • 240 |
  • Variable
  • 241 |
  • Function
  • 242 |
  • Function with type parameter
  • 243 |
  • Index signature
  • 244 |
  • Type alias
  • 245 |
246 |
    247 |
  • Enumeration
  • 248 |
  • Enumeration member
  • 249 |
  • Property
  • 250 |
  • Method
  • 251 |
252 |
    253 |
  • Interface
  • 254 |
  • Interface with type parameter
  • 255 |
  • Constructor
  • 256 |
  • Property
  • 257 |
  • Method
  • 258 |
  • Index signature
  • 259 |
260 |
    261 |
  • Class
  • 262 |
  • Class with type parameter
  • 263 |
  • Constructor
  • 264 |
  • Property
  • 265 |
  • Method
  • 266 |
  • Accessor
  • 267 |
  • Index signature
  • 268 |
269 |
    270 |
  • Inherited constructor
  • 271 |
  • Inherited property
  • 272 |
  • Inherited method
  • 273 |
  • Inherited accessor
  • 274 |
275 |
    276 |
  • Protected property
  • 277 |
  • Protected method
  • 278 |
  • Protected accessor
  • 279 |
280 |
    281 |
  • Private property
  • 282 |
  • Private method
  • 283 |
  • Private accessor
  • 284 |
285 |
    286 |
  • Static property
  • 287 |
  • Static method
  • 288 |
289 |
290 |
291 |
292 |
293 |

Generated using TypeDoc

294 |
295 |
296 | 297 | 298 | 299 | -------------------------------------------------------------------------------- /docs/modules/___tests___recentsearches_test_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "__tests__/RecentSearches.test" | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "__tests__/RecentSearches.test"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Object literals

75 | 79 |
80 |
81 |
82 |
83 |
84 |

Object literals

85 |
86 | 87 |

Const localStorageEnvironment

88 |
localStorageEnvironment: object
89 | 94 |
95 | 96 |

label

97 |
label: string = "LocalStorage"
98 | 103 |
104 |
105 | 106 |

after

107 |
    108 |
  • after(): void
  • 109 |
110 | 120 |
121 |
122 | 123 |

before

124 |
    125 |
  • before(): undefined
  • 126 |
127 | 137 |
138 |
139 |
140 | 141 |

Const memoryStorageEnvironment

142 |
memoryStorageEnvironment: object
143 | 148 |
149 | 150 |

label

151 |
label: string = "MemoryStorage"
152 | 157 |
158 |
159 | 160 |

after

161 |
    162 |
  • after(): undefined
  • 163 |
164 | 174 |
175 |
176 | 177 |

before

178 |
    179 |
  • before(): void
  • 180 |
181 | 191 |
192 |
193 |
194 |
195 | 232 |
233 |
234 |
235 |
236 |

Legend

237 |
238 |
    239 |
  • Module
  • 240 |
  • Object literal
  • 241 |
  • Variable
  • 242 |
  • Function
  • 243 |
  • Function with type parameter
  • 244 |
  • Index signature
  • 245 |
  • Type alias
  • 246 |
247 |
    248 |
  • Enumeration
  • 249 |
  • Enumeration member
  • 250 |
  • Property
  • 251 |
  • Method
  • 252 |
253 |
    254 |
  • Interface
  • 255 |
  • Interface with type parameter
  • 256 |
  • Constructor
  • 257 |
  • Property
  • 258 |
  • Method
  • 259 |
  • Index signature
  • 260 |
261 |
    262 |
  • Class
  • 263 |
  • Class with type parameter
  • 264 |
  • Constructor
  • 265 |
  • Property
  • 266 |
  • Method
  • 267 |
  • Accessor
  • 268 |
  • Index signature
  • 269 |
270 |
    271 |
  • Inherited constructor
  • 272 |
  • Inherited property
  • 273 |
  • Inherited method
  • 274 |
  • Inherited accessor
  • 275 |
276 |
    277 |
  • Protected property
  • 278 |
  • Protected method
  • 279 |
  • Protected accessor
  • 280 |
281 |
    282 |
  • Private property
  • 283 |
  • Private method
  • 284 |
  • Private accessor
  • 285 |
286 |
    287 |
  • Static property
  • 288 |
  • Static method
  • 289 |
290 |
291 |
292 |
293 |
294 |

Generated using TypeDoc

295 |
296 |
297 | 298 | 299 | 300 | -------------------------------------------------------------------------------- /docs/modules/_safelocalstorage_.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | "SafeLocalStorage" | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 62 |

External module "SafeLocalStorage"

63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |

Index

71 |
72 |
73 |
74 |

Classes

75 | 78 |
79 |
80 |

Interfaces

81 | 85 |
86 |
87 |

Variables

88 | 91 |
92 |
93 |

Functions

94 | 99 |
100 |
101 |
102 |
103 |
104 |

Variables

105 |
106 | 107 |

Const DEFAULT_STORAGE_KEY

108 |
DEFAULT_STORAGE_KEY: "__RECENT_SEARCHES__" = "__RECENT_SEARCHES__"
109 | 114 |
115 |
116 |
117 |

Functions

118 |
119 | 120 |

Const NewSafeLocalStorage

121 | 124 | 149 |
150 |
151 | 152 |

Const isLocalStorageSupported

153 |
    154 |
  • isLocalStorageSupported(): boolean
  • 155 |
156 | 166 |
167 |
168 | 169 |

Const safeDataParse

170 |
    171 |
  • safeDataParse<T>(data: string | null, defaultValue: T): T
  • 172 |
173 |
    174 |
  • 175 | 180 |

    Type parameters

    181 |
      182 |
    • 183 |

      T

      184 |
    • 185 |
    186 |

    Parameters

    187 |
      188 |
    • 189 |
      data: string | null
      190 |
    • 191 |
    • 192 |
      defaultValue: T
      193 |
    • 194 |
    195 |

    Returns T

    196 |
  • 197 |
198 |
199 |
200 |
201 | 253 |
254 |
255 |
256 |
257 |

Legend

258 |
259 |
    260 |
  • Module
  • 261 |
  • Object literal
  • 262 |
  • Variable
  • 263 |
  • Function
  • 264 |
  • Function with type parameter
  • 265 |
  • Index signature
  • 266 |
  • Type alias
  • 267 |
268 |
    269 |
  • Enumeration
  • 270 |
  • Enumeration member
  • 271 |
  • Property
  • 272 |
  • Method
  • 273 |
274 |
    275 |
  • Interface
  • 276 |
  • Interface with type parameter
  • 277 |
  • Constructor
  • 278 |
  • Property
  • 279 |
  • Method
  • 280 |
  • Index signature
  • 281 |
282 |
    283 |
  • Class
  • 284 |
  • Class with type parameter
  • 285 |
  • Constructor
  • 286 |
  • Property
  • 287 |
  • Method
  • 288 |
  • Accessor
  • 289 |
  • Index signature
  • 290 |
291 |
    292 |
  • Inherited constructor
  • 293 |
  • Inherited property
  • 294 |
  • Inherited method
  • 295 |
  • Inherited accessor
  • 296 |
297 |
    298 |
  • Protected property
  • 299 |
  • Protected method
  • 300 |
  • Protected accessor
  • 301 |
302 |
    303 |
  • Private property
  • 304 |
  • Private method
  • 305 |
  • Private accessor
  • 306 |
307 |
    308 |
  • Static property
  • 309 |
  • Static method
  • 310 |
311 |
312 |
313 |
314 |
315 |

Generated using TypeDoc

316 |
317 |
318 | 319 | 320 | 321 | -------------------------------------------------------------------------------- /docs/classes/_safelocalstorage_.safelocalstorage.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | SafeLocalStorage | recent-searches 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 27 |
28 |
29 | Options 30 |
31 |
32 | All 33 |
    34 |
  • Public
  • 35 |
  • Public/Protected
  • 36 |
  • All
  • 37 |
38 |
39 | 40 | 41 | 42 | 43 | 44 | 45 |
46 |
47 | Menu 48 |
49 |
50 |
51 |
52 |
53 |
54 | 65 |

Class SafeLocalStorage<T>

66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |

Type parameters

74 |
    75 |
  • 76 |

    T

    77 |
  • 78 |
79 |
80 |
81 |

Hierarchy

82 |
    83 |
  • 84 | SafeLocalStorage 85 |
  • 86 |
87 |
88 |
89 |

Implements

90 | 93 |
94 |
95 |

Index

96 |
97 |
98 |
99 |

Constructors

100 | 103 |
104 |
105 |

Properties

106 | 110 |
111 |
112 |

Methods

113 | 117 |
118 |
119 |
120 |
121 |
122 |

Constructors

123 |
124 | 125 |

constructor

126 | 129 | 145 |
146 |
147 |
148 |

Properties

149 |
150 | 151 |

Private DEFAULT_VALUE

152 |
DEFAULT_VALUE: T
153 | 158 |
159 |
160 | 161 |

Private KEY

162 |
KEY: string
163 | 168 |
169 |
170 |
171 |

Methods

172 |
173 | 174 |

getItem

175 |
    176 |
  • getItem(): T
  • 177 |
178 | 188 |
189 |
190 | 191 |

setItem

192 |
    193 |
  • setItem(items: T): boolean
  • 194 |
195 |
    196 |
  • 197 | 202 |

    Parameters

    203 |
      204 |
    • 205 |
      items: T
      206 |
    • 207 |
    208 |

    Returns boolean

    209 |
  • 210 |
211 |
212 |
213 |
214 | 287 |
288 |
289 |
290 |
291 |

Legend

292 |
293 |
    294 |
  • Module
  • 295 |
  • Object literal
  • 296 |
  • Variable
  • 297 |
  • Function
  • 298 |
  • Function with type parameter
  • 299 |
  • Index signature
  • 300 |
  • Type alias
  • 301 |
302 |
    303 |
  • Enumeration
  • 304 |
  • Enumeration member
  • 305 |
  • Property
  • 306 |
  • Method
  • 307 |
308 |
    309 |
  • Interface
  • 310 |
  • Interface with type parameter
  • 311 |
  • Constructor
  • 312 |
  • Property
  • 313 |
  • Method
  • 314 |
  • Index signature
  • 315 |
316 |
    317 |
  • Class
  • 318 |
  • Class with type parameter
  • 319 |
  • Constructor
  • 320 |
  • Property
  • 321 |
  • Method
  • 322 |
  • Accessor
  • 323 |
  • Index signature
  • 324 |
325 |
    326 |
  • Inherited constructor
  • 327 |
  • Inherited property
  • 328 |
  • Inherited method
  • 329 |
  • Inherited accessor
  • 330 |
331 |
    332 |
  • Protected property
  • 333 |
  • Protected method
  • 334 |
  • Protected accessor
  • 335 |
336 |
    337 |
  • Private property
  • 338 |
  • Private method
  • 339 |
  • Private accessor
  • 340 |
341 |
    342 |
  • Static property
  • 343 |
  • Static method
  • 344 |
345 |
346 |
347 |
348 |
349 |

Generated using TypeDoc

350 |
351 |
352 | 353 | 354 | 355 | --------------------------------------------------------------------------------