diff --git a/index.d.ts b/index.d.ts index 031e44c..c191a6c 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,147 +1,71 @@ -declare module "flexsearch" { - export interface Index { - readonly id: string; - readonly index: string; - readonly length: number; - - init(options?: CreateOptions): this; - info(): { - id: any; - items: any; - cache: any; - matcher: number; - worker: any; - threshold: any; - depth: any; - resolution: any; - contextual: boolean; - }; - add(o: T): this; - add(id: number, o: string): this; - - // Result without pagination -> T[] - search( - query: string, - options: number | SearchOptions, - callback: (results: T[]) => void - ): void; - search(query: string, options?: number | SearchOptions): Promise; - search( - options: SearchOptions & { query: string }, - callback: (results: T[]) => void - ): void; - search(options: SearchOptions & { query: string }): Promise; - - // Result with pagination -> SearchResults - search( - query: string, - options: number | (SearchOptions & { page?: boolean | Cursor }), - callback: (results: SearchResults) => void - ): void; - search( - query: string, - options?: number | (SearchOptions & { page?: boolean | Cursor }) - ): Promise>; - search( - options: SearchOptions & { query: string; page?: boolean | Cursor }, - callback: (results: SearchResults) => void - ): void; - search( - options: SearchOptions & { query: string; page?: boolean | Cursor } - ): Promise>; - - update(id: number, o: T): this; - remove(id: number): this; - clear(): this; - destroy(): this; - addMatcher(matcher: Matcher): this; - - where(whereObj: { [key: string]: string } | ((o: T) => boolean)): T[]; - encode(str: string): string; - export( - callback: (key: string, data: any) => any, - self?: this, - field?: string, - index_doc?: Number, - index?: Number - ): Promise; - import(exported: string): this; - } +interface SearchOptions { + limit?: number; + suggest?: boolean; + where?: { [key: string]: string }; + field?: string | string[]; + bool?: 'and' | 'or' | 'not'; +} - interface SearchOptions { - limit?: number; - suggest?: boolean; - where?: { [key: string]: string }; - field?: string | string[]; - bool?: "and" | "or" | "not"; - //TODO: Sorting - } +interface SearchResults { + page?: string; + next?: string; + result: T[]; +} - interface SearchResults { - page?: Cursor; - next?: Cursor; - result: T[]; - } +type DefaultEncoder = 'icase' | 'simple' | 'advanced' | 'extra' | 'balance'; +type DefaultTokenizer = 'strict' | 'forward' | 'reverse' | 'full'; +type EncoderFunction = (str: string) => string; +type FilterFunction = (str: string) => boolean; +type TokenizerFunction = (str: string) => string[]; - interface Document { - id: string; - field: any; - } +export interface CreateOptions { + async?: boolean; + boost?: any; // TODO: what? + cache?: number | boolean; + charset?: string; + context?: { + bidirectional?: boolean; + depth?: number; + resolution?: any; // TODO: what? + }; + depth?: number | false; + doc?: { id: string; field: any }; + encode?: false | DefaultEncoder | ((input: string | number) => ThisType); + fastupdate?: any; // TODO: what? + filter?: string | false | FilterFunction; + lang?: string; // TODO: define lang + matcher?: any; // TODO: what? + minlength?: number; + optimize?: boolean; + profile?: 'memory' | 'speed' | 'match' | 'score' | 'balance' | 'fast'; + resolution?: number; + rtl?: boolean; + split?: RegExp; + stemmer?: string | false | { [key: string]: string }; + threshold?: number | false; + tokenize?: DefaultTokenizer | TokenizerFunction; + worker?: number | false; +} - export type CreateOptions = { - profile?: IndexProfile; - tokenize?: DefaultTokenizer | TokenizerFn; - split?: RegExp; - encode?: DefaultEncoder | EncoderFn | false; - cache?: boolean | number; - async?: boolean; - worker?: false | number; - depth?: false | number; - threshold?: false | number; - resolution?: number; - stemmer?: Stemmer | string | false; - filter?: FilterFn | string | false; - rtl?: boolean; - doc?: Document; - }; +export default class FlexSearch { + constructor(options?: CreateOptions); - // limit number Sets the limit of results. - // suggest true, false Enables suggestions in results. - // where object Use a where-clause for non-indexed fields. - // field string, Array Sets the document fields which should be searched. When no field is set, all fields will be searched. Custom options per field are also supported. - // bool "and", "or" Sets the used logical operator when searching through multiple fields. - // page true, false, cursor Enables paginated results. + readonly id: string; + readonly index: string; + readonly length: number; - type IndexProfile = - | "memory" - | "speed" - | "match" - | "score" - | "balance" - | "fast"; - type DefaultTokenizer = "strict" | "forward" | "reverse" | "full"; - type TokenizerFn = (str: string) => string[]; - type DefaultEncoder = "icase" | "simple" | "advanced" | "extra" | "balance"; - type EncoderFn = (str: string) => string; - type Stemmer = { [key: string]: string }; - type Matcher = { [key: string]: string }; - type FilterFn = (str: string) => boolean; - type Cursor = string; + static encode(name: string, str: string): string; + static registerLanguage( + lang: string, + options: { + stemmer?: { [key: string]: string }; + filter?: string[]; + } + ): typeof FlexSearch; - export default class FlexSearch { - static create(options?: CreateOptions): Index; - static registerMatcher(matcher: Matcher): typeof FlexSearch; - static registerEncoder(name: string, encoder: EncoderFn): typeof FlexSearch; - static registerLanguage( - lang: string, - options: { stemmer?: Stemmer; filter?: string[] } - ): typeof FlexSearch; - static encode(name: string, str: string): string; - } + add(id: number, content: string): this; + append(id: number, content: string): this; + remove(id: number): this; + search(query: string, limit: number, options: SearchOptions): this; + update(id: number, content: string): this; } - -// FlexSearch.create() -// FlexSearch.registerMatcher({KEY: VALUE}) -// FlexSearch.registerEncoder(name, encoder) -// FlexSearch.registerLanguage(lang, {stemmer:{}, filter:[]}) -// FlexSearch.encode(name, string) diff --git a/package.json b/package.json index 62a73f7..4737272 100644 --- a/package.json +++ b/package.json @@ -44,7 +44,9 @@ "build:module": "npx babel src -d dist/module && exit 0", "build:all": "npm run build && npm run build:light && npm run build:compact && npm run build:es5 && npm run build:debug && npm run build:module", "test": "cd test && npm install && npm run test", - "server": "node task/server" + "server": "node task/server", + "format": "prettier --write src", + "check:style": "prettier --check src" }, "files": [ "dist/**", @@ -56,6 +58,7 @@ "LICENSE" ], "readme": "README.md", + "prettier": "mauss/prettier.json", "devDependencies": { "babel-cli": "^6.26.0", "babel-plugin-minify-constant-folding": "^0.5.0", @@ -75,7 +78,10 @@ "babel-plugin-transform-undefined-to-void": "^6.9.4", "cpx": "^1.5.0", "google-closure-compiler": "^20220905.0.0", + "mauss": "^0.3.3", + "prettier": "^2.7.1", "shx": "^0.3.3", + "typescript": "^4.8.4", "web-servo": "^0.5.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000..4164984 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,1918 @@ +lockfileVersion: 5.4 + +specifiers: + babel-cli: ^6.26.0 + babel-plugin-minify-constant-folding: ^0.5.0 + babel-plugin-minify-dead-code-elimination: ^0.5.1 + babel-plugin-minify-flip-comparisons: ^0.4.3 + babel-plugin-minify-guarded-expressions: ^0.4.4 + babel-plugin-minify-infinity: ^0.4.3 + babel-plugin-minify-mangle-names: ^0.5.0 + babel-plugin-minify-replace: ^0.5.0 + babel-plugin-minify-simplify: ^0.5.1 + babel-plugin-minify-type-constructors: ^0.4.3 + babel-plugin-transform-member-expression-literals: ^6.9.4 + babel-plugin-transform-merge-sibling-variables: ^6.9.4 + babel-plugin-transform-minify-booleans: ^6.9.4 + babel-plugin-transform-property-literals: ^6.9.4 + babel-plugin-transform-simplify-comparison-operators: ^6.9.4 + babel-plugin-transform-undefined-to-void: ^6.9.4 + cpx: ^1.5.0 + google-closure-compiler: ^20220905.0.0 + mauss: ^0.3.3 + prettier: ^2.7.1 + shx: ^0.3.3 + typescript: ^4.8.4 + web-servo: ^0.5.1 + +devDependencies: + babel-cli: 6.26.0 + babel-plugin-minify-constant-folding: 0.5.0 + babel-plugin-minify-dead-code-elimination: 0.5.2 + babel-plugin-minify-flip-comparisons: 0.4.3 + babel-plugin-minify-guarded-expressions: 0.4.4 + babel-plugin-minify-infinity: 0.4.3 + babel-plugin-minify-mangle-names: 0.5.1 + babel-plugin-minify-replace: 0.5.0 + babel-plugin-minify-simplify: 0.5.1 + babel-plugin-minify-type-constructors: 0.4.3 + babel-plugin-transform-member-expression-literals: 6.9.4 + babel-plugin-transform-merge-sibling-variables: 6.9.5 + babel-plugin-transform-minify-booleans: 6.9.4 + babel-plugin-transform-property-literals: 6.9.4 + babel-plugin-transform-simplify-comparison-operators: 6.9.4 + babel-plugin-transform-undefined-to-void: 6.9.4 + cpx: 1.5.0 + google-closure-compiler: 20220905.0.0 + mauss: 0.3.3 + prettier: 2.7.1 + shx: 0.3.4 + typescript: 4.8.4 + web-servo: 0.5.1 + +packages: + + /ansi-regex/2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + dev: true + + /ansi-styles/2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + dev: true + + /ansi-styles/4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: true + + /anymatch/1.3.2: + resolution: {integrity: sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==} + dependencies: + micromatch: 2.3.11 + normalize-path: 2.1.1 + dev: true + + /arr-diff/2.0.0: + resolution: {integrity: sha512-dtXTVMkh6VkEEA7OhXnN1Ecb8aAGFdZ1LFxtOCoqj4qkyOJMt7+qs6Ahdy6p/NQCPYsRSXXivhSB/J5E9jmYKA==} + engines: {node: '>=0.10.0'} + dependencies: + arr-flatten: 1.1.0 + dev: true + + /arr-diff/4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + dev: true + + /arr-flatten/1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + dev: true + + /arr-union/3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + dev: true + + /array-unique/0.2.1: + resolution: {integrity: sha512-G2n5bG5fSUCpnsXz4+8FUkYsGPkNfLn9YvS66U5qbTIXI2Ynnlo4Bi42bWv+omKUCqz+ejzfClwne0alJWJPhg==} + engines: {node: '>=0.10.0'} + dev: true + + /array-unique/0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + dev: true + + /assign-symbols/1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + dev: true + + /async-each/1.0.3: + resolution: {integrity: sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==} + dev: true + + /atob/2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + dev: true + + /babel-cli/6.26.0: + resolution: {integrity: sha512-wau+BDtQfuSBGQ9PzzFL3REvR9Sxnd4LKwtcHAiPjhugA7K/80vpHXafj+O5bAqJOuSefjOx5ZJnNSR2J1Qw6Q==} + hasBin: true + dependencies: + babel-core: 6.26.3 + babel-polyfill: 6.26.0 + babel-register: 6.26.0 + babel-runtime: 6.26.0 + commander: 2.20.3 + convert-source-map: 1.9.0 + fs-readdir-recursive: 1.1.0 + glob: 7.2.3 + lodash: 4.17.21 + output-file-sync: 1.1.2 + path-is-absolute: 1.0.1 + slash: 1.0.0 + source-map: 0.5.7 + v8flags: 2.1.1 + optionalDependencies: + chokidar: 1.7.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-code-frame/6.26.0: + resolution: {integrity: sha512-XqYMR2dfdGMW+hd0IUZ2PwK+fGeFkOxZJ0wY+JaQAHzt1Zx8LcvpiZD2NiGkEG8qx0CfkAOr5xt76d1e8vG90g==} + dependencies: + chalk: 1.1.3 + esutils: 2.0.3 + js-tokens: 3.0.2 + dev: true + + /babel-core/6.26.3: + resolution: {integrity: sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==} + dependencies: + babel-code-frame: 6.26.0 + babel-generator: 6.26.1 + babel-helpers: 6.24.1 + babel-messages: 6.23.0 + babel-register: 6.26.0 + babel-runtime: 6.26.0 + babel-template: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + convert-source-map: 1.9.0 + debug: 2.6.9 + json5: 0.5.1 + lodash: 4.17.21 + minimatch: 3.1.2 + path-is-absolute: 1.0.1 + private: 0.1.8 + slash: 1.0.0 + source-map: 0.5.7 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-generator/6.26.1: + resolution: {integrity: sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==} + dependencies: + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + detect-indent: 4.0.0 + jsesc: 1.3.0 + lodash: 4.17.21 + source-map: 0.5.7 + trim-right: 1.0.1 + dev: true + + /babel-helper-evaluate-path/0.5.0: + resolution: {integrity: sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA==} + dev: true + + /babel-helper-flip-expressions/0.4.3: + resolution: {integrity: sha512-rSrkRW4YQ2ETCWww9gbsWk4N0x1BOtln349Tk0dlCS90oT68WMLyGR7WvaMp3eAnsVrCqdUtC19lo1avyGPejA==} + dev: true + + /babel-helper-is-nodes-equiv/0.0.1: + resolution: {integrity: sha512-ri/nsMFVRqXn7IyT5qW4/hIAGQxuYUFHa3qsxmPtbk6spZQcYlyDogfVpNm2XYOslH/ULS4VEJGUqQX5u7ACQw==} + dev: true + + /babel-helper-is-void-0/0.4.3: + resolution: {integrity: sha512-07rBV0xPRM3TM5NVJEOQEkECX3qnHDjaIbFvWYPv+T1ajpUiVLiqTfC+MmiZxY5KOL/Ec08vJdJD9kZiP9UkUg==} + dev: true + + /babel-helper-mark-eval-scopes/0.4.3: + resolution: {integrity: sha512-+d/mXPP33bhgHkdVOiPkmYoeXJ+rXRWi7OdhwpyseIqOS8CmzHQXHUp/+/Qr8baXsT0kjGpMHHofHs6C3cskdA==} + dev: true + + /babel-helper-remove-or-void/0.4.3: + resolution: {integrity: sha512-eYNceYtcGKpifHDir62gHJadVXdg9fAhuZEXiRQnJJ4Yi4oUTpqpNY//1pM4nVyjjDMPYaC2xSf0I+9IqVzwdA==} + dev: true + + /babel-helper-to-multiple-sequence-expressions/0.5.0: + resolution: {integrity: sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA==} + dev: true + + /babel-helpers/6.24.1: + resolution: {integrity: sha512-n7pFrqQm44TCYvrCDb0MqabAF+JUBq+ijBvNMUxpkLjJaAu32faIexewMumrH5KLLJ1HDyT0PTEqRyAe/GwwuQ==} + dependencies: + babel-runtime: 6.26.0 + babel-template: 6.26.0 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-messages/6.23.0: + resolution: {integrity: sha512-Bl3ZiA+LjqaMtNYopA9TYE9HP1tQ+E5dLxE0XrAzcIJeK2UqF0/EaqXwBn9esd4UmTfEab+P+UYQ1GnioFIb/w==} + dependencies: + babel-runtime: 6.26.0 + dev: true + + /babel-plugin-minify-constant-folding/0.5.0: + resolution: {integrity: sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ==} + dependencies: + babel-helper-evaluate-path: 0.5.0 + dev: true + + /babel-plugin-minify-dead-code-elimination/0.5.2: + resolution: {integrity: sha512-krq9Lwi0QIzyAlcNBXTL4usqUvevB4BzktdEsb8srcXC1AaYqRJiAQw6vdKdJSaXbz6snBvziGr6ch/aoRCfpA==} + dependencies: + babel-helper-evaluate-path: 0.5.0 + babel-helper-mark-eval-scopes: 0.4.3 + babel-helper-remove-or-void: 0.4.3 + lodash: 4.17.21 + dev: true + + /babel-plugin-minify-flip-comparisons/0.4.3: + resolution: {integrity: sha512-8hNwgLVeJzpeLVOVArag2DfTkbKodzOHU7+gAZ8mGBFGPQHK6uXVpg3jh5I/F6gfi5Q5usWU2OKcstn1YbAV7A==} + dependencies: + babel-helper-is-void-0: 0.4.3 + dev: true + + /babel-plugin-minify-guarded-expressions/0.4.4: + resolution: {integrity: sha512-RMv0tM72YuPPfLT9QLr3ix9nwUIq+sHT6z8Iu3sLbqldzC1Dls8DPCywzUIzkTx9Zh1hWX4q/m9BPoPed9GOfA==} + dependencies: + babel-helper-evaluate-path: 0.5.0 + babel-helper-flip-expressions: 0.4.3 + dev: true + + /babel-plugin-minify-infinity/0.4.3: + resolution: {integrity: sha512-X0ictxCk8y+NvIf+bZ1HJPbVZKMlPku3lgYxPmIp62Dp8wdtbMLSekczty3MzvUOlrk5xzWYpBpQprXUjDRyMA==} + dev: true + + /babel-plugin-minify-mangle-names/0.5.1: + resolution: {integrity: sha512-8KMichAOae2FHlipjNDTo2wz97MdEb2Q0jrn4NIRXzHH7SJ3c5TaNNBkeTHbk9WUsMnqpNUx949ugM9NFWewzw==} + dependencies: + babel-helper-mark-eval-scopes: 0.4.3 + dev: true + + /babel-plugin-minify-replace/0.5.0: + resolution: {integrity: sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q==} + dev: true + + /babel-plugin-minify-simplify/0.5.1: + resolution: {integrity: sha512-OSYDSnoCxP2cYDMk9gxNAed6uJDiDz65zgL6h8d3tm8qXIagWGMLWhqysT6DY3Vs7Fgq7YUDcjOomhVUb+xX6A==} + dependencies: + babel-helper-evaluate-path: 0.5.0 + babel-helper-flip-expressions: 0.4.3 + babel-helper-is-nodes-equiv: 0.0.1 + babel-helper-to-multiple-sequence-expressions: 0.5.0 + dev: true + + /babel-plugin-minify-type-constructors/0.4.3: + resolution: {integrity: sha512-4ADB0irJ/6BeXWHubjCJmrPbzhxDgjphBMjIjxCc25n4NGJ00NsYqwYt+F/OvE9RXx8KaSW7cJvp+iZX436tnQ==} + dependencies: + babel-helper-is-void-0: 0.4.3 + dev: true + + /babel-plugin-transform-member-expression-literals/6.9.4: + resolution: {integrity: sha512-Xq9/Rarpj+bjOZSl1nBbZYETsNEDDJSrb6Plb1sS3/36FukWFLLRysgecva5KZECjUJTrJoQqjJgtWToaflk5Q==} + dev: true + + /babel-plugin-transform-merge-sibling-variables/6.9.5: + resolution: {integrity: sha512-xj/KrWi6/uP+DrD844h66Qh2cZN++iugEIgH8QcIxhmZZPNP6VpOE9b4gP2FFW39xDAY43kCmYMM6U0QNKN8fw==} + dev: true + + /babel-plugin-transform-minify-booleans/6.9.4: + resolution: {integrity: sha512-9pW9ePng6DZpzGPalcrULuhSCcauGAbn8AeU3bE34HcDkGm8Ldt0ysjGkyb64f0K3T5ilV4mriayOVv5fg0ASA==} + dev: true + + /babel-plugin-transform-property-literals/6.9.4: + resolution: {integrity: sha512-Pf8JHTjTPxecqVyL6KSwD/hxGpoTZjiEgV7nCx0KFQsJYM0nuuoCajbg09KRmZWeZbJ5NGTySABYv8b/hY1eEA==} + dependencies: + esutils: 2.0.3 + dev: true + + /babel-plugin-transform-simplify-comparison-operators/6.9.4: + resolution: {integrity: sha512-GLInxhGAQWJ9YIdjwF6dAFlmh4U+kN8pL6Big7nkDzHoZcaDQOtBm28atEhQJq6m9GpAovbiGEShKqXv4BSp0A==} + dev: true + + /babel-plugin-transform-undefined-to-void/6.9.4: + resolution: {integrity: sha512-D2UbwxawEY1xVc9svYAUZQM2xarwSNXue2qDIx6CeV2EuMGaes/0su78zlIDIAgE7BvnMw4UpmSo9fDy+znghg==} + dev: true + + /babel-polyfill/6.26.0: + resolution: {integrity: sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==} + dependencies: + babel-runtime: 6.26.0 + core-js: 2.6.12 + regenerator-runtime: 0.10.5 + dev: true + + /babel-register/6.26.0: + resolution: {integrity: sha512-veliHlHX06wjaeY8xNITbveXSiI+ASFnOqvne/LaIJIqOWi2Ogmj91KOugEz/hoh/fwMhXNBJPCv8Xaz5CyM4A==} + dependencies: + babel-core: 6.26.3 + babel-runtime: 6.26.0 + core-js: 2.6.12 + home-or-tmp: 2.0.0 + lodash: 4.17.21 + mkdirp: 0.5.6 + source-map-support: 0.4.18 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-runtime/6.26.0: + resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==} + dependencies: + core-js: 2.6.12 + regenerator-runtime: 0.11.1 + dev: true + + /babel-template/6.26.0: + resolution: {integrity: sha512-PCOcLFW7/eazGUKIoqH97sO9A2UYMahsn/yRQ7uOk37iutwjq7ODtcTNF+iFDSHNfkctqsLRjLP7URnOx0T1fg==} + dependencies: + babel-runtime: 6.26.0 + babel-traverse: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-traverse/6.26.0: + resolution: {integrity: sha512-iSxeXx7apsjCHe9c7n8VtRXGzI2Bk1rBSOJgCCjfyXb6v1aCqE1KSEpq/8SXuVN8Ka/Rh1WDTF0MDzkvTA4MIA==} + dependencies: + babel-code-frame: 6.26.0 + babel-messages: 6.23.0 + babel-runtime: 6.26.0 + babel-types: 6.26.0 + babylon: 6.18.0 + debug: 2.6.9 + globals: 9.18.0 + invariant: 2.2.4 + lodash: 4.17.21 + transitivePeerDependencies: + - supports-color + dev: true + + /babel-types/6.26.0: + resolution: {integrity: sha512-zhe3V/26rCWsEZK8kZN+HaQj5yQ1CilTObixFzKW1UWjqG7618Twz6YEsCnjfg5gBcJh02DrpCkS9h98ZqDY+g==} + dependencies: + babel-runtime: 6.26.0 + esutils: 2.0.3 + lodash: 4.17.21 + to-fast-properties: 1.0.3 + dev: true + + /babylon/6.18.0: + resolution: {integrity: sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==} + hasBin: true + dev: true + + /balanced-match/1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + dev: true + + /base/0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.0 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + dev: true + + /binary-extensions/1.13.1: + resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} + engines: {node: '>=0.10.0'} + dev: true + + /bindings/1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + dependencies: + file-uri-to-path: 1.0.0 + dev: true + + /brace-expansion/1.1.11: + resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + dev: true + + /braces/1.8.5: + resolution: {integrity: sha512-xU7bpz2ytJl1bH9cgIurjpg/n8Gohy9GTw81heDYLJQ4RU60dlyJsa+atVF2pI0yMMvKxI9HkKwjePCj5XI1hw==} + engines: {node: '>=0.10.0'} + dependencies: + expand-range: 1.8.2 + preserve: 0.2.0 + repeat-element: 1.1.4 + dev: true + + /braces/2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /busboy/0.2.14: + resolution: {integrity: sha512-InWFDomvlkEj+xWLBfU3AvnbVYqeTWmQopiW0tWWEy5yehYm2YkGEc59sUmw/4ty5Zj/b0WHGs1LgecuBSBGrg==} + engines: {node: '>=0.8.0'} + dependencies: + dicer: 0.2.5 + readable-stream: 1.1.14 + dev: true + + /cache-base/1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.0 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + dev: true + + /chalk/1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + dev: true + + /chalk/4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + dev: true + + /chokidar/1.7.0: + resolution: {integrity: sha512-mk8fAWcRUOxY7btlLtitj3A45jOwSAxH4tOFOoEGbVsl6cL6pPMWUy7dwZ/canfj3QEdP6FHSnf/l1c6/WkzVg==} + deprecated: Chokidar 2 will break on node v14+. Upgrade to chokidar 3 with 15x less dependencies. + dependencies: + anymatch: 1.3.2 + async-each: 1.0.3 + glob-parent: 2.0.0 + inherits: 2.0.4 + is-binary-path: 1.0.1 + is-glob: 2.0.1 + path-is-absolute: 1.0.1 + readdirp: 2.2.1 + optionalDependencies: + fsevents: 1.2.13 + transitivePeerDependencies: + - supports-color + dev: true + + /class-utils/0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + dev: true + + /clone-buffer/1.0.0: + resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} + engines: {node: '>= 0.10'} + dev: true + + /clone-stats/1.0.0: + resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} + dev: true + + /clone/2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + dev: true + + /cloneable-readable/1.1.3: + resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} + dependencies: + inherits: 2.0.4 + process-nextick-args: 2.0.1 + readable-stream: 2.3.7 + dev: true + + /collection-visit/1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + dev: true + + /color-convert/2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: true + + /color-name/1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: true + + /colors/1.1.2: + resolution: {integrity: sha512-ENwblkFQpqqia6b++zLD/KUWafYlVY/UNnAp7oz7LY7E924wmpye416wBOmvv/HMWzl8gL1kJlfvId/1Dg176w==} + engines: {node: '>=0.1.90'} + dev: true + + /commander/2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + dev: true + + /component-emitter/1.3.0: + resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} + dev: true + + /concat-map/0.0.1: + resolution: {integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=} + dev: true + + /convert-source-map/1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: true + + /copy-descriptor/0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + dev: true + + /core-js/2.6.12: + resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==} + deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js. + requiresBuild: true + dev: true + + /core-util-is/1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + dev: true + + /cpx/1.5.0: + resolution: {integrity: sha512-jHTjZhsbg9xWgsP2vuNW2jnnzBX+p4T+vNI9Lbjzs1n4KhOfa22bQppiFYLsWQKd8TzmL5aSP/Me3yfsCwXbDA==} + hasBin: true + dependencies: + babel-runtime: 6.26.0 + chokidar: 1.7.0 + duplexer: 0.1.2 + glob: 7.2.3 + glob2base: 0.0.12 + minimatch: 3.1.2 + mkdirp: 0.5.6 + resolve: 1.22.1 + safe-buffer: 5.2.1 + shell-quote: 1.7.3 + subarg: 1.0.0 + transitivePeerDependencies: + - supports-color + dev: true + + /deasync/0.1.28: + resolution: {integrity: sha512-QqLF6inIDwiATrfROIyQtwOQxjZuek13WRYZ7donU5wJPLoP67MnYxA6QtqdvdBy2mMqv5m3UefBVdJjvevOYg==} + engines: {node: '>=0.11.0'} + requiresBuild: true + dependencies: + bindings: 1.5.0 + node-addon-api: 1.7.2 + dev: true + + /debug/2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.0.0 + dev: true + + /decode-uri-component/0.2.0: + resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} + engines: {node: '>=0.10'} + dev: true + + /define-property/0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 0.1.6 + dev: true + + /define-property/1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + dev: true + + /define-property/2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-descriptor: 1.0.2 + isobject: 3.0.1 + dev: true + + /detect-indent/4.0.0: + resolution: {integrity: sha512-BDKtmHlOzwI7iRuEkhzsnPoi5ypEhWAJB5RvHWe1kMr06js3uK5B3734i3ui5Yd+wOJV1cpE4JnivPD283GU/A==} + engines: {node: '>=0.10.0'} + dependencies: + repeating: 2.0.1 + dev: true + + /dicer/0.2.5: + resolution: {integrity: sha512-FDvbtnq7dzlPz0wyYlOExifDEZcu8h+rErEXgfxqmLfRfC/kJidEFh4+effJRO3P0xmfqyPbSMG0LveNRfTKVg==} + engines: {node: '>=0.8.0'} + dependencies: + readable-stream: 1.1.14 + streamsearch: 0.1.2 + dev: true + + /duplexer/0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + dev: true + + /escape-string-regexp/1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + dev: true + + /esutils/2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + dev: true + + /expand-brackets/0.1.5: + resolution: {integrity: sha512-hxx03P2dJxss6ceIeri9cmYOT4SRs3Zk3afZwWpOsRqLqprhTR8u++SlC+sFGsQr7WGFPdMF7Gjc1njDLDK6UA==} + engines: {node: '>=0.10.0'} + dependencies: + is-posix-bracket: 0.1.1 + dev: true + + /expand-brackets/2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /expand-range/1.8.2: + resolution: {integrity: sha512-AFASGfIlnIbkKPQwX1yHaDjFvh/1gyKJODme52V6IORh69uEYgZp0o9C+qsIGNVEiuuhQU0CSSl++Rlegg1qvA==} + engines: {node: '>=0.10.0'} + dependencies: + fill-range: 2.2.4 + dev: true + + /extend-shallow/2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + dependencies: + is-extendable: 0.1.1 + dev: true + + /extend-shallow/3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + dev: true + + /extglob/0.3.2: + resolution: {integrity: sha512-1FOj1LOwn42TMrruOHGt18HemVnbwAmAak7krWk+wa93KXxGbK+2jpezm+ytJYDaBX0/SPLZFHKM7m+tKobWGg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 1.0.0 + dev: true + + /extglob/2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /file-uri-to-path/1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + dev: true + + /filename-regex/2.0.1: + resolution: {integrity: sha512-BTCqyBaWBTsauvnHiE8i562+EdJj+oUpkqWp2R1iCoR8f6oo8STRu3of7WJJ0TqWtxN50a5YFpzYK4Jj9esYfQ==} + engines: {node: '>=0.10.0'} + dev: true + + /fill-range/2.2.4: + resolution: {integrity: sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 2.1.0 + isobject: 2.1.0 + randomatic: 3.1.1 + repeat-element: 1.1.4 + repeat-string: 1.6.1 + dev: true + + /fill-range/4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + dev: true + + /find-index/0.1.1: + resolution: {integrity: sha512-uJ5vWrfBKMcE6y2Z8834dwEZj9mNGxYa3t3I53OwFeuZ8D9oc2E5zcsrkuhX6h4iYrjhiv0T3szQmxlAV9uxDg==} + dev: true + + /for-in/1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + dev: true + + /for-own/0.1.5: + resolution: {integrity: sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==} + engines: {node: '>=0.10.0'} + dependencies: + for-in: 1.0.2 + dev: true + + /fragment-cache/0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + dependencies: + map-cache: 0.2.2 + dev: true + + /fs-readdir-recursive/1.1.0: + resolution: {integrity: sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==} + dev: true + + /fs.realpath/1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + dev: true + + /fsevents/1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. + requiresBuild: true + dependencies: + bindings: 1.5.0 + nan: 2.17.0 + dev: true + optional: true + + /function-bind/1.1.1: + resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} + dev: true + + /get-value/2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + dev: true + + /glob-base/0.3.0: + resolution: {integrity: sha512-ab1S1g1EbO7YzauaJLkgLp7DZVAqj9M/dvKlTt8DkXA2tiOIcSMrlVI2J1RZyB5iJVccEscjGn+kpOG9788MHA==} + engines: {node: '>=0.10.0'} + dependencies: + glob-parent: 2.0.0 + is-glob: 2.0.1 + dev: true + + /glob-parent/2.0.0: + resolution: {integrity: sha512-JDYOvfxio/t42HKdxkAYaCiBN7oYiuxykOxKxdaUW5Qn0zaYN3gRQWolrwdnf0shM9/EP0ebuuTmyoXNr1cC5w==} + dependencies: + is-glob: 2.0.1 + dev: true + + /glob/7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.2 + once: 1.4.0 + path-is-absolute: 1.0.1 + dev: true + + /glob2base/0.0.12: + resolution: {integrity: sha512-ZyqlgowMbfj2NPjxaZZ/EtsXlOch28FRXgMd64vqZWk1bT9+wvSRLYD1om9M7QfQru51zJPAT17qXm4/zd+9QA==} + engines: {node: '>= 0.10'} + dependencies: + find-index: 0.1.1 + dev: true + + /globals/9.18.0: + resolution: {integrity: sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==} + engines: {node: '>=0.10.0'} + dev: true + + /google-closure-compiler-java/20220905.0.0: + resolution: {integrity: sha512-wxGxNla/0UDS1Lm0cRxEy85KhVRd0vNlsTclnIJ9f1gRWzvvTsJ4lwz+PdT60R6y2hKAOBvydIJHh+B8XJastA==} + dev: true + + /google-closure-compiler-linux/20220905.0.0: + resolution: {integrity: sha512-kH09S66sz9+6wZmYM22VX8vG8KhCKJwFwXCfHx/ZOU6DBEzni6KfWrP+87CzTmZFEivclBhWAndm5HgNhSOEXQ==} + cpu: [x32, x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /google-closure-compiler-osx/20220905.0.0: + resolution: {integrity: sha512-4uo2GAz77gI8nDt4OA8VUYh/FNdjmTLOIRDazl7si+BOjgp9bC6C3E/88o+YHETsVtrPmZk57/W7vH0lftyTAw==} + cpu: [x32, x64, arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /google-closure-compiler-windows/20220905.0.0: + resolution: {integrity: sha512-TZKHu6RHnrmgV90Gyen8+TGc0vgjgds80ErR+al5CqmfP9p+AskBbOe5CWZJht0bANrUhaeBMCrbs+7loFv06Q==} + cpu: [x32, x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /google-closure-compiler/20220905.0.0: + resolution: {integrity: sha512-idZavy2vn91HCmqEepjmLFjfOdYoRsh9PggUbazUpjAOrBQz0HOm3WjOICMiywre+EnY1QGss0srEBtFtukM6w==} + engines: {node: '>=10'} + hasBin: true + dependencies: + chalk: 4.1.2 + google-closure-compiler-java: 20220905.0.0 + minimist: 1.2.7 + vinyl: 2.2.1 + vinyl-sourcemaps-apply: 0.2.1 + optionalDependencies: + google-closure-compiler-linux: 20220905.0.0 + google-closure-compiler-osx: 20220905.0.0 + google-closure-compiler-windows: 20220905.0.0 + dev: true + + /graceful-fs/4.2.10: + resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} + dev: true + + /has-ansi/2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + dependencies: + ansi-regex: 2.1.1 + dev: true + + /has-flag/4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + dev: true + + /has-value/0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + dev: true + + /has-value/1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + dev: true + + /has-values/0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + dev: true + + /has-values/1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + dev: true + + /has/1.0.3: + resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} + engines: {node: '>= 0.4.0'} + dependencies: + function-bind: 1.1.1 + dev: true + + /home-or-tmp/2.0.0: + resolution: {integrity: sha512-ycURW7oUxE2sNiPVw1HVEFsW+ecOpJ5zaj7eC0RlwhibhRBod20muUN8qu/gzx956YrLolVvs1MTXwKgC2rVEg==} + engines: {node: '>=0.10.0'} + dependencies: + os-homedir: 1.0.2 + os-tmpdir: 1.0.2 + dev: true + + /inflight/1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + dev: true + + /inherits/2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + dev: true + + /inherits/2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: true + + /interpret/1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + dev: true + + /invariant/2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + dependencies: + loose-envify: 1.4.0 + dev: true + + /is-accessor-descriptor/0.1.6: + resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-accessor-descriptor/1.0.0: + resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-binary-path/1.0.1: + resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} + engines: {node: '>=0.10.0'} + dependencies: + binary-extensions: 1.13.1 + dev: true + + /is-buffer/1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + dev: true + + /is-core-module/2.10.0: + resolution: {integrity: sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==} + dependencies: + has: 1.0.3 + dev: true + + /is-data-descriptor/0.1.4: + resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-data-descriptor/1.0.0: + resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 6.0.3 + dev: true + + /is-descriptor/0.1.6: + resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 0.1.6 + is-data-descriptor: 0.1.4 + kind-of: 5.1.0 + dev: true + + /is-descriptor/1.0.2: + resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} + engines: {node: '>=0.10.0'} + dependencies: + is-accessor-descriptor: 1.0.0 + is-data-descriptor: 1.0.0 + kind-of: 6.0.3 + dev: true + + /is-dotfile/1.0.3: + resolution: {integrity: sha512-9YclgOGtN/f8zx0Pr4FQYMdibBiTaH3sn52vjYip4ZSf6C4/6RfTEZ+MR4GvKhCxdPh21Bg42/WL55f6KSnKpg==} + engines: {node: '>=0.10.0'} + dev: true + + /is-equal-shallow/0.1.3: + resolution: {integrity: sha512-0EygVC5qPvIyb+gSz7zdD5/AAoS6Qrx1e//6N4yv4oNm30kqvdmG66oZFWVlQHUWe5OjP08FuTw2IdT0EOTcYA==} + engines: {node: '>=0.10.0'} + dependencies: + is-primitive: 2.0.0 + dev: true + + /is-extendable/0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + dev: true + + /is-extendable/1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + dependencies: + is-plain-object: 2.0.4 + dev: true + + /is-extglob/1.0.0: + resolution: {integrity: sha512-7Q+VbVafe6x2T+Tu6NcOf6sRklazEPmBoB3IWk3WdGZM2iGUwU/Oe3Wtq5lSEkDTTlpp8yx+5t4pzO/i9Ty1ww==} + engines: {node: '>=0.10.0'} + dev: true + + /is-finite/1.1.0: + resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} + engines: {node: '>=0.10.0'} + dev: true + + /is-glob/2.0.1: + resolution: {integrity: sha512-a1dBeB19NXsf/E0+FHqkagizel/LQw2DjSQpvQrj3zT+jYPpaUCryPnrQajXKFLCMuf4I6FhRpaGtw4lPrG6Eg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 1.0.0 + dev: true + + /is-number/2.1.0: + resolution: {integrity: sha512-QUzH43Gfb9+5yckcrSA0VBDwEtDUchrk4F6tfJZQuNzDJbEDB9cZNzSfXGQ1jqmdDY/kl41lUOWM9syA8z8jlg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-number/3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /is-number/4.0.0: + resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-plain-object/2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /is-posix-bracket/0.1.1: + resolution: {integrity: sha512-Yu68oeXJ7LeWNmZ3Zov/xg/oDBnBK2RNxwYY1ilNJX+tKKZqgPK+qOn/Gs9jEu66KDY9Netf5XLKNGzas/vPfQ==} + engines: {node: '>=0.10.0'} + dev: true + + /is-primitive/2.0.0: + resolution: {integrity: sha512-N3w1tFaRfk3UrPfqeRyD+GYDASU3W5VinKhlORy8EWVf/sIdDL9GAcew85XmktCfH+ngG7SRXEVDoO18WMdB/Q==} + engines: {node: '>=0.10.0'} + dev: true + + /is-windows/1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + dev: true + + /isarray/0.0.1: + resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==} + dev: true + + /isarray/1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + dev: true + + /isobject/2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + dependencies: + isarray: 1.0.0 + dev: true + + /isobject/3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + dev: true + + /js-tokens/3.0.2: + resolution: {integrity: sha512-RjTcuD4xjtthQkaWH7dFlH85L+QaVtSoOyGdZ3g6HFhS9dFNDfLyqgm2NFe2X6cQpeFmt0452FJjFG5UameExg==} + dev: true + + /js-tokens/4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: true + + /jsesc/1.3.0: + resolution: {integrity: sha512-Mke0DA0QjUWuJlhsE0ZPPhYiJkRap642SmI/4ztCFaUs6V2AiH1sfecc+57NgaryfAA2VR3v6O+CSjC1jZJKOA==} + hasBin: true + dev: true + + /json5/0.5.1: + resolution: {integrity: sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==} + hasBin: true + dev: true + + /kind-of/3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of/4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + dependencies: + is-buffer: 1.1.6 + dev: true + + /kind-of/5.1.0: + resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} + engines: {node: '>=0.10.0'} + dev: true + + /kind-of/6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + dev: true + + /lodash/4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + dev: true + + /loose-envify/1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: true + + /map-cache/0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + dev: true + + /map-visit/1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + dependencies: + object-visit: 1.0.1 + dev: true + + /math-random/1.0.4: + resolution: {integrity: sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==} + dev: true + + /mauss/0.3.3: + resolution: {integrity: sha512-NSTslY2so2r6+cEwQi5Yc6i+L2aEEesd1WPOfYommjmg8UAXS87MVWnLXuR0XR0gWS3ukit+JMCKuT1Xkg7EvQ==} + dev: true + + /micromatch/2.3.11: + resolution: {integrity: sha512-LnU2XFEk9xxSJ6rfgAry/ty5qwUTyHYOBU0g4R6tIw5ljwgGIBmiKhRWLw5NpMOnrgUNcDJ4WMp8rl3sYVHLNA==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 2.0.0 + array-unique: 0.2.1 + braces: 1.8.5 + expand-brackets: 0.1.5 + extglob: 0.3.2 + filename-regex: 2.0.1 + is-extglob: 1.0.0 + is-glob: 2.0.1 + kind-of: 3.2.2 + normalize-path: 2.1.1 + object.omit: 2.0.1 + parse-glob: 3.0.4 + regex-cache: 0.4.4 + dev: true + + /micromatch/3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /mime/1.3.6: + resolution: {integrity: sha512-a/kG+3WTtU8GJG1ngpkkHOHcH6zNjGrI47OQyoFsFBN0QpYYJ4u2yEORsGK5cZMI+cfu9HbSCCfGfRzG0fWE9A==} + hasBin: true + dev: true + + /minimatch/3.1.2: + resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} + dependencies: + brace-expansion: 1.1.11 + dev: true + + /minimist/1.2.7: + resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} + dev: true + + /mixin-deep/1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + dev: true + + /mkdirp/0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.7 + dev: true + + /ms/2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + dev: true + + /nan/2.17.0: + resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==} + requiresBuild: true + dev: true + optional: true + + /nanomatch/1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + dev: true + + /node-addon-api/1.7.2: + resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + dev: true + + /node-screwdriver/0.1.7: + resolution: {integrity: sha512-e++Oq/VFt9wKQg9pSdFpWOZGwjlVdAonjL8ZMC3elDRQy3/MuH4LF/AqsqgNQGury2x7BftZYz8aoNYAtNG/2A==} + dependencies: + deasync: 0.1.28 + dev: true + + /normalize-path/2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + dependencies: + remove-trailing-separator: 1.1.0 + dev: true + + /object-assign/4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + dev: true + + /object-copy/0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + dev: true + + /object-visit/1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /object.omit/2.0.1: + resolution: {integrity: sha512-UiAM5mhmIuKLsOvrL+B0U2d1hXHF3bFYWIuH1LMpuV2EJEHG1Ntz06PgLEHjm6VFd87NpH8rastvPoyv6UW2fA==} + engines: {node: '>=0.10.0'} + dependencies: + for-own: 0.1.5 + is-extendable: 0.1.1 + dev: true + + /object.pick/1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + dependencies: + isobject: 3.0.1 + dev: true + + /once/1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: true + + /os-homedir/1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + dev: true + + /os-tmpdir/1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + dev: true + + /output-file-sync/1.1.2: + resolution: {integrity: sha512-uQLlclru4xpCi+tfs80l3QF24KL81X57ELNMy7W/dox+JTtxUf1bLyQ8968fFCmSqqbokjW0kn+WBIlO+rSkNg==} + dependencies: + graceful-fs: 4.2.10 + mkdirp: 0.5.6 + object-assign: 4.1.1 + dev: true + + /parse-glob/3.0.4: + resolution: {integrity: sha512-FC5TeK0AwXzq3tUBFtH74naWkPQCEWs4K+xMxWZBlKDWu0bVHXGZa+KKqxKidd7xwhdZ19ZNuF2uO1M/r196HA==} + engines: {node: '>=0.10.0'} + dependencies: + glob-base: 0.3.0 + is-dotfile: 1.0.3 + is-extglob: 1.0.0 + is-glob: 2.0.1 + dev: true + + /pascalcase/0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + dev: true + + /path-is-absolute/1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + dev: true + + /path-parse/1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + dev: true + + /path/0.12.7: + resolution: {integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==} + dependencies: + process: 0.11.10 + util: 0.10.4 + dev: true + + /posix-character-classes/0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + dev: true + + /preserve/0.2.0: + resolution: {integrity: sha512-s/46sYeylUfHNjI+sA/78FAHlmIuKqI9wNnzEOGehAlUUYeObv5C2mOinXBjyUyWmJ2SfcS2/ydApH4hTF4WXQ==} + engines: {node: '>=0.10.0'} + dev: true + + /prettier/2.7.1: + resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} + engines: {node: '>=10.13.0'} + hasBin: true + dev: true + + /private/0.1.8: + resolution: {integrity: sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==} + engines: {node: '>= 0.6'} + dev: true + + /process-nextick-args/2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + dev: true + + /process/0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + + /punycode/1.3.2: + resolution: {integrity: sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==} + dev: true + + /querystring/0.2.0: + resolution: {integrity: sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==} + engines: {node: '>=0.4.x'} + deprecated: The querystring API is considered Legacy. new code should use the URLSearchParams API instead. + dev: true + + /randomatic/3.1.1: + resolution: {integrity: sha512-TuDE5KxZ0J461RVjrJZCJc+J+zCkTb1MbH9AQUq68sMhOMcy9jLcb3BrZKgp9q9Ncltdg4QVqWrH02W2EFFVYw==} + engines: {node: '>= 0.10.0'} + dependencies: + is-number: 4.0.0 + kind-of: 6.0.3 + math-random: 1.0.4 + dev: true + + /readable-stream/1.1.14: + resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 0.0.1 + string_decoder: 0.10.31 + dev: true + + /readable-stream/2.3.7: + resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + dev: true + + /readdirp/2.2.1: + resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} + engines: {node: '>=0.10'} + dependencies: + graceful-fs: 4.2.10 + micromatch: 3.1.10 + readable-stream: 2.3.7 + transitivePeerDependencies: + - supports-color + dev: true + + /rechoir/0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + dependencies: + resolve: 1.22.1 + dev: true + + /regenerator-runtime/0.10.5: + resolution: {integrity: sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==} + dev: true + + /regenerator-runtime/0.11.1: + resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==} + dev: true + + /regex-cache/0.4.4: + resolution: {integrity: sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==} + engines: {node: '>=0.10.0'} + dependencies: + is-equal-shallow: 0.1.3 + dev: true + + /regex-not/1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + dev: true + + /remove-trailing-separator/1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + dev: true + + /repeat-element/1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + dev: true + + /repeat-string/1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + dev: true + + /repeating/2.0.1: + resolution: {integrity: sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==} + engines: {node: '>=0.10.0'} + dependencies: + is-finite: 1.1.0 + dev: true + + /replace-ext/1.0.1: + resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} + engines: {node: '>= 0.10'} + dev: true + + /resolve-url/0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + dev: true + + /resolve/1.22.1: + resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + hasBin: true + dependencies: + is-core-module: 2.10.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + dev: true + + /ret/0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + dev: true + + /safe-buffer/5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + dev: true + + /safe-buffer/5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: true + + /safe-regex/1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + dependencies: + ret: 0.1.15 + dev: true + + /set-value/2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + dev: true + + /shell-quote/1.7.3: + resolution: {integrity: sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==} + dev: true + + /shelljs/0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + dev: true + + /shx/0.3.4: + resolution: {integrity: sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==} + engines: {node: '>=6'} + hasBin: true + dependencies: + minimist: 1.2.7 + shelljs: 0.8.5 + dev: true + + /slash/1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + dev: true + + /snapdragon-node/2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + dev: true + + /snapdragon-util/3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /snapdragon/0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + dev: true + + /source-map-resolve/0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.0 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + dev: true + + /source-map-support/0.4.18: + resolution: {integrity: sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==} + dependencies: + source-map: 0.5.7 + dev: true + + /source-map-url/0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + dev: true + + /source-map/0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + dev: true + + /split-string/3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + dependencies: + extend-shallow: 3.0.2 + dev: true + + /static-extend/0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + dev: true + + /streamsearch/0.1.2: + resolution: {integrity: sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==} + engines: {node: '>=0.8.0'} + dev: true + + /string_decoder/0.10.31: + resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==} + dev: true + + /string_decoder/1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + dependencies: + safe-buffer: 5.1.2 + dev: true + + /strip-ansi/3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + dependencies: + ansi-regex: 2.1.1 + dev: true + + /subarg/1.0.0: + resolution: {integrity: sha512-RIrIdRY0X1xojthNcVtgT9sjpOGagEUKpZdgBUi054OEPFo282yg+zE+t1Rj3+RqKq2xStL7uUHhY+AjbC4BXg==} + dependencies: + minimist: 1.2.7 + dev: true + + /supports-color/2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + dev: true + + /supports-color/7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + dependencies: + has-flag: 4.0.0 + dev: true + + /supports-preserve-symlinks-flag/1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + dev: true + + /to-fast-properties/1.0.3: + resolution: {integrity: sha512-lxrWP8ejsq+7E3nNjwYmUBMAgjMTZoTI+sdBOpvNyijeDLa29LUn9QaoXAHv4+Z578hbmHHJKZknzxVtvo77og==} + engines: {node: '>=0.10.0'} + dev: true + + /to-object-path/0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + dependencies: + kind-of: 3.2.2 + dev: true + + /to-regex-range/2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + dev: true + + /to-regex/3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + dev: true + + /trim-right/1.0.1: + resolution: {integrity: sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==} + engines: {node: '>=0.10.0'} + dev: true + + /typescript/4.8.4: + resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} + engines: {node: '>=4.2.0'} + hasBin: true + dev: true + + /union-value/1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + dev: true + + /unset-value/1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + dev: true + + /urix/0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + dev: true + + /url/0.11.0: + resolution: {integrity: sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==} + dependencies: + punycode: 1.3.2 + querystring: 0.2.0 + dev: true + + /use/3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + dev: true + + /user-home/1.1.1: + resolution: {integrity: sha512-aggiKfEEubv3UwRNqTzLInZpAOmKzwdHqEBmW/hBA/mt99eg+b4VrX6i+IRLxU8+WJYfa33rGwRseg4eElUgsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dev: true + + /util-deprecate/1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + dev: true + + /util/0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + dependencies: + inherits: 2.0.3 + dev: true + + /v8flags/2.1.1: + resolution: {integrity: sha512-SKfhk/LlaXzvtowJabLZwD4K6SGRYeoxA7KJeISlUMAB/NT4CBkZjMq3WceX2Ckm4llwqYVo8TICgsDYCBU2tA==} + engines: {node: '>= 0.10.0'} + dependencies: + user-home: 1.1.1 + dev: true + + /vinyl-sourcemaps-apply/0.2.1: + resolution: {integrity: sha512-+oDh3KYZBoZC8hfocrbrxbLUeaYtQK7J5WU5Br9VqWqmCll3tFJqKp97GC9GmMsVIL0qnx2DgEDVxdo5EZ5sSw==} + dependencies: + source-map: 0.5.7 + dev: true + + /vinyl/2.2.1: + resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} + engines: {node: '>= 0.10'} + dependencies: + clone: 2.1.2 + clone-buffer: 1.0.0 + clone-stats: 1.0.0 + cloneable-readable: 1.1.3 + remove-trailing-separator: 1.1.0 + replace-ext: 1.0.1 + dev: true + + /web-servo/0.5.1: + resolution: {integrity: sha512-GXR2ILhMQnAIDXyeHMG83gs7q5SoG0mwi7mnnq4D+6+/wqRIeFL6cRWrh8sm4gB+w8kYvkFe02by7hokqVPPXg==} + dependencies: + busboy: 0.2.14 + colors: 1.1.2 + mime: 1.3.6 + node-screwdriver: 0.1.7 + path: 0.12.7 + url: 0.11.0 + dev: true + + /wrappy/1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: true diff --git a/src/async.js b/src/async.js index 31f1c08..cbee2a3 100644 --- a/src/async.js +++ b/src/async.js @@ -1,51 +1,45 @@ -import { IndexInterface, DocumentInterface } from "./type.js"; -//import { promise as Promise } from "./polyfill.js"; -import { is_function, is_object, is_string } from "./common.js"; - -export default function(prototype){ - - register(prototype, "add"); - register(prototype, "append"); - register(prototype, "search"); - register(prototype, "update"); - register(prototype, "remove"); +import { is_function } from './common.js'; + +export default function (prototype) { + register(prototype, 'add'); + register(prototype, 'append'); + register(prototype, 'search'); + register(prototype, 'update'); + register(prototype, 'remove'); } -function register(prototype, key){ - - prototype[key + "Async"] = function(){ - - /** @type {IndexInterface|DocumentInterface} */ - const self = this; - const args = /*[].slice.call*/(arguments); - const arg = args[args.length - 1]; - let callback; - - if(is_function(arg)){ - - callback = arg; - delete args[args.length - 1]; - } - - const promise = new Promise(function(resolve){ - - setTimeout(function(){ - - self.async = true; - const res = self[key].apply(self, args); - self.async = false; - resolve(res); - }); - }); - - if(callback){ - - promise.then(callback); - return this; - } - else{ - - return promise; - } - }; +function register(prototype, key) { + /** + * @typedef {import('./type').DocumentInterface} Document + * @typedef {import('./type').IndexInterface} Index + */ + + prototype[key + 'Async'] = function () { + /** @type {Document | Index} */ + const self = this; + const args = /*[].slice.call*/ arguments; + const arg = args[args.length - 1]; + let callback; + + if (is_function(arg)) { + callback = arg; + delete args[args.length - 1]; + } + + const promise = new Promise(function (resolve) { + setTimeout(function () { + self.async = true; + const res = self[key].apply(self, args); + self.async = false; + resolve(res); + }); + }); + + if (callback) { + promise.then(callback); + return this; + } else { + return promise; + } + }; } diff --git a/src/cache.js b/src/cache.js index 5cd7407..630d43c 100644 --- a/src/cache.js +++ b/src/cache.js @@ -1,51 +1,51 @@ -import { IndexInterface, DocumentInterface } from "./type.js"; -import { create_object, is_object } from "./common.js"; +import { create_object, is_object } from './common.js'; + +/** + * @typedef {import('./type').DocumentInterface} Document + * @typedef {import('./type').IndexInterface} Index + */ /** * @param {boolean|number=} limit * @constructor */ -function CacheClass(limit){ - - /** @private */ - this.limit = (limit !== true) && limit; +function CacheClass(limit) { + /** @private */ + this.limit = limit !== true && limit; - /** @private */ - this.cache = create_object(); + /** @private */ + this.cache = create_object(); - /** @private */ - this.queue = []; + /** @private */ + this.queue = []; - //this.clear(); + //this.clear(); } export default CacheClass; /** - * @param {string|Object} query - * @param {number|Object=} limit - * @param {Object=} options - * @this {IndexInterface} + * @param {string | Object} query + * @param {number | Object} limit + * @param {Object} options + * @this {Index} * @returns {Array} */ -export function searchCache(query, limit, options){ +export function searchCache(query, limit, options) { + if (is_object(query)) { + query = query['query']; + } - if(is_object(query)){ + let cache = this.cache.get(query); - query = query["query"]; - } + if (!cache) { + cache = this.search(query, limit, options); + this.cache.set(query, cache); + } - let cache = this.cache.get(query); - - if(!cache){ - - cache = this.search(query, limit, options); - this.cache.set(query, cache); - } - - return cache; + return cache; } // CacheClass.prototype.clear = function(){ @@ -57,113 +57,101 @@ export function searchCache(query, limit, options){ // this.queue = []; // }; -CacheClass.prototype.set = function(key, value){ - - if(!this.cache[key]){ - - // it is just a shame that native function array.shift() performs so bad - - // const length = this.queue.length; - // - // this.queue[length] = key; - // - // if(length === this.limit){ - // - // delete this.cache[this.queue.shift()]; - // } - - // the same bad performance - - // this.queue.unshift(key); - // - // if(this.queue.length === this.limit){ - // - // this.queue.pop(); - // } - - // fast implementation variant - - // let length = this.queue.length; - // - // if(length === this.limit){ - // - // length--; - // - // delete this.cache[this.queue[0]]; - // - // for(let x = 0; x < length; x++){ - // - // this.queue[x] = this.queue[x + 1]; - // } - // } - // - // this.queue[length] = key; - - // current fastest implementation variant - // theoretically that should not perform better compared to the example above - - let length = this.queue.length; - - if(length === this.limit){ - - delete this.cache[this.queue[length - 1]]; - } - else{ - - length++; - } - - for(let x = length - 1; x > 0; x--){ - - this.queue[x] = this.queue[x - 1]; - } - - this.queue[0] = key; - } - - this.cache[key] = value; +CacheClass.prototype.set = function (key, value) { + if (!this.cache[key]) { + // it is just a shame that native function array.shift() performs so bad + + // const length = this.queue.length; + // + // this.queue[length] = key; + // + // if(length === this.limit){ + // + // delete this.cache[this.queue.shift()]; + // } + + // the same bad performance + + // this.queue.unshift(key); + // + // if(this.queue.length === this.limit){ + // + // this.queue.pop(); + // } + + // fast implementation variant + + // let length = this.queue.length; + // + // if(length === this.limit){ + // + // length--; + // + // delete this.cache[this.queue[0]]; + // + // for(let x = 0; x < length; x++){ + // + // this.queue[x] = this.queue[x + 1]; + // } + // } + // + // this.queue[length] = key; + + // current fastest implementation variant + // theoretically that should not perform better compared to the example above + + let length = this.queue.length; + + if (length === this.limit) { + delete this.cache[this.queue[length - 1]]; + } else { + length++; + } + + for (let x = length - 1; x > 0; x--) { + this.queue[x] = this.queue[x - 1]; + } + + this.queue[0] = key; + } + + this.cache[key] = value; }; -CacheClass.prototype.get = function(key){ - - const cache = this.cache[key]; - - if(this.limit && cache){ - - // probably the indexOf() method performs faster when matched content is on front (left-to-right) - // using lastIndexOf() does not help, it performs almost slower +CacheClass.prototype.get = function (key) { + const cache = this.cache[key]; - const pos = this.queue.indexOf(key); + if (this.limit && cache) { + // probably the indexOf() method performs faster when matched content is on front (left-to-right) + // using lastIndexOf() does not help, it performs almost slower - // if(pos < this.queue.length - 1){ - // - // const tmp = this.queue[pos]; - // this.queue[pos] = this.queue[pos + 1]; - // this.queue[pos + 1] = tmp; - // } + const pos = this.queue.indexOf(key); - if(pos){ + // if(pos < this.queue.length - 1){ + // + // const tmp = this.queue[pos]; + // this.queue[pos] = this.queue[pos + 1]; + // this.queue[pos + 1] = tmp; + // } - const tmp = this.queue[pos - 1]; - this.queue[pos - 1] = this.queue[pos]; - this.queue[pos] = tmp; - } - } + if (pos) { + const tmp = this.queue[pos - 1]; + this.queue[pos - 1] = this.queue[pos]; + this.queue[pos] = tmp; + } + } - return cache; + return cache; }; -CacheClass.prototype.del = function(id){ - - for(let i = 0, item, key; i < this.queue.length; i++){ - - key = this.queue[i]; - item = this.cache[key]; - - if(item.includes(id)){ +CacheClass.prototype.del = function (id) { + for (let i = 0, item, key; i < this.queue.length; i++) { + key = this.queue[i]; + item = this.cache[key]; - this.queue.splice(i--, 1); - delete this.cache[key]; - } - } + if (item.includes(id)) { + this.queue.splice(i--, 1); + delete this.cache[key]; + } + } }; diff --git a/src/common.js b/src/common.js index 878eb1f..2c9f473 100644 --- a/src/common.js +++ b/src/common.js @@ -1,6 +1,5 @@ -export function parse_option(value, default_value){ - - return typeof value !== "undefined" ? value : default_value; +export function parse_option(value, default_value) { + return typeof value !== 'undefined' ? value : default_value; } /** @@ -8,28 +7,27 @@ export function parse_option(value, default_value){ * @returns {Array} */ -export function create_object_array(count){ - - const array = new Array(count); +export function create_object_array(count) { + const array = new Array(count); - for(let i = 0; i < count; i++){ + for (let i = 0; i < count; i++) { + array[i] = create_object(); + } - array[i] = create_object(); - } - - return array; + return array; } -export function create_arrays(count){ - - const array = new Array(count); - - for(let i = 0; i < count; i++){ +/** + * @param {number} count + */ +export function create_arrays(count) { + const array = new Array(count); - array[i] = []; - } + for (let i = 0; i < count; i++) { + array[i] = []; + } - return array; + return array; } /** @@ -37,42 +35,59 @@ export function create_arrays(count){ * @returns {Array} */ -export function get_keys(obj){ - - return Object.keys(obj); +export function get_keys(obj) { + return Object.keys(obj); } -export function create_object(){ - - return Object.create(null); +export function create_object() { + return Object.create(null); } -export function concat(arrays){ - - return [].concat.apply([], arrays); +/** + * @param {any[]} arrays + */ +export function concat(arrays) { + return [].concat.apply([], arrays); } -export function sort_by_length_down(a, b){ - - return b.length - a.length; +/** + * @param {any[]} a + * @param {any[]} b + */ +export function sort_by_length_down(a, b) { + return b.length - a.length; } -export function is_array(val){ - - return val.constructor === Array; +/** + * @param {object} val + */ +export function is_array(val) { + return val.constructor === Array; } -export function is_string(val){ - - return typeof val === "string"; +/** + * @template T + * @param {T} val + * @returns {T is string} + */ +export function is_string(val) { + return typeof val === 'string'; } -export function is_object(val){ - - return typeof val === "object"; +/** + * @template T + * @param {T} val + * @returns {T is object} + */ +export function is_object(val) { + return typeof val === 'object'; } -export function is_function(val){ - - return typeof val === "function"; +/** + * @template T + * @param {T} val + * @returns {T is Function} + */ +export function is_function(val) { + return typeof val === 'function'; } diff --git a/src/document.js b/src/document.js index 395ad19..d83b237 100644 --- a/src/document.js +++ b/src/document.js @@ -7,86 +7,69 @@ */ import { - - SUPPORT_ASYNC, - SUPPORT_CACHE, - SUPPORT_SERIALIZE, - SUPPORT_STORE, - SUPPORT_TAGS, - SUPPORT_WORKER - -} from "./config.js"; - -import Index from "./index.js"; -import { DocumentInterface } from "./type.js"; -import Cache, { searchCache } from "./cache.js"; -import { create_object, is_array, is_string, is_object, parse_option, get_keys } from "./common.js"; -import apply_async from "./async.js"; -import { intersect, intersect_union } from "./intersect.js"; -import { exportDocument, importDocument } from "./serialize.js"; -import WorkerIndex from "./worker/index.js"; - -/** - * @constructor - * @implements DocumentInterface - * @param {Object=} options - * @return {Document} - */ - -function Document(options){ - - if(!(this instanceof Document)) { - - return new Document(options); - } - - const document = options["document"] || options["doc"] || options; - let opt; - - this.tree = []; - this.field = []; - this.marker = []; - this.register = create_object(); - this.key = ((opt = document["key"] || document["id"]) && parse_tree(opt, this.marker)) || "id"; - this.fastupdate = parse_option(options["fastupdate"], true); - - if(SUPPORT_STORE){ - - this.storetree = (opt = document["store"]) && (opt !== true) && []; - this.store = opt && create_object(); - } - - if(SUPPORT_TAGS){ - - // TODO case-insensitive tags - - this.tag = ((opt = document["tag"]) && parse_tree(opt, this.marker)); - this.tagindex = opt && create_object(); - } - - if(SUPPORT_CACHE){ - - this.cache = (opt = options["cache"]) && new Cache(opt); - - // do not apply cache again for the indexes - - options["cache"] = false; - } - - if(SUPPORT_WORKER){ - - this.worker = options["worker"]; - } - - if(SUPPORT_ASYNC){ - - // this switch is used by recall of promise callbacks - - this.async = false; - } - - /** @export */ - this.index = parse_descriptor.call(this, options, document); + SUPPORT_ASYNC, + SUPPORT_CACHE, + SUPPORT_SERIALIZE, + SUPPORT_STORE, + SUPPORT_TAGS, + SUPPORT_WORKER, +} from './config.js'; + +import Index from './index.js'; +import Cache, { searchCache } from './cache.js'; +import { create_object, is_array, is_string, is_object, parse_option } from './common.js'; +import apply_async from './async.js'; +import { intersect, intersect_union } from './intersect.js'; +import { exportDocument, importDocument } from './serialize.js'; +import WorkerIndex from './worker/index.js'; + +function Document(options) { + if (!(this instanceof Document)) { + return new Document(options); + } + + const document = options['document'] || options['doc'] || options; + let opt; + + this.tree = []; + this.field = []; + this.marker = []; + this.register = create_object(); + this.key = ((opt = document['key'] || document['id']) && parse_tree(opt, this.marker)) || 'id'; + this.fastupdate = parse_option(options['fastupdate'], true); + + if (SUPPORT_STORE) { + this.storetree = (opt = document['store']) && opt !== true && []; + this.store = opt && create_object(); + } + + if (SUPPORT_TAGS) { + // TODO case-insensitive tags + + this.tag = (opt = document['tag']) && parse_tree(opt, this.marker); + this.tagindex = opt && create_object(); + } + + if (SUPPORT_CACHE) { + this.cache = (opt = options['cache']) && new Cache(opt); + + // do not apply cache again for the indexes + + options['cache'] = false; + } + + if (SUPPORT_WORKER) { + this.worker = options['worker']; + } + + if (SUPPORT_ASYNC) { + // this switch is used by recall of promise callbacks + + this.async = false; + } + + /** @export */ + this.index = parse_descriptor.call(this, options, document); } export default Document; @@ -95,693 +78,568 @@ export default Document; * @this Document */ -function parse_descriptor(options, document){ - - const index = create_object(); - let field = document["index"] || document["field"] || document; - - if(is_string(field)){ - - field = [field]; - } - - for(let i = 0, key, opt; i < field.length; i++){ - - key = field[i]; - - if(!is_string(key)){ - - opt = key; - key = key["field"]; - } - - opt = is_object(opt) ? Object.assign({}, options, opt) : options; +function parse_descriptor(options, document) { + const index = create_object(); + let field = document['index'] || document['field'] || document; - if(SUPPORT_WORKER && this.worker){ + if (is_string(field)) { + field = [field]; + } - index[key] = new WorkerIndex(opt); + for (let i = 0, key, opt; i < field.length; i++) { + key = field[i]; - if(!index[key].worker){ + if (!is_string(key)) { + opt = key; + key = key['field']; + } - this.worker = false; - } - } + opt = is_object(opt) ? Object.assign({}, options, opt) : options; - if(!this.worker){ + if (SUPPORT_WORKER && this.worker) { + index[key] = new WorkerIndex(opt); - index[key] = new Index(opt, this.register); - } + if (!index[key].worker) { + this.worker = false; + } + } - this.tree[i] = parse_tree(key, this.marker); - this.field[i] = key; - } + if (!this.worker) { + index[key] = new Index(opt, this.register); + } - if(SUPPORT_STORE && this.storetree){ + this.tree[i] = parse_tree(key, this.marker); + this.field[i] = key; + } - let store = document["store"]; + if (SUPPORT_STORE && this.storetree) { + let store = document['store']; - if(is_string(store)){ + if (is_string(store)) { + store = [store]; + } - store = [store]; - } + for (let i = 0; i < store.length; i++) { + this.storetree[i] = parse_tree(store[i], this.marker); + } + } - for(let i = 0; i < store.length; i++){ - - this.storetree[i] = parse_tree(store[i], this.marker); - } - } - - return index; + return index; } -function parse_tree(key, marker){ - - const tree = key.split(":"); - let count = 0; - - for(let i = 0; i < tree.length; i++){ - - key = tree[i]; - - if(key.indexOf("[]") >= 0){ +function parse_tree(key, marker) { + const tree = key.split(':'); + let count = 0; - key = key.substring(0, key.length - 2); + for (let i = 0; i < tree.length; i++) { + key = tree[i]; - if(key){ + if (key.indexOf('[]') >= 0) { + key = key.substring(0, key.length - 2); - marker[count] = true; - } - } + if (key) { + marker[count] = true; + } + } - if(key){ + if (key) { + tree[count++] = key; + } + } - tree[count++] = key; - } - } + if (count < tree.length) { + tree.length = count; + } - if(count < tree.length){ - - tree.length = count; - } - - return count > 1 ? tree : tree[0]; + return count > 1 ? tree : tree[0]; } // TODO support generic function created from string when tree depth > 1 -function parse_simple(obj, tree){ - - if(is_string(tree)){ - - obj = obj[tree]; - } - else{ - - for(let i = 0; obj && (i < tree.length); i++){ +function parse_simple(obj, tree) { + if (is_string(tree)) { + obj = obj[tree]; + } else { + for (let i = 0; obj && i < tree.length; i++) { + obj = obj[tree[i]]; + } + } - obj = obj[tree[i]]; - } - } - - return obj; + return obj; } // TODO support generic function created from string when tree depth > 1 -function store_value(obj, store, tree, pos, key){ - - obj = obj[key]; - - // reached target field - - if(pos === (tree.length - 1)){ - - // store target value - - store[key] = obj; - } - else if(obj){ +function store_value(obj, store, tree, pos, key) { + obj = obj[key]; - if(is_array(obj)){ + // reached target field - store = store[key] = new Array(obj.length); + if (pos === tree.length - 1) { + // store target value - for(let i = 0; i < obj.length; i++){ + store[key] = obj; + } else if (obj) { + if (is_array(obj)) { + store = store[key] = new Array(obj.length); - // do not increase pos (an array is not a field) - store_value(obj, store, tree, pos, i); - } - } - else{ + for (let i = 0; i < obj.length; i++) { + // do not increase pos (an array is not a field) + store_value(obj, store, tree, pos, i); + } + } else { + store = store[key] || (store[key] = create_object()); + key = tree[++pos]; - store = store[key] || (store[key] = create_object()); - key = tree[++pos]; - - store_value(obj, store, tree, pos, key); - } - } + store_value(obj, store, tree, pos, key); + } + } } -function add_index(obj, tree, marker, pos, index, id, key, _append){ - - obj = obj[key]; - - if(obj){ - - // reached target field - - if(pos === (tree.length - 1)){ +function add_index(obj, tree, marker, pos, index, id, key, _append) { + obj = obj[key]; - // handle target value + if (obj) { + // reached target field - if(is_array(obj)){ + if (pos === tree.length - 1) { + // handle target value - // append array contents so each entry gets a new scoring context + if (is_array(obj)) { + // append array contents so each entry gets a new scoring context - if(marker[pos]){ + if (marker[pos]) { + for (let i = 0; i < obj.length; i++) { + index.add(id, obj[i], /* append: */ true, /* skip update: */ true); + } - for(let i = 0; i < obj.length; i++){ + return; + } - index.add(id, obj[i], /* append: */ true, /* skip update: */ true); - } + // or join array contents and use one scoring context - return; - } + obj = obj.join(' '); + } - // or join array contents and use one scoring context + index.add(id, obj, _append, /* skip_update: */ true); + } else { + if (is_array(obj)) { + for (let i = 0; i < obj.length; i++) { + // do not increase index, an array is not a field - obj = obj.join(" "); - } + add_index(obj, tree, marker, pos, index, id, i, _append); + } + } else { + key = tree[++pos]; - index.add(id, obj, _append, /* skip_update: */ true); - } - else{ - - if(is_array(obj)){ - - for(let i = 0; i < obj.length; i++){ - - // do not increase index, an array is not a field - - add_index(obj, tree, marker, pos, index, id, i, _append); - } - } - else{ - - key = tree[++pos]; - - add_index(obj, tree, marker, pos, index, id, key, _append); - } - } - } + add_index(obj, tree, marker, pos, index, id, key, _append); + } + } + } } /** * * @param id * @param content - * @param {boolean=} _append - * @returns {Document|Promise} + * @param {boolean} _append + * @returns {Document | Promise} */ -Document.prototype.add = function(id, content, _append){ - - if(is_object(id)){ - - content = id; - id = parse_simple(content, this.key); - } - - if(content && (id || (id === 0))){ - - if(!_append && this.register[id]){ - - return this.update(id, content); - } +Document.prototype.add = function (id, content, _append) { + if (is_object(id)) { + content = id; + id = parse_simple(content, this.key); + } - for(let i = 0, tree, field; i < this.field.length; i++){ + if (content && (id || id === 0)) { + if (!_append && this.register[id]) { + return this.update(id, content); + } - field = this.field[i]; - tree = this.tree[i]; + for (let i = 0, tree, field; i < this.field.length; i++) { + field = this.field[i]; + tree = this.tree[i]; - if(is_string(tree)){ + if (is_string(tree)) { + tree = [tree]; + } - tree = [tree]; - } + add_index(content, tree, this.marker, 0, this.index[field], id, tree[0], _append); + } - add_index(content, tree, this.marker, 0, this.index[field], id, tree[0], _append); - } + if (SUPPORT_TAGS && this.tag) { + let tag = parse_simple(content, this.tag); + let dupes = create_object(); - if(SUPPORT_TAGS && this.tag){ + if (is_string(tag)) { + tag = [tag]; + } - let tag = parse_simple(content, this.tag); - let dupes = create_object(); + for (let i = 0, key, arr; i < tag.length; i++) { + key = tag[i]; - if(is_string(tag)){ + if (!dupes[key]) { + dupes[key] = 1; + arr = this.tagindex[key] || (this.tagindex[key] = []); - tag = [tag]; - } + if (!_append || !arr.includes(id)) { + arr[arr.length] = id; - for(let i = 0, key, arr; i < tag.length; i++){ + // add a reference to the register for fast updates - key = tag[i]; + if (this.fastupdate) { + const tmp = this.register[id] || (this.register[id] = []); + tmp[tmp.length] = arr; + } + } + } + } + } - if(!dupes[key]){ + // TODO: how to handle store when appending contents? - dupes[key] = 1; - arr = this.tagindex[key] || (this.tagindex[key] = []); + if (SUPPORT_STORE && this.store && (!_append || !this.store[id])) { + let store; - if(!_append || !arr.includes(id)){ + if (this.storetree) { + store = create_object(); - arr[arr.length] = id; + for (let i = 0, tree; i < this.storetree.length; i++) { + tree = this.storetree[i]; - // add a reference to the register for fast updates + if (is_string(tree)) { + store[tree] = content[tree]; + } else { + store_value(content, store, tree, 0, tree[0]); + } + } + } - if(this.fastupdate){ + this.store[id] = store || content; + } + } - const tmp = this.register[id] || (this.register[id] = []); - tmp[tmp.length] = arr; - } - } - } - } - } - - // TODO: how to handle store when appending contents? - - if(SUPPORT_STORE && this.store && (!_append || !this.store[id])){ - - let store; - - if(this.storetree){ - - store = create_object(); - - for(let i = 0, tree; i < this.storetree.length; i++){ - - tree = this.storetree[i]; - - if(is_string(tree)){ - - store[tree] = content[tree]; - } - else{ - - store_value(content, store, tree, 0, tree[0]); - } - } - } - - this.store[id] = store || content; - } - } - - return this; + return this; }; -Document.prototype.append = function(id, content){ - - return this.add(id, content, true); +Document.prototype.append = function (id, content) { + return this.add(id, content, true); }; -Document.prototype.update = function(id, content){ - - return this.remove(id).add(id, content); +Document.prototype.update = function (id, content) { + return this.remove(id).add(id, content); }; -Document.prototype.remove = function(id){ - - if(is_object(id)){ - - id = parse_simple(id, this.key); - } - - if(this.register[id]){ - - for(let i = 0; i < this.field.length; i++){ - - // workers does not share the register - - this.index[this.field[i]].remove(id, !this.worker); - - if(this.fastupdate){ - - // when fastupdate was enabled all ids are removed +Document.prototype.remove = function (id) { + if (is_object(id)) { + id = parse_simple(id, this.key); + } - break; - } - } + if (this.register[id]) { + for (let i = 0; i < this.field.length; i++) { + // workers does not share the register - if(SUPPORT_TAGS && this.tag){ + this.index[this.field[i]].remove(id, !this.worker); - // when fastupdate was enabled all ids are already removed + if (this.fastupdate) { + // when fastupdate was enabled all ids are removed - if(!this.fastupdate){ + break; + } + } - for(let key in this.tagindex){ + if (SUPPORT_TAGS && this.tag) { + // when fastupdate was enabled all ids are already removed - const tag = this.tagindex[key]; - const pos = tag.indexOf(id); + if (!this.fastupdate) { + for (let key in this.tagindex) { + const tag = this.tagindex[key]; + const pos = tag.indexOf(id); - if(pos !== -1){ + if (pos !== -1) { + if (tag.length > 1) { + tag.splice(pos, 1); + } else { + delete this.tagindex[key]; + } + } + } + } + } - if(tag.length > 1){ + if (SUPPORT_STORE && this.store) { + delete this.store[id]; + } - tag.splice(pos, 1); - } - else{ + delete this.register[id]; + } - delete this.tagindex[key]; - } - } - } - } - } - - if(SUPPORT_STORE && this.store){ - - delete this.store[id]; - } - - delete this.register[id]; - } - - return this; + return this; }; /** - * @param {!string|Object} query - * @param {number|Object=} limit - * @param {Object=} options - * @param {Array=} _resolve For internal use only. - * @returns {Promise|Array} + * @template T + * @param {string | Object} query + * @param {number | Object} limit + * @param {Object} options + * @param {any[]} _resolve For internal use only. + * @returns {Array | Promise} */ -Document.prototype.search = function(query, limit, options, _resolve){ - - if(!options){ - - if(!limit && is_object(query)){ - - options = /** @type {Object} */ (query); - query = ""; - } - else if(is_object(limit)){ - - options = /** @type {Object} */ (limit); - limit = 0; - } - } - - let result = [], result_field = []; - let pluck, enrich; - let field, tag, bool, offset, count = 0; - - if(options){ - - if(is_array(options)){ - - field = options; - options = null; - } - else{ - - query = options["query"] || query; - pluck = options["pluck"]; - field = pluck || options["index"] || options["field"] /*|| (is_string(options) && [options])*/; - tag = SUPPORT_TAGS && options["tag"]; - enrich = SUPPORT_STORE && this.store && options["enrich"]; - bool = options["bool"] === "and"; - limit = options["limit"] || limit || 100; - offset = options["offset"] || 0; - - if(tag){ - - if(is_string(tag)){ - - tag = [tag]; - } - - // when tags is used and no query was set, - // then just return the tag indexes - - if(!query){ - - for(let i = 0, res; i < tag.length; i++){ - - res = get_tag.call(this, tag[i], limit, offset, enrich); - - if(res){ - - result[result.length] = res; - count++; - } - } - - return count ? result : []; - } - } - - if(is_string(field)){ - - field = [field]; - } - } - } - - field || (field = this.field); - bool = bool && ((field.length > 1) || (tag && (tag.length > 1))); - - const promises = !_resolve && (this.worker || this.async) && []; - - // TODO solve this in one loop below - - for(let i = 0, res, key, len; i < field.length; i++){ - - let field_options; - - key = field[i]; - - if(!is_string(key)){ - - field_options = key; - key = field_options["field"]; - query = field_options["query"] || query; - limit = field_options["limit"] || limit; - } - - if(promises){ - - promises[i] = this.index[key].searchAsync(query, limit, field_options || options); - - // just collect and continue - - continue; - } - else if(_resolve){ - - res = _resolve[i]; - } - else{ - - // inherit options also when search? it is just for laziness, Object.assign() has a cost - - res = this.index[key].search(query, limit, field_options || options); - } - - len = res && res.length; - - if(tag && len){ - - const arr = []; - let count = 0; - - if(bool){ +Document.prototype.search = function (query, limit, options, _resolve) { + if (!options) { + if (!limit && is_object(query)) { + options = /** @type {Object} */ (query); + query = ''; + } else if (is_object(limit)) { + options = /** @type {Object} */ (limit); + limit = 0; + } + } + + let result = [], + result_field = []; + let pluck, enrich; + let field, + tag, + bool, + offset, + count = 0; + + if (options) { + if (is_array(options)) { + field = options; + options = null; + } else { + query = options['query'] || query; + pluck = options['pluck']; + field = + pluck || options['index'] || options['field'] /*|| (is_string(options) && [options])*/; + tag = SUPPORT_TAGS && options['tag']; + enrich = SUPPORT_STORE && this.store && options['enrich']; + bool = options['bool'] === 'and'; + limit = options['limit'] || limit || 100; + offset = options['offset'] || 0; + + if (tag) { + if (is_string(tag)) { + tag = [tag]; + } + + // when tags is used and no query was set, + // then just return the tag indexes + + if (!query) { + for (let i = 0, res; i < tag.length; i++) { + res = get_tag.call(this, tag[i], limit, offset, enrich); + + if (res) { + result[result.length] = res; + count++; + } + } + + return count ? result : []; + } + } + + if (is_string(field)) { + field = [field]; + } + } + } + + field || (field = this.field); + bool = bool && (field.length > 1 || (tag && tag.length > 1)); + + const promises = !_resolve && (this.worker || this.async) && []; + + // TODO solve this in one loop below + + for (let i = 0, res, key, len; i < field.length; i++) { + let field_options; + + key = field[i]; + + if (!is_string(key)) { + field_options = key; + key = field_options['field']; + query = field_options['query'] || query; + limit = field_options['limit'] || limit; + } + + if (promises) { + promises[i] = this.index[key].searchAsync(query, limit, field_options || options); + + // just collect and continue + + continue; + } else if (_resolve) { + res = _resolve[i]; + } else { + // inherit options also when search? it is just for laziness, Object.assign() has a cost + + res = this.index[key].search(query, limit, field_options || options); + } + + len = res && res.length; + + if (tag && len) { + const arr = []; + let count = 0; + + if (bool) { + // prepare for intersection + + arr[0] = [res]; + } + + for (let y = 0, key, res; y < tag.length; y++) { + key = tag[y]; + res = this.tagindex[key]; + len = res && res.length; + + if (len) { + count++; + arr[arr.length] = bool ? [res] : res; + } + } + + if (count) { + if (bool) { + res = intersect(arr, limit || 100, offset || 0); + } else { + res = intersect_union(res, arr); + } + + len = res.length; + } + } + + if (len) { + result_field[count] = key; + result[count++] = res; + } else if (bool) { + return []; + } + } - // prepare for intersection + if (promises) { + const self = this; + + // anyone knows a better workaround of optionally having async promises? + // the promise.all() needs to be wrapped into additional promise, + // otherwise the recursive callback wouldn't run before return + + return new Promise(function (resolve) { + Promise.all(promises).then(function (result) { + resolve(self.search(query, limit, options, result)); + }); + }); + } - arr[0] = [res]; - } + if (!count) { + // fast path "not found" - for(let y = 0, key, res; y < tag.length; y++){ + return []; + } - key = tag[y]; - res = this.tagindex[key]; - len = res && res.length; + if (pluck && (!enrich || !this.store)) { + // fast path optimization - if(len){ + return result[0]; + } - count++; - arr[arr.length] = bool ? [res] : res; - } - } + for (let i = 0, res; i < result_field.length; i++) { + res = result[i]; - if(count){ - - if(bool){ - - res = intersect(arr, limit || 100, offset || 0); - } - else{ - - res = intersect_union(res, arr); - } - - len = res.length; - } - } - - if(len){ - - result_field[count] = key; - result[count++] = res; - } - else if(bool){ - - return []; - } - } - - if(promises){ - - const self = this; - - // anyone knows a better workaround of optionally having async promises? - // the promise.all() needs to be wrapped into additional promise, - // otherwise the recursive callback wouldn't run before return - - return new Promise(function(resolve){ - - Promise.all(promises).then(function(result){ - - resolve(self.search(query, limit, options, result)); - }); - }); - } - - if(!count){ - - // fast path "not found" - - return []; - } - - if(pluck && (!enrich || !this.store)){ - - // fast path optimization - - return result[0]; - } - - for(let i = 0, res; i < result_field.length; i++){ - - res = result[i]; - - if(res.length){ - - if(enrich){ - - res = apply_enrich.call(this, res); - } - } - - if(pluck){ - - return res; - } - - result[i] = { - - "field": result_field[i], - "result": res - }; - } - - return result; + if (res.length) { + if (enrich) { + res = apply_enrich.call(this, res); + } + } + + if (pluck) { + return res; + } + + result[i] = { + field: result_field[i], + result: res, + }; + } + + return result; }; /** * @this Document */ -function get_tag(key, limit, offset, enrich){ - - let res = this.tagindex[key]; - let len = res && (res.length - offset); - - if(len && (len > 0)){ - - if((len > limit) || offset){ - - res = res.slice(offset, offset + limit); - } +function get_tag(key, limit, offset, enrich) { + let res = this.tagindex[key]; + let len = res && res.length - offset; - if(enrich){ + if (len && len > 0) { + if (len > limit || offset) { + res = res.slice(offset, offset + limit); + } - res = apply_enrich.call(this, res); - } + if (enrich) { + res = apply_enrich.call(this, res); + } - return { - - "tag": key, - "result": res - }; - } + return { + tag: key, + result: res, + }; + } } /** * @this Document */ -function apply_enrich(res){ - - const arr = new Array(res.length); - - for(let x = 0, id; x < res.length; x++){ +function apply_enrich(res) { + const arr = new Array(res.length); - id = res[x]; + for (let x = 0, id; x < res.length; x++) { + id = res[x]; - arr[x] = { + arr[x] = { + id: id, + doc: this.store[id], + }; + } - "id": id, - "doc": this.store[id] - }; - } - - return arr; + return arr; } -Document.prototype.contain = function(id){ - - return !!this.register[id]; +Document.prototype.contain = function (id) { + return !!this.register[id]; }; -if(SUPPORT_STORE){ - - Document.prototype.get = function(id){ +if (SUPPORT_STORE) { + Document.prototype.get = function (id) { + return this.store[id]; + }; - return this.store[id]; - }; - - Document.prototype.set = function(id, data){ - - this.store[id] = data; - return this; - }; + Document.prototype.set = function (id, data) { + this.store[id] = data; + return this; + }; } -if(SUPPORT_CACHE){ - - Document.prototype.searchCache = searchCache; +if (SUPPORT_CACHE) { + Document.prototype.searchCache = searchCache; } -if(SUPPORT_SERIALIZE){ - - Document.prototype.export = exportDocument; - Document.prototype.import = importDocument; +if (SUPPORT_SERIALIZE) { + Document.prototype.export = exportDocument; + Document.prototype.import = importDocument; } -if(SUPPORT_ASYNC){ - - apply_async(Document.prototype); +if (SUPPORT_ASYNC) { + apply_async(Document.prototype); } diff --git a/src/engine.js b/src/engine.js index 57da76b..e69833d 100644 --- a/src/engine.js +++ b/src/engine.js @@ -1,47 +1,34 @@ -import { DEBUG, SUPPORT_ASYNC, SUPPORT_CACHE } from "./config"; -import { searchCache } from "./cache"; - -/** - * @constructor - * @abstract - */ - -function Engine(index){ - - if(DEBUG){ - - //if(this.constructor === Engine){ - if(this instanceof Engine){ - - throw new Error("Can't instantiate abstract class!"); - } - } - - if(SUPPORT_CACHE){ - - index.prototype.searchCache = searchCache; - } - - if(SUPPORT_ASYNC){ - - index.prototype.addAsync = addAsync; - index.prototype.appendAsync = appendAsync; - index.prototype.searchAsync = searchAsync; - index.prototype.updateAsync = updateAsync; - index.prototype.removeAsync = removeAsync; - } +import { DEBUG, SUPPORT_ASYNC, SUPPORT_CACHE } from './config'; +import { searchCache } from './cache'; + +function Engine(index) { + if (DEBUG) { + if (this instanceof Engine) { + throw new Error("Can't instantiate abstract class!"); + } + } + + if (SUPPORT_CACHE) { + index.prototype.searchCache = searchCache; + } + + if (SUPPORT_ASYNC) { + index.prototype.addAsync = addAsync; + index.prototype.appendAsync = appendAsync; + index.prototype.searchAsync = searchAsync; + index.prototype.updateAsync = updateAsync; + index.prototype.removeAsync = removeAsync; + } } -if(SUPPORT_CACHE){ - - Engine.prototype.searchCache = searchCache; +if (SUPPORT_CACHE) { + Engine.prototype.searchCache = searchCache; } -if(SUPPORT_ASYNC){ - - Engine.prototype.addAsync = addAsync; - Engine.prototype.appendAsync = appendAsync; - Engine.prototype.searchAsync = searchAsync; - Engine.prototype.updateAsync = updateAsync; - Engine.prototype.removeAsync = removeAsync; -} \ No newline at end of file +if (SUPPORT_ASYNC) { + Engine.prototype.addAsync = addAsync; + Engine.prototype.appendAsync = appendAsync; + Engine.prototype.searchAsync = searchAsync; + Engine.prototype.updateAsync = updateAsync; + Engine.prototype.removeAsync = removeAsync; +} diff --git a/src/global.js b/src/global.js index 9635704..344acba 100644 --- a/src/global.js +++ b/src/global.js @@ -1,22 +1,21 @@ +/** @type {Record} */ export const global_lang = {}; +/** @type {Record} */ export const global_charset = {}; /** - * @param {!string} name - * @param {Object} charset + * @param {string} name + * @param {object} charset */ - -export function registerCharset(name, charset){ - - global_charset[name] = charset; +export function registerCharset(name, charset) { + global_charset[name] = charset; } /** - * @param {!string} name - * @param {Object} lang + * @param {string} name + * @param {object} lang */ -export function registerLanguage(name, lang){ - - global_lang[name] = lang; +export function registerLanguage(name, lang) { + global_lang[name] = lang; } diff --git a/src/index.js b/src/index.js index 155b3ef..f530876 100644 --- a/src/index.js +++ b/src/index.js @@ -7,276 +7,590 @@ */ import { - - SUPPORT_ENCODER, - SUPPORT_CACHE, - SUPPORT_ASYNC, - SUPPORT_SUGGESTION, - SUPPORT_SERIALIZE - -} from "./config.js"; - -import { IndexInterface } from "./type.js"; -import { encode as default_encoder } from "./lang/latin/default.js"; -import { create_object, create_object_array, concat, sort_by_length_down, is_array, is_string, is_object, parse_option } from "./common.js"; -import { pipeline, init_stemmer_or_matcher, init_filter } from "./lang.js"; -import { global_lang, global_charset } from "./global.js"; -import apply_async from "./async.js"; -import { intersect } from "./intersect.js"; -import Cache, { searchCache } from "./cache.js"; -import apply_preset from "./preset.js"; -import { exportIndex, importIndex } from "./serialize.js"; - -/** - * @constructor - * @implements IndexInterface - * @param {Object=} options - * @param {Object=} _register - * @return {Index} - */ - -function Index(options, _register){ - - if(!(this instanceof Index)) { - - return new Index(options); - } - - let charset, lang, tmp; - - if(options){ - - if(SUPPORT_ENCODER){ - - options = apply_preset(options); - } - - charset = options["charset"]; - lang = options["lang"]; - - if(is_string(charset)){ - - if(charset.indexOf(":") === -1){ - - charset += ":default"; - } - - charset = global_charset[charset]; - } - - if(is_string(lang)){ - - lang = global_lang[lang]; - } - } - else{ - - options = {}; - } - - let resolution, optimize, context = options["context"] || {}; - - this.encode = options["encode"] || (charset && charset.encode) || default_encoder; - this.register = _register || create_object(); - this.resolution = resolution = options["resolution"] || 9; - this.tokenize = tmp = (charset && charset.tokenize) || options["tokenize"] || "strict"; - this.depth = (tmp === "strict") && context["depth"]; - this.bidirectional = parse_option(context["bidirectional"], true); - this.optimize = optimize = parse_option(options["optimize"], true); - this.fastupdate = parse_option(options["fastupdate"], true); - this.minlength = options["minlength"] || 1; - this.boost = options["boost"]; - - // when not using the memory strategy the score array should not pre-allocated to its full length - - this.map = optimize ? create_object_array(resolution) : create_object(); - this.resolution_ctx = resolution = context["resolution"] || 1; - this.ctx = optimize ? create_object_array(resolution) : create_object(); - this.rtl = (charset && charset.rtl) || options["rtl"]; - this.matcher = (tmp = options["matcher"] || (lang && lang.matcher)) && init_stemmer_or_matcher(tmp, false); - this.stemmer = (tmp = options["stemmer"] || (lang && lang.stemmer)) && init_stemmer_or_matcher(tmp, true); - this.filter = (tmp = options["filter"] || (lang && lang.filter)) && init_filter(tmp); - - if(SUPPORT_CACHE){ - - this.cache = (tmp = options["cache"]) && new Cache(tmp); - } + SUPPORT_ENCODER, + SUPPORT_CACHE, + SUPPORT_ASYNC, + SUPPORT_SUGGESTION, + SUPPORT_SERIALIZE, +} from './config.js'; + +import { encode as default_encoder } from './lang/latin/default.js'; +import { + create_object, + create_object_array, + concat, + sort_by_length_down, + is_array, + is_string, + is_object, + parse_option, +} from './common.js'; +import { init_stemmer_or_matcher, init_filter } from './lang.js'; +import { global_lang, global_charset } from './global.js'; +import apply_async from './async.js'; +import { intersect } from './intersect.js'; +import Cache, { searchCache } from './cache.js'; +import apply_preset from './preset.js'; +import { exportIndex, importIndex } from './serialize.js'; + +class Index { + /** @type {{ tokenize?: string; rtl?: boolean; }} */ + charset = {}; + + /** @type {any} */ + encode = default_encoder; + + /** @type {{ matcher?: any; stemmer?: any; filter?: any }} */ + lang = {}; + + minlength = 1; + + resolution = 9; + + /** + * @param {import('../index').CreateOptions} options + * @param {boolean} [_register] + * @returns + */ + constructor(options = {}, _register) { + if (!(this instanceof Index)) { + return new Index(options); + } + + let charset = options['charset']; + let lang = options['lang']; + let tmp; + + if (SUPPORT_ENCODER) { + options = apply_preset(options); + } + + if (charset && is_string(charset)) { + if (charset.indexOf(':') === -1) { + charset += ':default'; + } + + this.charset = global_charset[charset]; + } + + if (lang && is_string(lang)) { + this.lang = global_lang[lang]; + } + + let resolution, + optimize, + context = options['context'] || {}; + + this.encode = options['encode'] || default_encoder; + this.register = _register || create_object(); + this.resolution = resolution = options['resolution'] || 9; + this.tokenize = tmp = + (this.charset && this.charset.tokenize) || options['tokenize'] || 'strict'; + this.depth = tmp === 'strict' && context['depth']; + this.bidirectional = parse_option(context['bidirectional'], true); + this.optimize = optimize = parse_option(options['optimize'], true); + this.fastupdate = parse_option(options['fastupdate'], true); + this.minlength = options['minlength'] || 1; + this.boost = options['boost']; + + // when not using the memory strategy the score array should not pre-allocated to its full length + + this.map = optimize ? create_object_array(resolution) : create_object(); + this.resolution_ctx = resolution = context['resolution'] || 1; + this.ctx = optimize ? create_object_array(resolution) : create_object(); + this.rtl = (this.charset && this.charset.rtl) || options['rtl']; + this.matcher = + (tmp = options['matcher'] || (this.lang && this.lang.matcher)) && + init_stemmer_or_matcher(tmp, false); + this.stemmer = + (tmp = options['stemmer'] || (this.lang && this.lang.stemmer)) && + init_stemmer_or_matcher(tmp, true); + this.filter = (tmp = options['filter'] || (this.lang && this.lang.filter)) && init_filter(tmp); + + if (SUPPORT_CACHE) { + this.cache = (tmp = options['cache']) && new Cache(tmp); + } + } + + /** + * @param {number} id + * @param {string} content + * @param {*} [_append] + * @param {*} [_skip_update] + * @returns {this} + */ + add(id, content, _append, _skip_update) { + if (content && (id || id === 0)) { + if (!_skip_update && !_append && this.register[id]) { + return this.update(id, content); + } + + content = this.encode('' + content); + const length = content.length; + + if (length) { + // check context dupes to skip all contextual redundancy along a document + + const dupes_ctx = create_object(); + const dupes = create_object(); + const depth = this.depth; + const resolution = this.resolution; + + for (let i = 0; i < length; i++) { + let term = content[this.rtl ? length - 1 - i : i]; + let term_length = term.length; + + // skip dupes will break the context chain + + if (term && term_length >= this.minlength && (depth || !dupes[term])) { + let score = get_score(resolution, length, i); + let token = ''; + + switch (this.tokenize) { + case 'full': + if (term_length > 2) { + for (let x = 0; x < term_length; x++) { + for (let y = term_length; y > x; y--) { + if (y - x >= this.minlength) { + const partial_score = get_score(resolution, length, i, term_length, x); + token = term.substring(x, y); + this.push_index(dupes, token, partial_score, id, _append); + } + } + } + + break; + } + + // fallthrough to next case when term length < 3 + + case 'reverse': + // skip last round (this token exist already in "forward") + + if (term_length > 1) { + for (let x = term_length - 1; x > 0; x--) { + token = term[x] + token; + + if (token.length >= this.minlength) { + const partial_score = get_score(resolution, length, i, term_length, x); + this.push_index(dupes, token, partial_score, id, _append); + } + } + + token = ''; + } + + // fallthrough to next case to apply forward also + + case 'forward': + if (term_length > 1) { + for (let x = 0; x < term_length; x++) { + token += term[x]; + + if (token.length >= this.minlength) { + this.push_index(dupes, token, score, id, _append); + } + } + + break; + } + + // fallthrough to next case when token has a length of 1 + + default: + // case "strict": + + if (this.boost) { + score = Math.min((score / this.boost(content, term, i)) | 0, resolution - 1); + } + + this.push_index(dupes, term, score, id, _append); + + // context is just supported by tokenizer "strict" + + if (depth) { + if (length > 1 && i < length - 1) { + // check inner dupes to skip repeating words in the current context + + const dupes_inner = create_object(); + const resolution = this.resolution_ctx; + const keyword = term; + const size = Math.min(depth + 1, length - i); + + dupes_inner[keyword] = 1; + + for (let x = 1; x < size; x++) { + term = content[this.rtl ? length - 1 - i - x : i + x]; + + if (term && term.length >= this.minlength && !dupes_inner[term]) { + dupes_inner[term] = 1; + + const context_score = get_score( + resolution + (length / 2 > resolution ? 0 : 1), + length, + i, + size - 1, + x - 1 + ); + const swap = this.bidirectional && term > keyword; + this.push_index( + dupes_ctx, + swap ? keyword : term, + context_score, + id, + _append, + swap ? term : keyword + ); + } + } + } + } + } + } + } + + this.fastupdate || (this.register[id] = 1); + } + } + + return this; + } + + /** + * + * @param {number} id + * @param {string} content + * @returns {this} + */ + append(id, content) { + return this.add(id, content, true); + } + + /** + * + * @param {number} id + * @returns {boolean} + */ + contain(id) { + return !!this.register[id]; + } + + /** + * + * @param {number} id + * @param {boolean} [_skip_deletion] + * @returns {this} + */ + remove(id, _skip_deletion) { + const refs = this.register[id]; + + if (refs) { + if (this.fastupdate) { + // fast updates performs really fast but did not fully cleanup the key entries + + for (let i = 0, tmp; i < refs.length; i++) { + tmp = refs[i]; + tmp.splice(tmp.indexOf(id), 1); + } + } else { + remove_index(this.map, id, this.resolution, this.optimize); + + if (this.depth) { + remove_index(this.ctx, id, this.resolution_ctx, this.optimize); + } + } + + _skip_deletion || delete this.register[id]; + + if (SUPPORT_CACHE && this.cache) { + this.cache.del(id); + } + } + + return this; + } + + /** + * @param {string} query + * @param {object} limit + * @param {object} options + */ + search(query, limit, options) { + if (!options) { + if (!limit && is_object(query)) { + options = /** @type {Object} */ (query); + query = options['query']; + } else if (is_object(limit)) { + options = /** @type {Object} */ (limit); + } + } + + let result = []; + let length; + let context, + suggest, + offset = 0; + + if (options) { + query = options['query'] || query; + limit = options['limit']; + offset = options['offset'] || 0; + context = options['context']; + suggest = SUPPORT_SUGGESTION && options['suggest']; + } + + if (query) { + query = /** @type {Array} */ (this.encode('' + query)); + length = query.length; + + // TODO: solve this in one single loop below + + if (length > 1) { + const dupes = create_object(); + const query_new = []; + + for (let i = 0, count = 0, term; i < length; i++) { + term = query[i]; + + if (term && term.length >= this.minlength && !dupes[term]) { + // this fast path can just apply when not in memory-optimized mode + + if (!this.optimize && !suggest && !this.map[term]) { + // fast path "not found" + + return result; + } else { + query_new[count++] = term; + dupes[term] = 1; + } + } + } + + query = query_new; + length = query.length; + } + } + + if (!length) { + return result; + } + + limit || (limit = 100); + + let depth = this.depth && length > 1 && context !== false; + let index = 0, + keyword; + + if (depth) { + keyword = query[0]; + index = 1; + } else { + if (length > 1) { + query.sort(sort_by_length_down); + } + } + + for (let arr, term; index < length; index++) { + term = query[index]; + + // console.log(keyword); + // console.log(term); + // console.log(""); + + if (depth) { + arr = this.add_result(result, suggest, limit, offset, length === 2, term, keyword); + + // console.log(arr); + // console.log(result); + + // when suggestion enabled just forward keyword if term was found + // as long as the result is empty forward the pointer also + + if (!suggest || arr !== false || !result.length) { + keyword = term; + } + } else { + arr = this.add_result(result, suggest, limit, offset, length === 1, term); + } + + if (arr) { + return /** @type {Array} */ (arr); + } + + // apply suggestions on last loop or fallback + + if (suggest && index === length - 1) { + let length = result.length; + + if (!length) { + if (depth) { + // fallback to non-contextual search when no result was found + + depth = 0; + index = -1; + + continue; + } + + return result; + } else if (length === 1) { + // fast path optimization + + return single_result(result[0], limit, offset); + } + } + } + + return intersect(result, limit, offset, suggest); + } + + /** + * + * @param {number} id + * @param {string} content + * @returns + */ + update(id, content) { + return this.remove(id).add(id, content); + } + + /** + * Returns an array when the result is done (to stop the process immediately), + * returns false when suggestions is enabled and no result was found, + * or returns nothing when a set was pushed successfully to the results + * + * @private + * @template T + * @param {Array} result + * @param {Array} suggest + * @param {number} limit + * @param {number} offset + * @param {boolean} single_term + * @param {string} term + * @param {string=} keyword + * @return {Array> | boolean | undefined} + */ + + add_result(result, suggest, limit, offset, single_term, term, keyword) { + let word_arr = []; + let arr = keyword ? this.ctx : this.map; + + if (!this.optimize) { + arr = get_array(arr, term, keyword, this.bidirectional); + } + + if (arr) { + let count = 0; + const arr_len = Math.min(arr.length, keyword ? this.resolution_ctx : this.resolution); + + // relevance: + for (let x = 0, size = 0, tmp, len; x < arr_len; x++) { + tmp = arr[x]; + + if (tmp) { + if (this.optimize) { + tmp = get_array(tmp, term, keyword, this.bidirectional); + } + + if (offset) { + if (tmp && single_term) { + len = tmp.length; + + if (len <= offset) { + offset -= len; + tmp = null; + } else { + tmp = tmp.slice(offset); + offset = 0; + } + } + } + + if (tmp) { + // keep score (sparse array): + //word_arr[x] = tmp; + + // simplified score order: + word_arr[count++] = tmp; + + if (single_term) { + size += tmp.length; + + if (size >= limit) { + // fast path optimization + + break; + } + } + } + } + } + + if (count) { + if (single_term) { + // fast path optimization + // offset was already applied at this point + + return single_result(word_arr, limit, 0); + } + + result[result.length] = word_arr; + return; + } + } + + // return an empty array will stop the loop, + // to prevent stop when using suggestions return a false value + + return !suggest && word_arr; + } + + /** + * @private + * @param {*} dupes + * @param {*} value + * @param {*} score + * @param {*} id + * @param {boolean} [append] + * @param {string} [keyword] + */ + push_index(dupes, value, score, id, append, keyword) { + let arr = keyword ? this.ctx : this.map; + + if (!dupes[value] || (keyword && !dupes[value][keyword])) { + if (this.optimize) { + arr = arr[score]; + } + + if (keyword) { + dupes = dupes[value] || (dupes[value] = create_object()); + dupes[keyword] = 1; + + arr = arr[keyword] || (arr[keyword] = create_object()); + } else { + dupes[value] = 1; + } + + arr = arr[value] || (arr[value] = []); + + if (!this.optimize) { + arr = arr[score] || (arr[score] = []); + } + + if (!append || !arr.includes(id)) { + arr[arr.length] = id; + + // add a reference to the register for fast updates + + if (this.fastupdate) { + const tmp = this.register[id] || (this.register[id] = []); + tmp[tmp.length] = arr; + } + } + } + } } -export default Index; - -//Index.prototype.pipeline = pipeline; - -/** - * @param {!number|string} id - * @param {!string} content - */ - -Index.prototype.append = function(id, content){ - - return this.add(id, content, true); -}; - -// TODO: -// string + number as text -// boolean, null, undefined as ? - -/** - * @param {!number|string} id - * @param {!string} content - * @param {boolean=} _append - * @param {boolean=} _skip_update - */ - -Index.prototype.add = function(id, content, _append, _skip_update){ - - if(content && (id || (id === 0))){ - - if(!_skip_update && !_append && this.register[id]){ - - return this.update(id, content); - } - - content = this.encode("" + content); - const length = content.length; - - if(length){ - - // check context dupes to skip all contextual redundancy along a document - - const dupes_ctx = create_object(); - const dupes = create_object(); - const depth = this.depth; - const resolution = this.resolution; - - for(let i = 0; i < length; i++){ - - let term = content[this.rtl ? length - 1 - i : i]; - let term_length = term.length; - - // skip dupes will break the context chain - - if(term && (term_length >= this.minlength) && (depth || !dupes[term])){ - - let score = get_score(resolution, length, i); - let token = ""; - - switch(this.tokenize){ - - case "full": - - if(term_length > 2){ - - for(let x = 0; x < term_length; x++){ - - for(let y = term_length; y > x; y--){ - - if((y - x) >= this.minlength){ - - const partial_score = get_score(resolution, length, i, term_length, x); - token = term.substring(x, y); - this.push_index(dupes, token, partial_score, id, _append); - } - } - } - - break; - } - - // fallthrough to next case when term length < 3 - - case "reverse": - - // skip last round (this token exist already in "forward") - - if(term_length > 1){ - - for(let x = term_length - 1; x > 0; x--){ - - token = term[x] + token; - - if(token.length >= this.minlength){ - - const partial_score = get_score(resolution, length, i, term_length, x); - this.push_index(dupes, token, partial_score, id, _append); - } - } - - token = ""; - } - - // fallthrough to next case to apply forward also - - case "forward": - - if(term_length > 1){ - - for(let x = 0; x < term_length; x++){ - - token += term[x]; - - if(token.length >= this.minlength){ - - this.push_index(dupes, token, score, id, _append); - } - } - - break; - } - - // fallthrough to next case when token has a length of 1 - - default: - // case "strict": - - if(this.boost){ - - score = Math.min((score / this.boost(content, term, i)) | 0, resolution - 1); - } - - this.push_index(dupes, term, score, id, _append); - - // context is just supported by tokenizer "strict" - - if(depth){ - - if((length > 1) && (i < (length - 1))){ - - // check inner dupes to skip repeating words in the current context - - const dupes_inner = create_object(); - const resolution = this.resolution_ctx; - const keyword = term; - const size = Math.min(depth + 1, length - i); - - dupes_inner[keyword] = 1; - - for(let x = 1; x < size; x++){ - - term = content[this.rtl ? length - 1 - i - x : i + x]; - - if(term && (term.length >= this.minlength) && !dupes_inner[term]){ - - dupes_inner[term] = 1; - - const context_score = get_score(resolution + ((length / 2) > resolution ? 0 : 1), length, i, size - 1, x - 1); - const swap = this.bidirectional && (term > keyword); - this.push_index(dupes_ctx, swap ? keyword : term, context_score, id, _append, swap ? term : keyword); - } - } - } - } - } - } - } - - this.fastupdate || (this.register[id] = 1); - } - } - - return this; -}; - /** * @param {number} resolution * @param {number} length @@ -286,450 +600,59 @@ Index.prototype.add = function(id, content, _append, _skip_update){ * @returns {number} */ -function get_score(resolution, length, i, term_length, x){ - - // console.log("resolution", resolution); - // console.log("length", length); - // console.log("term_length", term_length); - // console.log("i", i); - // console.log("x", x); - // console.log((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1); - - // the first resolution slot is reserved for the best match, - // when a query matches the first word(s). - - // also to stretch score to the whole range of resolution, the - // calculation is shift by one and cut the floating point. - // this needs the resolution "1" to be handled additionally. - - // do not stretch the resolution more than the term length will - // improve performance and memory, also it improves scoring in - // most cases between a short document and a long document - - return i && (resolution > 1) ? ( - - (length + (term_length || 0)) <= resolution ? - - i + (x || 0) - : - ((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1) | 0 - ): - 0; +function get_score(resolution, length, i, term_length, x) { + // console.log("resolution", resolution); + // console.log("length", length); + // console.log("term_length", term_length); + // console.log("i", i); + // console.log("x", x); + // console.log((resolution - 1) / (length + (term_length || 0)) * (i + (x || 0)) + 1); + + // the first resolution slot is reserved for the best match, + // when a query matches the first word(s). + + // also to stretch score to the whole range of resolution, the + // calculation is shift by one and cut the floating point. + // this needs the resolution "1" to be handled additionally. + + // do not stretch the resolution more than the term length will + // improve performance and memory, also it improves scoring in + // most cases between a short document and a long document + + return i && resolution > 1 + ? length + (term_length || 0) <= resolution + ? i + (x || 0) + : (((resolution - 1) / (length + (term_length || 0))) * (i + (x || 0)) + 1) | 0 + : 0; } -/** - * @private - * @param dupes - * @param value - * @param score - * @param id - * @param {boolean=} append - * @param {string=} keyword - */ - -Index.prototype.push_index = function(dupes, value, score, id, append, keyword){ - - let arr = keyword ? this.ctx : this.map; - - if(!dupes[value] || (keyword && !dupes[value][keyword])){ - - if(this.optimize){ - - arr = arr[score]; - } - - if(keyword){ - - dupes = dupes[value] || (dupes[value] = create_object()); - dupes[keyword] = 1; - - arr = arr[keyword] || (arr[keyword] = create_object()); - } - else{ - - dupes[value] = 1; - } - - arr = arr[value] || (arr[value] = []); - - if(!this.optimize){ - - arr = arr[score] || (arr[score] = []); - } - - if(!append || !arr.includes(id)){ - - arr[arr.length] = id; - - // add a reference to the register for fast updates +function single_result(result, limit, offset) { + if (result.length === 1) { + result = result[0]; + } else { + result = concat(result); + } - if(this.fastupdate){ - - const tmp = this.register[id] || (this.register[id] = []); - tmp[tmp.length] = arr; - } - } - } + return offset || result.length > limit ? result.slice(offset, offset + limit) : result; } -/** - * @param {string|Object} query - * @param {number|Object=} limit - * @param {Object=} options - * @returns {Array} - */ - -Index.prototype.search = function(query, limit, options){ - - if(!options){ - - if(!limit && is_object(query)){ - - options = /** @type {Object} */ (query); - query = options["query"]; - } - else if(is_object(limit)){ - - options = /** @type {Object} */ (limit); - } - } - - let result = []; - let length; - let context, suggest, offset = 0; - - if(options){ - - query = options["query"] || query; - limit = options["limit"]; - offset = options["offset"] || 0; - context = options["context"]; - suggest = SUPPORT_SUGGESTION && options["suggest"]; - } - - if(query){ - - query = /** @type {Array} */ (this.encode("" + query)); - length = query.length; - - // TODO: solve this in one single loop below - - if(length > 1){ - - const dupes = create_object(); - const query_new = []; - - for(let i = 0, count = 0, term; i < length; i++){ +function get_array(arr, term, keyword, bidirectional) { + if (keyword) { + // the frequency of the starting letter is slightly less + // on the last half of the alphabet (m-z) in almost every latin language, + // so we sort downwards (https://en.wikipedia.org/wiki/Letter_frequency) - term = query[i]; + const swap = bidirectional && term > keyword; - if(term && (term.length >= this.minlength) && !dupes[term]){ + arr = arr[swap ? term : keyword]; + arr = arr && arr[swap ? keyword : term]; + } else { + arr = arr[term]; + } - // this fast path can just apply when not in memory-optimized mode - - if(!this.optimize && !suggest && !this.map[term]){ - - // fast path "not found" - - return result; - } - else{ - - query_new[count++] = term; - dupes[term] = 1; - } - } - } - - query = query_new; - length = query.length; - } - } - - if(!length){ - - return result; - } - - limit || (limit = 100); - - let depth = this.depth && (length > 1) && (context !== false); - let index = 0, keyword; - - if(depth){ - - keyword = query[0]; - index = 1; - } - else{ - - if(length > 1){ - - query.sort(sort_by_length_down); - } - } - - for(let arr, term; index < length; index++){ - - term = query[index]; - - // console.log(keyword); - // console.log(term); - // console.log(""); - - if(depth){ - - arr = this.add_result(result, suggest, limit, offset, length === 2, term, keyword); - - // console.log(arr); - // console.log(result); - - // when suggestion enabled just forward keyword if term was found - // as long as the result is empty forward the pointer also - - if(!suggest || (arr !== false) || !result.length){ - - keyword = term; - } - } - else{ - - arr = this.add_result(result, suggest, limit, offset, length === 1, term); - } - - if(arr){ - - return /** @type {Array} */ (arr); - } - - // apply suggestions on last loop or fallback - - if(suggest && (index === length - 1)){ - - let length = result.length; - - if(!length){ - - if(depth){ - - // fallback to non-contextual search when no result was found - - depth = 0; - index = -1; - - continue; - } - - return result; - } - else if(length === 1){ - - // fast path optimization - - return single_result(result[0], limit, offset); - } - } - } - - return intersect(result, limit, offset, suggest); -}; - -/** - * Returns an array when the result is done (to stop the process immediately), - * returns false when suggestions is enabled and no result was found, - * or returns nothing when a set was pushed successfully to the results - * - * @private - * @param {Array} result - * @param {Array} suggest - * @param {number} limit - * @param {number} offset - * @param {boolean} single_term - * @param {string} term - * @param {string=} keyword - * @return {Array>|boolean|undefined} - */ - -Index.prototype.add_result = function(result, suggest, limit, offset, single_term, term, keyword){ - - let word_arr = []; - let arr = keyword ? this.ctx : this.map; - - if(!this.optimize){ - - arr = get_array(arr, term, keyword, this.bidirectional); - } - - if(arr){ - - let count = 0; - const arr_len = Math.min(arr.length, keyword ? this.resolution_ctx : this.resolution); - - // relevance: - for(let x = 0, size = 0, tmp, len; x < arr_len; x++){ - - tmp = arr[x]; - - if(tmp){ - - if(this.optimize){ - - tmp = get_array(tmp, term, keyword, this.bidirectional); - } - - if(offset){ - - if(tmp && single_term){ - - len = tmp.length; - - if(len <= offset){ - - offset -= len; - tmp = null; - } - else{ - - tmp = tmp.slice(offset); - offset = 0; - } - } - } - - if(tmp){ - - // keep score (sparse array): - //word_arr[x] = tmp; - - // simplified score order: - word_arr[count++] = tmp; - - if(single_term){ - - size += tmp.length; - - if(size >= limit){ - - // fast path optimization - - break; - } - } - } - } - } - - if(count){ - - if(single_term){ - - // fast path optimization - // offset was already applied at this point - - return single_result(word_arr, limit, 0); - } - - result[result.length] = word_arr; - return; - } - } - - // return an empty array will stop the loop, - // to prevent stop when using suggestions return a false value - - return !suggest && word_arr; -}; - -function single_result(result, limit, offset){ - - if(result.length === 1){ - - result = result[0]; - } - else{ - - result = concat(result); - } - - return offset || (result.length > limit) ? - - result.slice(offset, offset + limit) - : - result; -} - -function get_array(arr, term, keyword, bidirectional){ - - if(keyword){ - - // the frequency of the starting letter is slightly less - // on the last half of the alphabet (m-z) in almost every latin language, - // so we sort downwards (https://en.wikipedia.org/wiki/Letter_frequency) - - const swap = bidirectional && (term > keyword); - - arr = arr[swap ? term : keyword]; - arr = arr && arr[swap ? keyword : term]; - } - else{ - - arr = arr[term]; - } - - return arr; + return arr; } -Index.prototype.contain = function(id){ - - return !!this.register[id]; -}; - -Index.prototype.update = function(id, content){ - - return this.remove(id).add(id, content); -}; - -/** - * @param {boolean=} _skip_deletion - */ - -Index.prototype.remove = function(id, _skip_deletion){ - - const refs = this.register[id]; - - if(refs){ - - if(this.fastupdate){ - - // fast updates performs really fast but did not fully cleanup the key entries - - for(let i = 0, tmp; i < refs.length; i++){ - - tmp = refs[i]; - tmp.splice(tmp.indexOf(id), 1); - } - } - else{ - - remove_index(this.map, id, this.resolution, this.optimize); - - if(this.depth){ - - remove_index(this.ctx, id, this.resolution_ctx, this.optimize); - } - } - - _skip_deletion || delete this.register[id]; - - if(SUPPORT_CACHE && this.cache){ - - this.cache.del(id); - } - } - - return this; -}; - /** * @param map * @param id @@ -739,83 +662,66 @@ Index.prototype.remove = function(id, _skip_deletion){ * @return {number} */ -function remove_index(map, id, res, optimize, resolution){ - - let count = 0; - - if(is_array(map)){ - - // the first array is the score array in both strategies - - if(!resolution){ - - resolution = Math.min(map.length, res); - - for(let x = 0, arr; x < resolution; x++){ - - arr = map[x]; - - if(arr){ - - count = remove_index(arr, id, res, optimize, resolution); - - if(!optimize && !count){ - - // when not memory optimized the score index should removed - - delete map[x]; - } - } - } - } - else{ - - const pos = map.indexOf(id); - - if(pos !== -1){ - - // fast path, when length is 1 or lower then the whole field gets deleted - - if(map.length > 1){ - - map.splice(pos, 1); - count++; - } - } - else{ - - count++; - } - } - } - else{ - - for(let key in map){ - - count = remove_index(map[key], id, res, optimize, resolution); - - if(!count){ - - delete map[key]; - } - } - } - - return count; +function remove_index(map, id, res, optimize, resolution) { + let count = 0; + + if (is_array(map)) { + // the first array is the score array in both strategies + + if (!resolution) { + resolution = Math.min(map.length, res); + + for (let x = 0, arr; x < resolution; x++) { + arr = map[x]; + + if (arr) { + count = remove_index(arr, id, res, optimize, resolution); + + if (!optimize && !count) { + // when not memory optimized the score index should removed + + delete map[x]; + } + } + } + } else { + const pos = map.indexOf(id); + + if (pos !== -1) { + // fast path, when length is 1 or lower then the whole field gets deleted + + if (map.length > 1) { + map.splice(pos, 1); + count++; + } + } else { + count++; + } + } + } else { + for (let key in map) { + count = remove_index(map[key], id, res, optimize, resolution); + + if (!count) { + delete map[key]; + } + } + } + + return count; } -if(SUPPORT_CACHE){ - - Index.prototype.searchCache = searchCache; +if (SUPPORT_CACHE) { + Index.prototype.searchCache = searchCache; } -if(SUPPORT_SERIALIZE){ - - Index.prototype.export = exportIndex; - Index.prototype.import = importIndex; +if (SUPPORT_SERIALIZE) { + Index.prototype.export = exportIndex; + Index.prototype.import = importIndex; } -if(SUPPORT_ASYNC){ - - apply_async(Index.prototype); +if (SUPPORT_ASYNC) { + apply_async(Index.prototype); } + +export default Index; diff --git a/src/intersect.js b/src/intersect.js index 16828e6..31a85d9 100644 --- a/src/intersect.js +++ b/src/intersect.js @@ -1,4 +1,4 @@ -import { create_object, concat } from "./common.js"; +import { create_object } from './common.js'; /** * Implementation based on Array.includes() provides better performance, @@ -198,163 +198,135 @@ import { create_object, concat } from "./common.js"; * Implementation based on Object[key] provides better suggestions * capabilities and has less performance scaling issues on large indexes. * + * @template T * @param arrays * @param limit * @param offset - * @param {boolean|Array=} suggest - * @returns {Array} + * @param {boolean | Array} suggest + * @returns {Array} */ export function intersect(arrays, limit, offset, suggest) { + const length = arrays.length; + let result = []; + let check; + let check_suggest; + let size = 0; - const length = arrays.length; - let result = []; - let check; - let check_suggest; - let size = 0; - - if(suggest){ - - suggest = []; - } - - // process terms in reversed order often has advantage for the fast path "end reached". - // also a reversed order prioritize the order of words from a query. - - for(let x = length - 1; x >= 0; x--){ - - const word_arr = arrays[x]; - const word_arr_len = word_arr.length; - const check_new = create_object(); - - let found = !check; - - // process relevance in forward order (direction is - // important for adding IDs during the last round) - - for(let y = 0; y < word_arr_len; y++){ - - const arr = word_arr[y]; - const arr_len = arr.length; - - if(arr_len){ - - // loop through IDs - - for(let z = 0, check_idx, id; z < arr_len; z++){ - - id = arr[z]; - - if(check){ - - if(check[id]){ - - // check if in last round - - if(!x){ - - if(offset){ - - offset--; - } - else{ - - result[size++] = id; - - if(size === limit){ - - // fast path "end reached" - - return result; - } - } - } - - if(x || suggest){ - - check_new[id] = 1; - } - - found = true; - } - - if(suggest){ - - check_idx = (check_suggest[id] || 0) + 1; - check_suggest[id] = check_idx; - - // do not adding IDs which are already included in the result (saves one loop) - // the first intersection match has the check index 2, so shift by -2 + if (suggest) { + suggest = []; + } - if(check_idx < length){ + // process terms in reversed order often has advantage for the fast path "end reached". + // also a reversed order prioritize the order of words from a query. - const tmp = suggest[check_idx - 2] || (suggest[check_idx - 2] = []); - tmp[tmp.length] = id; - } - } - } - else{ + for (let x = length - 1; x >= 0; x--) { + const word_arr = arrays[x]; + const word_arr_len = word_arr.length; + const check_new = create_object(); + + let found = !check; + + // process relevance in forward order (direction is + // important for adding IDs during the last round) + + for (let y = 0; y < word_arr_len; y++) { + const arr = word_arr[y]; + const arr_len = arr.length; + + if (arr_len) { + // loop through IDs + + for (let z = 0, check_idx, id; z < arr_len; z++) { + id = arr[z]; + + if (check) { + if (check[id]) { + // check if in last round + + if (!x) { + if (offset) { + offset--; + } else { + result[size++] = id; + + if (size === limit) { + // fast path "end reached" + + return result; + } + } + } + + if (x || suggest) { + check_new[id] = 1; + } + + found = true; + } + + if (suggest) { + check_idx = (check_suggest[id] || 0) + 1; + check_suggest[id] = check_idx; + + // do not adding IDs which are already included in the result (saves one loop) + // the first intersection match has the check index 2, so shift by -2 + + if (check_idx < length) { + const tmp = suggest[check_idx - 2] || (suggest[check_idx - 2] = []); + tmp[tmp.length] = id; + } + } + } else { + // pre-fill in first round + + check_new[id] = 1; + } + } + } + } + + if (suggest) { + // re-use the first pre-filled check for suggestions + + check || (check_suggest = check_new); + } else if (!found) { + return []; + } + + check = check_new; + } + + if (suggest) { + // needs to iterate in reverse direction + + for (let x = suggest.length - 1, arr, len; x >= 0; x--) { + arr = suggest[x]; + len = arr.length; + + for (let y = 0, id; y < len; y++) { + id = arr[y]; + + if (!check[id]) { + if (offset) { + offset--; + } else { + result[size++] = id; - // pre-fill in first round + if (size === limit) { + // fast path "end reached" - check_new[id] = 1; - } - } - } - } + return result; + } + } - if(suggest){ + check[id] = 1; + } + } + } + } - // re-use the first pre-filled check for suggestions - - check || (check_suggest = check_new); - } - else if(!found){ - - return []; - } - - check = check_new; - } - - if(suggest){ - - // needs to iterate in reverse direction - - for(let x = suggest.length - 1, arr, len; x >= 0; x--){ - - arr = suggest[x]; - len = arr.length; - - for(let y = 0, id; y < len; y++){ - - id = arr[y]; - - if(!check[id]){ - - if(offset){ - - offset--; - } - else{ - - result[size++] = id; - - if(size === limit){ - - // fast path "end reached" - - return result; - } - } - - check[id] = 1; - } - } - } - } - - return result; + return result; } /** @@ -364,34 +336,28 @@ export function intersect(arrays, limit, offset, suggest) { */ export function intersect_union(mandatory, arrays) { - - const check = create_object(); - const union = create_object(); - const result = []; - - for(let x = 0; x < mandatory.length; x++){ - - check[mandatory[x]] = 1; - } - - for(let x = 0, arr; x < arrays.length; x++){ - - arr = arrays[x]; - - for(let y = 0, id; y < arr.length; y++){ - - id = arr[y]; - - if(check[id]){ - - if(!union[id]){ - - union[id] = 1; - result[result.length] = id; - } - } - } - } - - return result; -} \ No newline at end of file + const check = create_object(); + const union = create_object(); + const result = []; + + for (let x = 0; x < mandatory.length; x++) { + check[mandatory[x]] = 1; + } + + for (let x = 0, arr; x < arrays.length; x++) { + arr = arrays[x]; + + for (let y = 0, id; y < arr.length; y++) { + id = arr[y]; + + if (check[id]) { + if (!union[id]) { + union[id] = 1; + result[result.length] = id; + } + } + } + } + + return result; +} diff --git a/src/lang.js b/src/lang.js index 14f62ca..1028c1a 100644 --- a/src/lang.js +++ b/src/lang.js @@ -1,5 +1,4 @@ -import { IndexInterface } from "./type.js"; -import { create_object, get_keys } from "./common.js"; +import { create_object, get_keys } from './common.js'; /** * @param {!string} str @@ -7,42 +6,35 @@ import { create_object, get_keys } from "./common.js"; * @param {boolean|string|RegExp=} split * @param {boolean=} _collapse * @returns {string|Array} - * @this IndexInterface + * @this import('./type').IndexInterface */ -export function pipeline(str, normalize, split, _collapse){ +export function pipeline(str, normalize, split, _collapse) { + if (str) { + if (normalize) { + str = replace(str, /** @type {Array} */ (normalize)); + } - if(str){ + if (this.matcher) { + str = replace(str, this.matcher); + } - if(normalize){ + if (this.stemmer && str.length > 1) { + str = replace(str, this.stemmer); + } - str = replace(str, /** @type {Array} */ (normalize)); - } + if (_collapse && str.length > 1) { + str = collapse(str); + } - if(this.matcher){ + if (split || split === '') { + const words = str.split(/** @type {string|RegExp} */ (split)); - str = replace(str, this.matcher); - } + return this.filter ? filter(words, this.filter) : words; + } + } - if(this.stemmer && (str.length > 1)){ - - str = replace(str, this.stemmer); - } - - if(_collapse && (str.length > 1)){ - - str = collapse(str); - } - - if(split || (split === "")){ - - const words = str.split(/** @type {string|RegExp} */ (split)); - - return this.filter ? filter(words, this.filter) : words; - } - } - - return str; + return str; } // TODO improve normalize + remove non-delimited chars like in "I'm" + split on whitespace+ @@ -50,14 +42,12 @@ export function pipeline(str, normalize, split, _collapse){ export const regex_whitespace = /[\p{Z}\p{S}\p{P}\p{C}]+/u; const regex_normalize = /[\u0300-\u036f]/g; -export function normalize(str){ +export function normalize(str) { + if (str.normalize) { + str = str.normalize('NFD').replace(regex_normalize, ''); + } - if(str.normalize){ - - str = str.normalize("NFD").replace(regex_normalize, ""); - } - - return str; + return str; } /** @@ -147,22 +137,19 @@ export function normalize(str){ // return str; // } - /** * @param {Array} words * @returns {Object} */ -export function init_filter(words){ - - const filter = create_object(); +export function init_filter(words) { + const filter = create_object(); - for(let i = 0, length = words.length; i < length; i++){ + for (let i = 0, length = words.length; i < length; i++) { + filter[words[i]] = 1; + } - filter[words[i]] = 1; - } - - return filter; + return filter; } /** @@ -171,59 +158,50 @@ export function init_filter(words){ * @returns {Array} */ -export function init_stemmer_or_matcher(obj, is_stemmer){ - - const keys = get_keys(obj); - const length = keys.length; - const final = []; - - let removal = "", count = 0; +export function init_stemmer_or_matcher(obj, is_stemmer) { + const keys = get_keys(obj); + const length = keys.length; + const final = []; - for(let i = 0, key, tmp; i < length; i++){ + let removal = '', + count = 0; - key = keys[i]; - tmp = obj[key]; + for (let i = 0, key, tmp; i < length; i++) { + key = keys[i]; + tmp = obj[key]; - if(tmp){ + if (tmp) { + final[count++] = regex(is_stemmer ? '(?!\\b)' + key + '(\\b|_)' : key); + final[count++] = tmp; + } else { + removal += (removal ? '|' : '') + key; + } + } - final[count++] = regex(is_stemmer ? "(?!\\b)" + key + "(\\b|_)" : key); - final[count++] = tmp; - } - else{ + if (removal) { + final[count++] = regex(is_stemmer ? '(?!\\b)(' + removal + ')(\\b|_)' : '(' + removal + ')'); + final[count] = ''; + } - removal += (removal ? "|" : "") + key; - } - } - - if(removal){ - - final[count++] = regex(is_stemmer ? "(?!\\b)(" + removal + ")(\\b|_)" : "(" + removal + ")"); - final[count] = ""; - } - - return final; + return final; } - /** * @param {!string} str * @param {Array} regexp * @returns {string} */ -export function replace(str, regexp){ - - for(let i = 0, len = regexp.length; i < len; i += 2){ - - str = str.replace(regexp[i], regexp[i + 1]); - - if(!str){ +export function replace(str, regexp) { + for (let i = 0, len = regexp.length; i < len; i += 2) { + str = str.replace(regexp[i], regexp[i + 1]); - break; - } - } + if (!str) { + break; + } + } - return str; + return str; } /** @@ -231,9 +209,8 @@ export function replace(str, regexp){ * @returns {RegExp} */ -export function regex(str){ - - return new RegExp(str, "g"); +export function regex(str) { + return new RegExp(str, 'g'); } /** @@ -242,38 +219,33 @@ export function regex(str){ * @returns {string} */ -export function collapse(string){ - - let final = "", prev = ""; - - for(let i = 0, len = string.length, char; i < len; i++){ - - if((char = string[i]) !== prev){ +export function collapse(string) { + let final = '', + prev = ''; - final += (prev = char); - } - } + for (let i = 0, len = string.length, char; i < len; i++) { + if ((char = string[i]) !== prev) { + final += prev = char; + } + } - return final; + return final; } // TODO using fast-swap -export function filter(words, map){ - - const length = words.length; - const filtered = []; - - for(let i = 0, count = 0; i < length; i++){ - - const word = words[i]; +export function filter(words, map) { + const length = words.length; + const filtered = []; - if(word && !map[word]){ + for (let i = 0, count = 0; i < length; i++) { + const word = words[i]; - filtered[count++] = word; - } - } + if (word && !map[word]) { + filtered[count++] = word; + } + } - return filtered; + return filtered; } // const chars = {a:1, e:1, i:1, o:1, u:1, y:1}; diff --git a/src/lang/arabic/default.js b/src/lang/arabic/default.js index 8b63103..b24eaf7 100644 --- a/src/lang/arabic/default.js +++ b/src/lang/arabic/default.js @@ -1,29 +1,26 @@ -import { IndexInterface } from "../../type.js"; -import { pipeline } from "../../lang.js"; +import { pipeline } from '../../lang.js'; export const rtl = true; -export const tokenize = ""; +export const tokenize = ''; export default { - encode: encode, - rtl: rtl -} + encode: encode, + rtl: rtl, +}; const regex = /[\x00-\x7F]+/g; const split = /\s+/; /** * @param {string|number} str - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str){ - - return pipeline.call( - - this, - /* string: */ ("" + str).replace(regex, " "), - /* normalize: */ false, - /* split: */ split, - /* collapse: */ false - ); +export function encode(str) { + return pipeline.call( + this, + /* string: */ ('' + str).replace(regex, ' '), + /* normalize: */ false, + /* split: */ split, + /* collapse: */ false + ); } diff --git a/src/lang/at.js b/src/lang/at.js index 0fecf05..ead64af 100644 --- a/src/lang/at.js +++ b/src/lang/at.js @@ -4,136 +4,135 @@ */ export const filter = [ - - "aber", - "als", - "am", - "an", - "auch", - "auf", - "aus", - "bei", - "bin", - "bis", - "bist", - "da", - "dadurch", - "daher", - "darum", - "das", - "daß", - "dass", - "dein", - "deine", - "dem", - "den", - "der", - "des", - "dessen", - "deshalb", - "die", - "dies", - "dieser", - "dieses", - "doch", - "dort", - "du", - "durch", - "ein", - "eine", - "einem", - "einen", - "einer", - "eines", - "er", - "es", - "euer", - "eure", - "für", - "hatte", - "hatten", - "hattest", - "hattet", - "hier", - "hinter", - "ich", - "ihr", - "ihre", - "im", - "in", - "ist", - "ja", - "jede", - "jedem", - "jeden", - "jeder", - "jedes", - "jener", - "jenes", - "jetzt", - "kann", - "kannst", - "können", - "könnt", - "machen", - "mein", - "meine", - "mit", - "muß", - "mußt", - "musst", - "müssen", - "müßt", - "nach", - "nachdem", - "nein", - "nicht", - "nun", - "oder", - "seid", - "sein", - "seine", - "sich", - "sie", - "sind", - "soll", - "sollen", - "sollst", - "sollt", - "sonst", - "soweit", - "sowie", - "und", - "unser", - "unsere", - "unter", - "vom", - "von", - "vor", - "wann", - "warum", - "was", - "weiter", - "weitere", - "wenn", - "wer", - "werde", - "werden", - "werdet", - "weshalb", - "wie", - "wieder", - "wieso", - "wir", - "wird", - "wirst", - "wo", - "woher", - "wohin", - "zu", - "zum", - "zur", - "über" + 'aber', + 'als', + 'am', + 'an', + 'auch', + 'auf', + 'aus', + 'bei', + 'bin', + 'bis', + 'bist', + 'da', + 'dadurch', + 'daher', + 'darum', + 'das', + 'daß', + 'dass', + 'dein', + 'deine', + 'dem', + 'den', + 'der', + 'des', + 'dessen', + 'deshalb', + 'die', + 'dies', + 'dieser', + 'dieses', + 'doch', + 'dort', + 'du', + 'durch', + 'ein', + 'eine', + 'einem', + 'einen', + 'einer', + 'eines', + 'er', + 'es', + 'euer', + 'eure', + 'für', + 'hatte', + 'hatten', + 'hattest', + 'hattet', + 'hier', + 'hinter', + 'ich', + 'ihr', + 'ihre', + 'im', + 'in', + 'ist', + 'ja', + 'jede', + 'jedem', + 'jeden', + 'jeder', + 'jedes', + 'jener', + 'jenes', + 'jetzt', + 'kann', + 'kannst', + 'können', + 'könnt', + 'machen', + 'mein', + 'meine', + 'mit', + 'muß', + 'mußt', + 'musst', + 'müssen', + 'müßt', + 'nach', + 'nachdem', + 'nein', + 'nicht', + 'nun', + 'oder', + 'seid', + 'sein', + 'seine', + 'sich', + 'sie', + 'sind', + 'soll', + 'sollen', + 'sollst', + 'sollt', + 'sonst', + 'soweit', + 'sowie', + 'und', + 'unser', + 'unsere', + 'unter', + 'vom', + 'von', + 'vor', + 'wann', + 'warum', + 'was', + 'weiter', + 'weitere', + 'wenn', + 'wer', + 'werde', + 'werden', + 'werdet', + 'weshalb', + 'wie', + 'wieder', + 'wieso', + 'wir', + 'wird', + 'wirst', + 'wo', + 'woher', + 'wohin', + 'zu', + 'zum', + 'zur', + 'über', ]; /** @@ -141,32 +140,30 @@ export const filter = [ */ export const stemmer = { - - "niss": "", - "isch": "", - "lich": "", - "heit": "", - "keit": "", - "end": "", - "ung": "", - "est": "", - "ern": "", - "em": "", - "er": "", - "en": "", - "es": "", - "st": "", - "ig": "", - "ik": "", - "e": "", - "s": "" + niss: '', + isch: '', + lich: '', + heit: '', + keit: '', + end: '', + ung: '', + est: '', + ern: '', + em: '', + er: '', + en: '', + es: '', + st: '', + ig: '', + ik: '', + e: '', + s: '', }; export const matcher = {}; export default { - - filter: filter, - stemmer: stemmer, - matcher: matcher -} + filter: filter, + stemmer: stemmer, + matcher: matcher, +}; diff --git a/src/lang/cjk/default.js b/src/lang/cjk/default.js index a31f0b5..e9ebec9 100644 --- a/src/lang/cjk/default.js +++ b/src/lang/cjk/default.js @@ -1,29 +1,26 @@ -import { IndexInterface } from "../../type.js"; -import { pipeline } from "../../lang.js"; +import { pipeline } from '../../lang.js'; export const rtl = false; -export const tokenize = "strict"; +export const tokenize = 'strict'; export default { - encode: encode, - rtl: rtl, - tokenize: tokenize -} + encode: encode, + rtl: rtl, + tokenize: tokenize, +}; const regex = /[\x00-\x7F]+/g; /** * @param {string|number} str - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str){ - - return pipeline.call( - - this, - /* string: */ ("" + str).replace(regex, ""), - /* normalize: */ false, - /* split: */ "", - /* collapse: */ false - ); +export function encode(str) { + return pipeline.call( + this, + /* string: */ ('' + str).replace(regex, ''), + /* normalize: */ false, + /* split: */ '', + /* collapse: */ false + ); } diff --git a/src/lang/cyrillic/default.js b/src/lang/cyrillic/default.js index 5bba75d..b396b4e 100644 --- a/src/lang/cyrillic/default.js +++ b/src/lang/cyrillic/default.js @@ -1,29 +1,26 @@ -import { IndexInterface } from "../../type.js"; -import { pipeline } from "../../lang.js"; +import { pipeline } from '../../lang.js'; export const rtl = false; -export const tokenize = ""; +export const tokenize = ''; export default { - encode: encode, - rtl: rtl -} + encode: encode, + rtl: rtl, +}; const regex = /[\x00-\x7F]+/g; const split = /\s+/; /** * @param {string|number} str - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str){ - - return pipeline.call( - - this, - /* string: */ ("" + str).replace(regex, " "), - /* normalize: */ false, - /* split: */ split, - /* collapse: */ false - ); +export function encode(str) { + return pipeline.call( + this, + /* string: */ ('' + str).replace(regex, ' '), + /* normalize: */ false, + /* split: */ split, + /* collapse: */ false + ); } diff --git a/src/lang/de.js b/src/lang/de.js index 029a6bd..b2ca975 100644 --- a/src/lang/de.js +++ b/src/lang/de.js @@ -6,136 +6,135 @@ */ export const filter = [ - - "aber", - "als", - "am", - "an", - "auch", - "auf", - "aus", - "bei", - "bin", - "bis", - "bist", - "da", - "dadurch", - "daher", - "darum", - "das", - "daß", - "dass", - "dein", - "deine", - "dem", - "den", - "der", - "des", - "dessen", - "deshalb", - "die", - "dies", - "dieser", - "dieses", - "doch", - "dort", - "du", - "durch", - "ein", - "eine", - "einem", - "einen", - "einer", - "eines", - "er", - "es", - "euer", - "eure", - "für", - "hatte", - "hatten", - "hattest", - "hattet", - "hier", - "hinter", - "ich", - "ihr", - "ihre", - "im", - "in", - "ist", - "ja", - "jede", - "jedem", - "jeden", - "jeder", - "jedes", - "jener", - "jenes", - "jetzt", - "kann", - "kannst", - "können", - "könnt", - "machen", - "mein", - "meine", - "mit", - "muß", - "mußt", - "musst", - "müssen", - "müßt", - "nach", - "nachdem", - "nein", - "nicht", - "nun", - "oder", - "seid", - "sein", - "seine", - "sich", - "sie", - "sind", - "soll", - "sollen", - "sollst", - "sollt", - "sonst", - "soweit", - "sowie", - "und", - "unser", - "unsere", - "unter", - "vom", - "von", - "vor", - "wann", - "warum", - "was", - "weiter", - "weitere", - "wenn", - "wer", - "werde", - "werden", - "werdet", - "weshalb", - "wie", - "wieder", - "wieso", - "wir", - "wird", - "wirst", - "wo", - "woher", - "wohin", - "zu", - "zum", - "zur", - "über" + 'aber', + 'als', + 'am', + 'an', + 'auch', + 'auf', + 'aus', + 'bei', + 'bin', + 'bis', + 'bist', + 'da', + 'dadurch', + 'daher', + 'darum', + 'das', + 'daß', + 'dass', + 'dein', + 'deine', + 'dem', + 'den', + 'der', + 'des', + 'dessen', + 'deshalb', + 'die', + 'dies', + 'dieser', + 'dieses', + 'doch', + 'dort', + 'du', + 'durch', + 'ein', + 'eine', + 'einem', + 'einen', + 'einer', + 'eines', + 'er', + 'es', + 'euer', + 'eure', + 'für', + 'hatte', + 'hatten', + 'hattest', + 'hattet', + 'hier', + 'hinter', + 'ich', + 'ihr', + 'ihre', + 'im', + 'in', + 'ist', + 'ja', + 'jede', + 'jedem', + 'jeden', + 'jeder', + 'jedes', + 'jener', + 'jenes', + 'jetzt', + 'kann', + 'kannst', + 'können', + 'könnt', + 'machen', + 'mein', + 'meine', + 'mit', + 'muß', + 'mußt', + 'musst', + 'müssen', + 'müßt', + 'nach', + 'nachdem', + 'nein', + 'nicht', + 'nun', + 'oder', + 'seid', + 'sein', + 'seine', + 'sich', + 'sie', + 'sind', + 'soll', + 'sollen', + 'sollst', + 'sollt', + 'sonst', + 'soweit', + 'sowie', + 'und', + 'unser', + 'unsere', + 'unter', + 'vom', + 'von', + 'vor', + 'wann', + 'warum', + 'was', + 'weiter', + 'weitere', + 'wenn', + 'wer', + 'werde', + 'werden', + 'werdet', + 'weshalb', + 'wie', + 'wieder', + 'wieso', + 'wir', + 'wird', + 'wirst', + 'wo', + 'woher', + 'wohin', + 'zu', + 'zum', + 'zur', + 'über', ]; /** @@ -146,27 +145,26 @@ export const filter = [ */ export const stemmer = { - - "niss": "", - "isch": "", - "lich": "", - "heit": "", - "keit": "", - "ell": "", - "bar": "", - "end": "", - "ung": "", - "est": "", - "ern": "", - "em": "", - "er": "", - "en": "", - "es": "", - "st": "", - "ig": "", - "ik": "", - "e": "", - "s": "" + niss: '', + isch: '', + lich: '', + heit: '', + keit: '', + ell: '', + bar: '', + end: '', + ung: '', + est: '', + ern: '', + em: '', + er: '', + en: '', + es: '', + st: '', + ig: '', + ik: '', + e: '', + s: '', }; /** @@ -178,8 +176,7 @@ export const stemmer = { export const matcher = {}; export default { - - filter: filter, - stemmer: stemmer, - matcher: matcher -} \ No newline at end of file + filter: filter, + stemmer: stemmer, + matcher: matcher, +}; diff --git a/src/lang/en.js b/src/lang/en.js index c7e9870..735cf18 100644 --- a/src/lang/en.js +++ b/src/lang/en.js @@ -4,212 +4,211 @@ */ export const filter = [ - - "a", - "about", - "above", - "after", - "again", - "against", - "all", - "also", - "am", - "an", - "and", - "any", - "are", - "aren't", - "as", - "at", - //"back", - "be", - "because", - "been", - "before", - "being", - "below", - //"between", - "both", - "but", - "by", - "can", - "cannot", - "can't", - "come", - "could", - "couldn't", - //"day", - "did", - "didn't", - "do", - "does", - "doesn't", - "doing", - "dont", - "down", - "during", - "each", - "even", - "few", - "first", - "for", - "from", - "further", - "get", - //"give", - "go", - //"good", - "had", - "hadn't", - "has", - "hasn't", - "have", - "haven't", - "having", - "he", - "hed", - //"hell", - "her", - "here", - "here's", - "hers", - "herself", - "hes", - "him", - "himself", - "his", - "how", - "how's", - "i", - "id", - "if", - "ill", - "im", - "in", - "into", - "is", - "isn't", - "it", - "it's", - "itself", - "i've", - "just", - "know", - "let's", - "like", - //"look", - "make", - "me", - "more", - "most", - "mustn't", - "my", - "myself", - "new", - "no", - "nor", - "not", - "now", - "of", - "off", - "on", - "once", - //"one", - "only", - "or", - "other", - "ought", - "our", - "our's", - "ourselves", - "out", - "over", - "own", - //"people", - "same", - "say", - "see", - "shan't", - "she", - "she'd", - "shell", - "shes", - "should", - "shouldn't", - "so", - "some", - "such", - //"take", - "than", - "that", - "that's", - "the", - "their", - "theirs", - "them", - "themselves", - "then", - "there", - "there's", - "these", - "they", - "they'd", - "they'll", - "they're", - "they've", - //"think", - "this", - "those", - "through", - "time", - "to", - "too", - //"two", - //"under", - "until", - "up", - "us", - //"use", - "very", - "want", - "was", - "wasn't", - "way", - "we", - "wed", - "well", - "were", - "weren't", - "we've", - "what", - "what's", - "when", - "when's", - "where", - "where's", - "which", - "while", - "who", - "whom", - "who's", - "why", - "why's", - "will", - "with", - "won't", - //"work", - "would", - "wouldn't", - //"year", - "you", - "you'd", - "you'll", - "your", - "you're", - "your's", - "yourself", - "yourselves", - "you've" + 'a', + 'about', + 'above', + 'after', + 'again', + 'against', + 'all', + 'also', + 'am', + 'an', + 'and', + 'any', + 'are', + "aren't", + 'as', + 'at', + //"back", + 'be', + 'because', + 'been', + 'before', + 'being', + 'below', + //"between", + 'both', + 'but', + 'by', + 'can', + 'cannot', + "can't", + 'come', + 'could', + "couldn't", + //"day", + 'did', + "didn't", + 'do', + 'does', + "doesn't", + 'doing', + 'dont', + 'down', + 'during', + 'each', + 'even', + 'few', + 'first', + 'for', + 'from', + 'further', + 'get', + //"give", + 'go', + //"good", + 'had', + "hadn't", + 'has', + "hasn't", + 'have', + "haven't", + 'having', + 'he', + 'hed', + //"hell", + 'her', + 'here', + "here's", + 'hers', + 'herself', + 'hes', + 'him', + 'himself', + 'his', + 'how', + "how's", + 'i', + 'id', + 'if', + 'ill', + 'im', + 'in', + 'into', + 'is', + "isn't", + 'it', + "it's", + 'itself', + "i've", + 'just', + 'know', + "let's", + 'like', + //"look", + 'make', + 'me', + 'more', + 'most', + "mustn't", + 'my', + 'myself', + 'new', + 'no', + 'nor', + 'not', + 'now', + 'of', + 'off', + 'on', + 'once', + //"one", + 'only', + 'or', + 'other', + 'ought', + 'our', + "our's", + 'ourselves', + 'out', + 'over', + 'own', + //"people", + 'same', + 'say', + 'see', + "shan't", + 'she', + "she'd", + 'shell', + 'shes', + 'should', + "shouldn't", + 'so', + 'some', + 'such', + //"take", + 'than', + 'that', + "that's", + 'the', + 'their', + 'theirs', + 'them', + 'themselves', + 'then', + 'there', + "there's", + 'these', + 'they', + "they'd", + "they'll", + "they're", + "they've", + //"think", + 'this', + 'those', + 'through', + 'time', + 'to', + 'too', + //"two", + //"under", + 'until', + 'up', + 'us', + //"use", + 'very', + 'want', + 'was', + "wasn't", + 'way', + 'we', + 'wed', + 'well', + 'were', + "weren't", + "we've", + 'what', + "what's", + 'when', + "when's", + 'where', + "where's", + 'which', + 'while', + 'who', + 'whom', + "who's", + 'why', + "why's", + 'will', + 'with', + "won't", + //"work", + 'would', + "wouldn't", + //"year", + 'you', + "you'd", + "you'll", + 'your', + "you're", + "your's", + 'yourself', + 'yourselves', + "you've", ]; /** @@ -217,60 +216,58 @@ export const filter = [ */ export const stemmer = { - - "ational": "ate", - "iveness": "ive", - "fulness": "ful", - "ousness": "ous", - "ization": "ize", - "tional": "tion", - "biliti": "ble", - "icate": "ic", - "ative": "", - "alize": "al", - "iciti": "ic", - "entli": "ent", - "ousli": "ous", - "alism": "al", - "ation": "ate", - "aliti": "al", - "iviti": "ive", - "ement": "", - "enci": "ence", - "anci": "ance", - "izer": "ize", - "alli": "al", - "ator": "ate", - "logi": "log", - "ical": "ic", - "ance": "", - "ence": "", - "ness": "", - "able": "", - "ible": "", - "ment": "", - "eli": "e", - "bli": "ble", - "ful": "", - "ant": "", - "ent": "", - "ism": "", - "ate": "", - "iti": "", - "ous": "", - "ive": "", - "ize": "", - "al": "", - "ou": "", - "er": "", - "ic": "" + ational: 'ate', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + ization: 'ize', + tional: 'tion', + biliti: 'ble', + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + entli: 'ent', + ousli: 'ous', + alism: 'al', + ation: 'ate', + aliti: 'al', + iviti: 'ive', + ement: '', + enci: 'ence', + anci: 'ance', + izer: 'ize', + alli: 'al', + ator: 'ate', + logi: 'log', + ical: 'ic', + ance: '', + ence: '', + ness: '', + able: '', + ible: '', + ment: '', + eli: 'e', + bli: 'ble', + ful: '', + ant: '', + ent: '', + ism: '', + ate: '', + iti: '', + ous: '', + ive: '', + ize: '', + al: '', + ou: '', + er: '', + ic: '', }; export const matcher = {}; export default { - - filter: filter, - stemmer: stemmer, - matcher: matcher -} + filter: filter, + stemmer: stemmer, + matcher: matcher, +}; diff --git a/src/lang/latin/advanced.js b/src/lang/latin/advanced.js index baa67e4..3817c08 100644 --- a/src/lang/latin/advanced.js +++ b/src/lang/latin/advanced.js @@ -1,92 +1,93 @@ -import { IndexInterface } from "../../type.js"; -import { regex, replace, collapse } from "../../lang.js"; -import { encode as encode_balance } from "./balance.js"; +import { regex, replace, collapse } from '../../lang.js'; +import { encode as encode_balance } from './balance.js'; export const rtl = false; -export const tokenize = ""; +export const tokenize = ''; export default { - encode: encode, - rtl: rtl, - tokenize: tokenize -} + encode: encode, + rtl: rtl, + tokenize: tokenize, +}; // Phonetic Normalization -const regex_ae = regex("ae"), - //regex_ai = regex("ai"), - //regex_ay = regex("ay"), - //regex_ey = regex("ey"), - regex_oe = regex("oe"), - //regex_ue = regex("ue"), - //regex_ie = regex("ie"), - //regex_sz = regex("sz"), - //regex_zs = regex("zs"), - //regex_ck = regex("ck"), - //regex_cc = regex("cc"), - regex_sh = regex("sh"), - regex_th = regex("th"), - //regex_dt = regex("dt"), - regex_ph = regex("ph"), - regex_pf = regex("pf"); - //regex_ou = regex("ou"), - //regex_uo = regex("uo"); +const regex_ae = regex('ae'), + //regex_ai = regex("ai"), + //regex_ay = regex("ay"), + //regex_ey = regex("ey"), + regex_oe = regex('oe'), + //regex_ue = regex("ue"), + //regex_ie = regex("ie"), + //regex_sz = regex("sz"), + //regex_zs = regex("zs"), + //regex_ck = regex("ck"), + //regex_cc = regex("cc"), + regex_sh = regex('sh'), + regex_th = regex('th'), + //regex_dt = regex("dt"), + regex_ph = regex('ph'), + regex_pf = regex('pf'); +//regex_ou = regex("ou"), +//regex_uo = regex("uo"); const pairs = [ - regex_ae, "a", - // regex_ai, "ei", - // regex_ay, "ei", - // regex_ey, "ei", - regex_oe, "o", - // regex_ue, "u", - // regex_ie, "i", - // regex_sz, "s", - // regex_zs, "s", - regex_sh, "s", - // regex_ck, "k", - // regex_cc, "k", - regex_th, "t", - // regex_dt, "t", - regex_ph, "f", - regex_pf, "f", - // regex_ou, "o", - // regex_uo, "u" - - // regex("(?![aeiouy])h(?![aeiouy])"), "", - // regex("(?!^[aeiouy])h(?!^[aeiouy])"), "" - regex("(?![aeo])h(?![aeo])"), "", - regex("(?!^[aeo])h(?!^[aeo])"), "" + regex_ae, + 'a', + // regex_ai, "ei", + // regex_ay, "ei", + // regex_ey, "ei", + regex_oe, + 'o', + // regex_ue, "u", + // regex_ie, "i", + // regex_sz, "s", + // regex_zs, "s", + regex_sh, + 's', + // regex_ck, "k", + // regex_cc, "k", + regex_th, + 't', + // regex_dt, "t", + regex_ph, + 'f', + regex_pf, + 'f', + // regex_ou, "o", + // regex_uo, "u" + + // regex("(?![aeiouy])h(?![aeiouy])"), "", + // regex("(?!^[aeiouy])h(?!^[aeiouy])"), "" + regex('(?![aeo])h(?![aeo])'), + '', + regex('(?!^[aeo])h(?!^[aeo])'), + '', ]; /** * @param {string|number} str * @param {boolean=} _skip_postprocessing - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str, _skip_postprocessing){ - - if(str){ - - str = encode_balance.call(this, str).join(" "); - - if(str.length > 2){ - - str = replace(str, pairs); - } - - if(!_skip_postprocessing){ - - if(str.length > 1){ +export function encode(str, _skip_postprocessing) { + if (str) { + str = encode_balance.call(this, str).join(' '); - str = collapse(str); - } + if (str.length > 2) { + str = replace(str, pairs); + } - if(str){ + if (!_skip_postprocessing) { + if (str.length > 1) { + str = collapse(str); + } - str = str.split(" "); - } - } - } + if (str) { + str = str.split(' '); + } + } + } - return str || []; + return str || []; } diff --git a/src/lang/latin/balance.js b/src/lang/latin/balance.js index bc20788..2c79afe 100644 --- a/src/lang/latin/balance.js +++ b/src/lang/latin/balance.js @@ -1,15 +1,14 @@ -import { IndexInterface } from "../../type.js"; -import { encode as encode_simple } from "./simple.js"; +import { encode as encode_simple } from './simple.js'; // custom soundex implementation export const rtl = false; -export const tokenize = "strict"; +export const tokenize = 'strict'; export default { - encode: encode, - rtl: rtl, - tokenize: tokenize -} + encode: encode, + rtl: rtl, + tokenize: tokenize, +}; //const regex_whitespace = /[\W_]+/g; const regex_strip = /[^a-z0-9]+/; @@ -22,98 +21,91 @@ const regex_strip = /[^a-z0-9]+/; // modified const soundex = { + b: 'p', + //"p": "p", - "b": "p", - //"p": "p", - - //"f": "f", - "v": "f", - "w": "f", + //"f": "f", + v: 'f', + w: 'f', - //"s": "s", - "z": "s", - "x": "s", - "ß": "s", + //"s": "s", + z: 's', + x: 's', + ß: 's', - "d": "t", - //"t": "t", + d: 't', + //"t": "t", - //"l": "l", + //"l": "l", - //"m": "m", - "n": "m", + //"m": "m", + n: 'm', - "c": "k", - "g": "k", - "j": "k", - //"k": "k", - "q": "k", + c: 'k', + g: 'k', + j: 'k', + //"k": "k", + q: 'k', - //"r": "r", - //"h": "h", - //"a": "a", + //"r": "r", + //"h": "h", + //"a": "a", - //"e": "e", - "i": "e", - "y": "e", + //"e": "e", + i: 'e', + y: 'e', - //"o": "o", - "u": "o" + //"o": "o", + u: 'o', }; /** * @param {string|number} str - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str){ - - str = encode_simple.call(this, str).join(" "); - - // str = this.pipeline( - // - // /* string: */ normalize("" + str).toLowerCase(), - // /* normalize: */ false, - // /* split: */ false, - // /* collapse: */ false - // ); - - const result = []; - - if(str){ - - const words = str.split(regex_strip); - const length = words.length; - - for(let x = 0, tmp, count = 0; x < length; x++){ - - if((str = words[x]) /*&& (str.length > 2)*/ && (!this.filter || !this.filter[str])){ - - tmp = str[0]; - let code = soundex[tmp] || tmp; //str[0]; - let previous = code; //soundex[code] || code; - - for(let i = 1; i < str.length; i++){ - - tmp = str[i]; - const current = soundex[tmp] || tmp; - - if(current && (current !== previous)){ - - code += current; - previous = current; - - // if(code.length === 7){ - // - // break; - // } - } - } - - result[count++] = code; //(code + "0000").substring(0, 4); - } - } - } - - return result; +export function encode(str) { + str = encode_simple.call(this, str).join(' '); + + // str = this.pipeline( + // + // /* string: */ normalize("" + str).toLowerCase(), + // /* normalize: */ false, + // /* split: */ false, + // /* collapse: */ false + // ); + + const result = []; + + if (str) { + const words = str.split(regex_strip); + const length = words.length; + + for (let x = 0, tmp, count = 0; x < length; x++) { + if ((str = words[x]) /*&& (str.length > 2)*/ && (!this.filter || !this.filter[str])) { + tmp = str[0]; + let code = soundex[tmp] || tmp; //str[0]; + let previous = code; //soundex[code] || code; + + for (let i = 1; i < str.length; i++) { + tmp = str[i]; + const current = soundex[tmp] || tmp; + + if (current && current !== previous) { + code += current; + previous = current; + + // if(code.length === 7){ + // + // break; + // } + } + } + + result[count++] = code; //(code + "0000").substring(0, 4); + } + } + } + + return result; } diff --git a/src/lang/latin/default.js b/src/lang/latin/default.js index 47870f3..069f2e1 100644 --- a/src/lang/latin/default.js +++ b/src/lang/latin/default.js @@ -1,27 +1,24 @@ -import { IndexInterface } from "../../type.js"; -import { pipeline, normalize, regex_whitespace } from "../../lang.js"; +import { pipeline, regex_whitespace } from '../../lang.js'; export const rtl = false; -export const tokenize = ""; +export const tokenize = ''; export default { - encode: encode, - rtl: rtl, - tokenize: tokenize -} + encode: encode, + rtl: rtl, + tokenize: tokenize, +}; /** * @param {string|number} str - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str){ - - return pipeline.call( - - this, - /* string: */ ("" + str).toLowerCase(), - /* normalize: */ false, - /* split: */ regex_whitespace, - /* collapse: */ false - ); +export function encode(str) { + return pipeline.call( + this, + /* string: */ ('' + str).toLowerCase(), + /* normalize: */ false, + /* split: */ regex_whitespace, + /* collapse: */ false + ); } diff --git a/src/lang/latin/extra.js b/src/lang/latin/extra.js index cc5dafc..46b1a20 100644 --- a/src/lang/latin/extra.js +++ b/src/lang/latin/extra.js @@ -1,67 +1,61 @@ -import { IndexInterface } from "../../type.js"; -import { regex, replace, collapse } from "../../lang.js"; -import { encode as encode_advanced } from "./advanced.js"; +import { regex, collapse } from '../../lang.js'; +import { encode as encode_advanced } from './advanced.js'; export const rtl = false; -export const tokenize = ""; +export const tokenize = ''; export default { - encode: encode, - rtl: rtl, - tokenize: tokenize -} + encode: encode, + rtl: rtl, + tokenize: tokenize, +}; // Soundex Normalization -const prefix = "(?!\\b)"; +const prefix = '(?!\\b)'; const //soundex_b = regex(prefix + "p"), - // soundex_s = regex(prefix + "z"), - // soundex_k = regex(prefix + "[cgq]"), - // soundex_m = regex(prefix + "n"), - // soundex_t = regex(prefix + "d"), - // soundex_f = regex(prefix + "[vw]"), - //regex_vowel = regex(prefix + "[aeiouy]"); - regex_vowel = regex(prefix + "[aeo]"); + // soundex_s = regex(prefix + "z"), + // soundex_k = regex(prefix + "[cgq]"), + // soundex_m = regex(prefix + "n"), + // soundex_t = regex(prefix + "d"), + // soundex_f = regex(prefix + "[vw]"), + //regex_vowel = regex(prefix + "[aeiouy]"); + regex_vowel = regex(prefix + '[aeo]'); const pairs = [ - - // soundex_b, "b", - // soundex_s, "s", - // soundex_k, "k", - // soundex_m, "m", - // soundex_t, "t", - // soundex_f, "f", - // regex("(?![aeiouy])h(?![aeiouy])"), "", - // regex("(?!^[aeiouy])h(?!^[aeiouy])"), "", - regex_vowel, "" + // soundex_b, "b", + // soundex_s, "s", + // soundex_k, "k", + // soundex_m, "m", + // soundex_t, "t", + // soundex_f, "f", + // regex("(?![aeiouy])h(?![aeiouy])"), "", + // regex("(?!^[aeiouy])h(?!^[aeiouy])"), "", + regex_vowel, + '', ]; /** * @param {string|number} str - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str){ - - if(str){ - - str = encode_advanced.call(this, str, /* skip post-processing: */ true); - - if(str.length > 1){ - - //str = replace(str, pairs); - str = str.replace(regex_vowel, ""); - } - - if(str.length > 1){ +export function encode(str) { + if (str) { + str = encode_advanced.call(this, str, /* skip post-processing: */ true); - str = collapse(str); - } + if (str.length > 1) { + //str = replace(str, pairs); + str = str.replace(regex_vowel, ''); + } - if(str){ + if (str.length > 1) { + str = collapse(str); + } - str = str.split(" "); - } - } + if (str) { + str = str.split(' '); + } + } - return str || []; + return str || []; } diff --git a/src/lang/latin/simple.js b/src/lang/latin/simple.js index 8f0cefe..4190661 100644 --- a/src/lang/latin/simple.js +++ b/src/lang/latin/simple.js @@ -1,60 +1,66 @@ -import { IndexInterface } from "../../type.js"; -import { pipeline, normalize, regex_whitespace, regex } from "../../lang.js"; +import { pipeline, normalize, regex_whitespace, regex } from '../../lang.js'; export const rtl = false; -export const tokenize = ""; +export const tokenize = ''; export default { - encode: encode, - rtl: rtl, - tokenize: tokenize -} + encode: encode, + rtl: rtl, + tokenize: tokenize, +}; // Charset Normalization const //regex_whitespace = /\W+/, - //regex_strip = regex("[^a-z0-9 ]"), - regex_a = regex("[àáâãäå]"), - regex_e = regex("[èéêë]"), - regex_i = regex("[ìíîï]"), - regex_o = regex("[òóôõöő]"), - regex_u = regex("[ùúûüű]"), - regex_y = regex("[ýŷÿ]"), - regex_n = regex("ñ"), - regex_c = regex("[çc]"), - regex_s = regex("ß"), - regex_and = regex(" & "); + //regex_strip = regex("[^a-z0-9 ]"), + regex_a = regex('[àáâãäå]'), + regex_e = regex('[èéêë]'), + regex_i = regex('[ìíîï]'), + regex_o = regex('[òóôõöő]'), + regex_u = regex('[ùúûüű]'), + regex_y = regex('[ýŷÿ]'), + regex_n = regex('ñ'), + regex_c = regex('[çc]'), + regex_s = regex('ß'), + regex_and = regex(' & '); const pairs = [ - - regex_a, "a", - regex_e, "e", - regex_i, "i", - regex_o, "o", - regex_u, "u", - regex_y, "y", - regex_n, "n", - regex_c, "k", - regex_s, "s", - regex_and, " and " - //regex_whitespace, " " - //regex_strip, "" + regex_a, + 'a', + regex_e, + 'e', + regex_i, + 'i', + regex_o, + 'o', + regex_u, + 'u', + regex_y, + 'y', + regex_n, + 'n', + regex_c, + 'k', + regex_s, + 's', + regex_and, + ' and ', + //regex_whitespace, " " + //regex_strip, "" ]; /** * @param {string|number} str - * @this IndexInterface + * @this import('../../type').IndexInterface */ -export function encode(str){ - - str = "" + str; - - return pipeline.call( +export function encode(str) { + str = '' + str; - this, - /* string: */ normalize(str).toLowerCase(), - /* normalize: */ !str.normalize && pairs, - /* split: */ regex_whitespace, - /* collapse: */ false - ); + return pipeline.call( + this, + /* string: */ normalize(str).toLowerCase(), + /* normalize: */ !str.normalize && pairs, + /* split: */ regex_whitespace, + /* collapse: */ false + ); } diff --git a/src/lang/us.js b/src/lang/us.js index c7e9870..735cf18 100644 --- a/src/lang/us.js +++ b/src/lang/us.js @@ -4,212 +4,211 @@ */ export const filter = [ - - "a", - "about", - "above", - "after", - "again", - "against", - "all", - "also", - "am", - "an", - "and", - "any", - "are", - "aren't", - "as", - "at", - //"back", - "be", - "because", - "been", - "before", - "being", - "below", - //"between", - "both", - "but", - "by", - "can", - "cannot", - "can't", - "come", - "could", - "couldn't", - //"day", - "did", - "didn't", - "do", - "does", - "doesn't", - "doing", - "dont", - "down", - "during", - "each", - "even", - "few", - "first", - "for", - "from", - "further", - "get", - //"give", - "go", - //"good", - "had", - "hadn't", - "has", - "hasn't", - "have", - "haven't", - "having", - "he", - "hed", - //"hell", - "her", - "here", - "here's", - "hers", - "herself", - "hes", - "him", - "himself", - "his", - "how", - "how's", - "i", - "id", - "if", - "ill", - "im", - "in", - "into", - "is", - "isn't", - "it", - "it's", - "itself", - "i've", - "just", - "know", - "let's", - "like", - //"look", - "make", - "me", - "more", - "most", - "mustn't", - "my", - "myself", - "new", - "no", - "nor", - "not", - "now", - "of", - "off", - "on", - "once", - //"one", - "only", - "or", - "other", - "ought", - "our", - "our's", - "ourselves", - "out", - "over", - "own", - //"people", - "same", - "say", - "see", - "shan't", - "she", - "she'd", - "shell", - "shes", - "should", - "shouldn't", - "so", - "some", - "such", - //"take", - "than", - "that", - "that's", - "the", - "their", - "theirs", - "them", - "themselves", - "then", - "there", - "there's", - "these", - "they", - "they'd", - "they'll", - "they're", - "they've", - //"think", - "this", - "those", - "through", - "time", - "to", - "too", - //"two", - //"under", - "until", - "up", - "us", - //"use", - "very", - "want", - "was", - "wasn't", - "way", - "we", - "wed", - "well", - "were", - "weren't", - "we've", - "what", - "what's", - "when", - "when's", - "where", - "where's", - "which", - "while", - "who", - "whom", - "who's", - "why", - "why's", - "will", - "with", - "won't", - //"work", - "would", - "wouldn't", - //"year", - "you", - "you'd", - "you'll", - "your", - "you're", - "your's", - "yourself", - "yourselves", - "you've" + 'a', + 'about', + 'above', + 'after', + 'again', + 'against', + 'all', + 'also', + 'am', + 'an', + 'and', + 'any', + 'are', + "aren't", + 'as', + 'at', + //"back", + 'be', + 'because', + 'been', + 'before', + 'being', + 'below', + //"between", + 'both', + 'but', + 'by', + 'can', + 'cannot', + "can't", + 'come', + 'could', + "couldn't", + //"day", + 'did', + "didn't", + 'do', + 'does', + "doesn't", + 'doing', + 'dont', + 'down', + 'during', + 'each', + 'even', + 'few', + 'first', + 'for', + 'from', + 'further', + 'get', + //"give", + 'go', + //"good", + 'had', + "hadn't", + 'has', + "hasn't", + 'have', + "haven't", + 'having', + 'he', + 'hed', + //"hell", + 'her', + 'here', + "here's", + 'hers', + 'herself', + 'hes', + 'him', + 'himself', + 'his', + 'how', + "how's", + 'i', + 'id', + 'if', + 'ill', + 'im', + 'in', + 'into', + 'is', + "isn't", + 'it', + "it's", + 'itself', + "i've", + 'just', + 'know', + "let's", + 'like', + //"look", + 'make', + 'me', + 'more', + 'most', + "mustn't", + 'my', + 'myself', + 'new', + 'no', + 'nor', + 'not', + 'now', + 'of', + 'off', + 'on', + 'once', + //"one", + 'only', + 'or', + 'other', + 'ought', + 'our', + "our's", + 'ourselves', + 'out', + 'over', + 'own', + //"people", + 'same', + 'say', + 'see', + "shan't", + 'she', + "she'd", + 'shell', + 'shes', + 'should', + "shouldn't", + 'so', + 'some', + 'such', + //"take", + 'than', + 'that', + "that's", + 'the', + 'their', + 'theirs', + 'them', + 'themselves', + 'then', + 'there', + "there's", + 'these', + 'they', + "they'd", + "they'll", + "they're", + "they've", + //"think", + 'this', + 'those', + 'through', + 'time', + 'to', + 'too', + //"two", + //"under", + 'until', + 'up', + 'us', + //"use", + 'very', + 'want', + 'was', + "wasn't", + 'way', + 'we', + 'wed', + 'well', + 'were', + "weren't", + "we've", + 'what', + "what's", + 'when', + "when's", + 'where', + "where's", + 'which', + 'while', + 'who', + 'whom', + "who's", + 'why', + "why's", + 'will', + 'with', + "won't", + //"work", + 'would', + "wouldn't", + //"year", + 'you', + "you'd", + "you'll", + 'your', + "you're", + "your's", + 'yourself', + 'yourselves', + "you've", ]; /** @@ -217,60 +216,58 @@ export const filter = [ */ export const stemmer = { - - "ational": "ate", - "iveness": "ive", - "fulness": "ful", - "ousness": "ous", - "ization": "ize", - "tional": "tion", - "biliti": "ble", - "icate": "ic", - "ative": "", - "alize": "al", - "iciti": "ic", - "entli": "ent", - "ousli": "ous", - "alism": "al", - "ation": "ate", - "aliti": "al", - "iviti": "ive", - "ement": "", - "enci": "ence", - "anci": "ance", - "izer": "ize", - "alli": "al", - "ator": "ate", - "logi": "log", - "ical": "ic", - "ance": "", - "ence": "", - "ness": "", - "able": "", - "ible": "", - "ment": "", - "eli": "e", - "bli": "ble", - "ful": "", - "ant": "", - "ent": "", - "ism": "", - "ate": "", - "iti": "", - "ous": "", - "ive": "", - "ize": "", - "al": "", - "ou": "", - "er": "", - "ic": "" + ational: 'ate', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + ization: 'ize', + tional: 'tion', + biliti: 'ble', + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + entli: 'ent', + ousli: 'ous', + alism: 'al', + ation: 'ate', + aliti: 'al', + iviti: 'ive', + ement: '', + enci: 'ence', + anci: 'ance', + izer: 'ize', + alli: 'al', + ator: 'ate', + logi: 'log', + ical: 'ic', + ance: '', + ence: '', + ness: '', + able: '', + ible: '', + ment: '', + eli: 'e', + bli: 'ble', + ful: '', + ant: '', + ent: '', + ism: '', + ate: '', + iti: '', + ous: '', + ive: '', + ize: '', + al: '', + ou: '', + er: '', + ic: '', }; export const matcher = {}; export default { - - filter: filter, - stemmer: stemmer, - matcher: matcher -} + filter: filter, + stemmer: stemmer, + matcher: matcher, +}; diff --git a/src/polyfill.js b/src/polyfill.js index 17a039a..9f0ab76 100644 --- a/src/polyfill.js +++ b/src/polyfill.js @@ -1,78 +1,70 @@ -import { POLYFILL, SUPPORT_ASYNC } from "./config.js"; +import { POLYFILL, SUPPORT_ASYNC } from './config.js'; export let promise = Promise; -if(POLYFILL){ - - Object.assign || (Object.assign = function(){ - - const args = arguments; - const size = args.length; - const obj = args[0]; - - for(let x = 1, current, keys, length; x < size; x++){ - - current = args[x]; - keys = Object.keys(current); - length = keys.length; - - for(let i = 0, key; i < length; i++){ - - key = keys[i]; - obj[key] = current[key]; - } - } - - return obj; - }); - - // Object.values || (Object.values = function(obj){ - // - // const keys = Object.keys(obj); - // const length = keys.length; - // const values = new Array(length); - // - // for(let x = 0; x < length; x++){ - // - // values[x] = obj[keys[x]]; - // } - // - // return values; - // }); - - if(SUPPORT_ASYNC && !promise){ - - /** - * @param {Function} fn - * @constructor - */ - - function SimplePromise(fn){ - - this.callback = null; - - const self = this; - - fn(function(val){ - - if(self.callback){ - - self.callback(val); - // self.callback = null; - // self = null; - } - }); - } - - /** - * @param {Function} callback - */ - - SimplePromise.prototype.then = function(callback){ - - this.callback = callback; - }; - - promise = SimplePromise; - } +if (POLYFILL) { + Object.assign || + (Object.assign = function () { + const args = arguments; + const size = args.length; + const obj = args[0]; + + for (let x = 1, current, keys, length; x < size; x++) { + current = args[x]; + keys = Object.keys(current); + length = keys.length; + + for (let i = 0, key; i < length; i++) { + key = keys[i]; + obj[key] = current[key]; + } + } + + return obj; + }); + + // Object.values || (Object.values = function(obj){ + // + // const keys = Object.keys(obj); + // const length = keys.length; + // const values = new Array(length); + // + // for(let x = 0; x < length; x++){ + // + // values[x] = obj[keys[x]]; + // } + // + // return values; + // }); + + if (SUPPORT_ASYNC && !promise) { + /** + * @param {Function} fn + * @constructor + */ + + function SimplePromise(fn) { + this.callback = null; + + const self = this; + + fn(function (val) { + if (self.callback) { + self.callback(val); + // self.callback = null; + // self = null; + } + }); + } + + /** + * @param {Function} callback + */ + + SimplePromise.prototype.then = function (callback) { + this.callback = callback; + }; + + promise = SimplePromise; + } } diff --git a/src/preset.js b/src/preset.js index 42a637a..95227ba 100644 --- a/src/preset.js +++ b/src/preset.js @@ -1,5 +1,5 @@ -import { DEBUG } from "./config.js"; -import { is_string } from "./common.js"; +import { DEBUG } from './config.js'; +import { is_string } from './common.js'; /** * @enum {Object} @@ -7,92 +7,84 @@ import { is_string } from "./common.js"; */ const preset = { - - "memory": { - charset: "latin:extra", - //tokenize: "strict", - resolution: 3, - //threshold: 0, - minlength: 4, - fastupdate: false - }, - - "performance": { - //charset: "latin", - //tokenize: "strict", - resolution: 3, - minlength: 3, - //fastupdate: true, - optimize: false, - //fastupdate: true, - context: { - depth: 2, - resolution: 1 - //bidirectional: false - } - }, - - "match": { - charset: "latin:extra", - tokenize: "reverse", - //resolution: 9, - //threshold: 0 - }, - - "score": { - charset: "latin:advanced", - //tokenize: "strict", - resolution: 20, - minlength: 3, - context: { - depth: 3, - resolution: 9, - //bidirectional: true - } - }, - - "default": { - // charset: "latin:default", - // tokenize: "strict", - // resolution: 3, - // threshold: 0, - // depth: 3 - }, - - // "fast": { - // //charset: "latin", - // //tokenize: "strict", - // threshold: 8, - // resolution: 9, - // depth: 1 - // } + memory: { + charset: 'latin:extra', + //tokenize: "strict", + resolution: 3, + //threshold: 0, + minlength: 4, + fastupdate: false, + }, + + performance: { + //charset: "latin", + //tokenize: "strict", + resolution: 3, + minlength: 3, + //fastupdate: true, + optimize: false, + //fastupdate: true, + context: { + depth: 2, + resolution: 1, + //bidirectional: false + }, + }, + + match: { + charset: 'latin:extra', + tokenize: 'reverse', + //resolution: 9, + //threshold: 0 + }, + + score: { + charset: 'latin:advanced', + //tokenize: "strict", + resolution: 20, + minlength: 3, + context: { + depth: 3, + resolution: 9, + //bidirectional: true + }, + }, + + default: { + // charset: "latin:default", + // tokenize: "strict", + // resolution: 3, + // threshold: 0, + // depth: 3 + }, + + // "fast": { + // //charset: "latin", + // //tokenize: "strict", + // threshold: 8, + // resolution: 9, + // depth: 1 + // } }; -export default function apply_preset(options){ - - if(is_string(options)){ - - if(DEBUG && !preset[options]){ - - console.warn("Preset not found: " + options); - } - - options = preset[options]; - } - else{ - - const preset = options["preset"]; - - if(preset){ +export default function apply_preset(options) { + if (is_string(options)) { + if (DEBUG && !preset[options]) { + console.warn('Preset not found: ' + options); + } - if(DEBUG && !preset[preset]){ + options = preset[options]; + } else { + const preset = options['preset']; - console.warn("Preset not found: " + preset); - } + if (preset) { + if (DEBUG && !preset[preset]) { + console.warn('Preset not found: ' + preset); + } - options = Object.assign({}, preset[preset], /** @type {Object} */ (options)); - } - } + options = Object.assign({}, preset[preset], /** @type {Object} */ (options)); + } + } - return options; -} \ No newline at end of file + return options; +} diff --git a/src/serialize.js b/src/serialize.js index 072e8c5..5aeb161 100644 --- a/src/serialize.js +++ b/src/serialize.js @@ -1,250 +1,206 @@ // TODO return promises instead of inner await -import { IndexInterface, DocumentInterface } from "./type.js"; -import { create_object, is_string } from "./common.js"; - -function async(callback, self, field, key, index_doc, index, data){ - - setTimeout(function(){ - - const res = callback(field ? field + "." + key : key, JSON.stringify(data)); - - // await isn't supported by ES5 - - if(res && res["then"]){ - - res["then"](function(){ - - self.export(callback, self, field, index_doc, index + 1); - }) - } - else{ - - self.export(callback, self, field, index_doc, index + 1); - } - }); +import { create_object, is_string } from './common.js'; + +function async(callback, self, field, key, index_doc, index, data) { + setTimeout(function () { + const res = callback(field ? field + '.' + key : key, JSON.stringify(data)); + + // await isn't supported by ES5 + + if (res && res['then']) { + res['then'](function () { + self.export(callback, self, field, index_doc, index + 1); + }); + } else { + self.export(callback, self, field, index_doc, index + 1); + } + }); } /** - * @this IndexInterface + * @this import('./type').IndexInterface */ -export function exportIndex(callback, self, field, index_doc, index){ - - let key, data; - - switch(index || (index = 0)){ - - case 0: - - key = "reg"; - - // fastupdate isn't supported by export - - if(this.fastupdate){ +export function exportIndex(callback, self, field, index_doc, index) { + let key, data; - data = create_object(); + switch (index || (index = 0)) { + case 0: + key = 'reg'; - for(let key in this.register){ + // fastupdate isn't supported by export - data[key] = 1; - } - } - else{ + if (this.fastupdate) { + data = create_object(); - data = this.register; - } + for (let key in this.register) { + data[key] = 1; + } + } else { + data = this.register; + } - break; + break; - case 1: + case 1: + key = 'cfg'; + data = { + doc: 0, + opt: this.optimize ? 1 : 0, + }; - key = "cfg"; - data = { - "doc": 0, - "opt": this.optimize ? 1 : 0 - }; + break; - break; + case 2: + key = 'map'; + data = this.map; + break; - case 2: + case 3: + key = 'ctx'; + data = this.ctx; + break; - key = "map"; - data = this.map; - break; + default: + return; + } - case 3: + async(callback, self || this, field, key, index_doc, index, data); - key = "ctx"; - data = this.ctx; - break; - - default: - - return; - } - - async(callback, self || this, field, key, index_doc, index, data); - - return true; + return true; } /** - * @this IndexInterface + * @this import('./type').IndexInterface */ -export function importIndex(key, data){ - - if(!data){ - - return; - } - - if(is_string(data)){ +export function importIndex(key, data) { + if (!data) { + return; + } - data = JSON.parse(data); - } + if (is_string(data)) { + data = JSON.parse(data); + } - switch(key){ + switch (key) { + case 'cfg': + this.optimize = !!data['opt']; + break; - case "cfg": + case 'reg': + // fastupdate isn't supported by import - this.optimize = !!data["opt"]; - break; + this.fastupdate = false; + this.register = data; + break; - case "reg": + case 'map': + this.map = data; + break; - // fastupdate isn't supported by import - - this.fastupdate = false; - this.register = data; - break; - - case "map": - - this.map = data; - break; - - case "ctx": - - this.ctx = data; - break; - } + case 'ctx': + this.ctx = data; + break; + } } /** - * @this DocumentInterface + * @this import('./type.js').DocumentInterface */ -export function exportDocument(callback, self, field, index_doc, index){ - - index || (index = 0); - index_doc || (index_doc = 0); - - if(index_doc < this.field.length){ - - const field = this.field[index_doc]; - const idx = this.index[field]; - - self = this; - - setTimeout(function(){ - - if(!idx.export(callback, self, index ? field/*.replace(":", "-")*/ : "", index_doc, index++)){ - - index_doc++; - index = 1; - - self.export(callback, self, field, index_doc, index); - } - }); - } - else{ - - let key, data; - - switch(index){ - - case 1: - - key = "tag"; - data = this.tagindex; - break; - - case 2: - - key = "store"; - data = this.store; - break; - - // case 3: - // - // key = "reg"; - // data = this.register; - // break; - - default: - - return; - } - - async(callback, this, field, key, index_doc, index, data); - } +export function exportDocument(callback, self, field, index_doc, index) { + index || (index = 0); + index_doc || (index_doc = 0); + + if (index_doc < this.field.length) { + const field = this.field[index_doc]; + const idx = this.index[field]; + + self = this; + + setTimeout(function () { + if ( + !idx.export(callback, self, index ? field /*.replace(":", "-")*/ : '', index_doc, index++) + ) { + index_doc++; + index = 1; + + self.export(callback, self, field, index_doc, index); + } + }); + } else { + let key, data; + + switch (index) { + case 1: + key = 'tag'; + data = this.tagindex; + break; + + case 2: + key = 'store'; + data = this.store; + break; + + // case 3: + // + // key = "reg"; + // data = this.register; + // break; + + default: + return; + } + + async(callback, this, field, key, index_doc, index, data); + } } /** - * @this DocumentInterface + * @this import('./type.js').DocumentInterface */ -export function importDocument(key, data){ - - if(!data){ - - return; - } - - if(is_string(data)){ - - data = JSON.parse(data); - } - - switch(key){ - - case "tag": - - this.tagindex = data; - break; - - case "reg": - - // fastupdate isn't supported by import - - this.fastupdate = false; - this.register = data; +export function importDocument(key, data) { + if (!data) { + return; + } - for(let i = 0, index; i < this.field.length; i++){ + if (is_string(data)) { + data = JSON.parse(data); + } - index = this.index[this.field[i]]; - index.register = data; - index.fastupdate = false; - } + switch (key) { + case 'tag': + this.tagindex = data; + break; - break; + case 'reg': + // fastupdate isn't supported by import - case "store": + this.fastupdate = false; + this.register = data; - this.store = data; - break; + for (let i = 0, index; i < this.field.length; i++) { + index = this.index[this.field[i]]; + index.register = data; + index.fastupdate = false; + } - default: + break; - key = key.split("."); - const field = key[0]; - key = key[1]; + case 'store': + this.store = data; + break; - if(field && key){ + default: + key = key.split('.'); + const field = key[0]; + key = key[1]; - this.index[field].import(key, data); - } - } + if (field && key) { + this.index[field].import(key, data); + } + } } diff --git a/src/type.js b/src/type.js index f6acd1b..1fe5913 100644 --- a/src/type.js +++ b/src/type.js @@ -2,12 +2,11 @@ * @interface */ -export function IndexInterface(){ - - this.cache = null; - this.matcher = null; - this.stemmer = null; - this.filter = null; +export function IndexInterface() { + this.cache = null; + this.matcher = null; + this.stemmer = null; + this.filter = null; } /** @@ -60,10 +59,9 @@ IndexInterface.prototype.remove; * @interface */ -export function DocumentInterface(){ - - this.field = null; +export function DocumentInterface() { + this.field = null; - /** @type IndexInterface */ - this.index = null; + /** @type IndexInterface */ + this.index = null; } diff --git a/src/webpack.js b/src/webpack.js index 6951481..cc1f9f5 100644 --- a/src/webpack.js +++ b/src/webpack.js @@ -1,13 +1,20 @@ -import { SUPPORT_ASYNC, SUPPORT_DOCUMENT, SUPPORT_CACHE, SUPPORT_SERIALIZE, SUPPORT_WORKER, SUPPORT_ENCODER } from "./config.js"; -import Document from "./document.js"; -import Index from "./index.js"; -import WorkerIndex from "./worker/index.js"; -import { registerCharset, registerLanguage } from "./global.js"; -import charset_default from "./lang/latin/default.js" -import charset_simple from "./lang/latin/simple.js" -import charset_balance from "./lang/latin/balance.js" -import charset_advanced from "./lang/latin/advanced.js" -import charset_extra from "./lang/latin/extra.js" +import { + SUPPORT_ASYNC, + SUPPORT_DOCUMENT, + SUPPORT_CACHE, + SUPPORT_SERIALIZE, + SUPPORT_WORKER, + SUPPORT_ENCODER, +} from './config.js'; +import Document from './document.js'; +import Index from './index.js'; +import WorkerIndex from './worker/index.js'; +import { registerCharset, registerLanguage } from './global.js'; +import charset_default from './lang/latin/default.js'; +import charset_simple from './lang/latin/simple.js'; +import charset_balance from './lang/latin/balance.js'; +import charset_advanced from './lang/latin/advanced.js'; +import charset_extra from './lang/latin/extra.js'; /** @export */ Document.prototype.add; /** @export */ Document.prototype.append; @@ -25,68 +32,57 @@ import charset_extra from "./lang/latin/extra.js" /** @export */ Index.prototype.remove; /** @export */ Index.prototype.contain; -if(SUPPORT_CACHE){ - -/** @export */ Index.prototype.searchCache; -/** @export */ Document.prototype.searchCache; +if (SUPPORT_CACHE) { + /** @export */ Index.prototype.searchCache; + /** @export */ Document.prototype.searchCache; } -if(SUPPORT_ASYNC){ - -/** @export */ Document.prototype.addAsync; -/** @export */ Document.prototype.appendAsync; -/** @export */ Document.prototype.searchAsync; -/** @export */ Document.prototype.updateAsync; -/** @export */ Document.prototype.removeAsync; - -/** @export */ Index.prototype.addAsync; -/** @export */ Index.prototype.appendAsync; -/** @export */ Index.prototype.searchAsync; -/** @export */ Index.prototype.updateAsync; -/** @export */ Index.prototype.removeAsync; +if (SUPPORT_ASYNC) { + /** @export */ Document.prototype.addAsync; + /** @export */ Document.prototype.appendAsync; + /** @export */ Document.prototype.searchAsync; + /** @export */ Document.prototype.updateAsync; + /** @export */ Document.prototype.removeAsync; + + /** @export */ Index.prototype.addAsync; + /** @export */ Index.prototype.appendAsync; + /** @export */ Index.prototype.searchAsync; + /** @export */ Index.prototype.updateAsync; + /** @export */ Index.prototype.removeAsync; } -if(SUPPORT_SERIALIZE){ - -/** @export */ Index.prototype.export; -/** @export */ Index.prototype.import; -/** @export */ Document.prototype.export; -/** @export */ Document.prototype.import; +if (SUPPORT_SERIALIZE) { + /** @export */ Index.prototype.export; + /** @export */ Index.prototype.import; + /** @export */ Document.prototype.export; + /** @export */ Document.prototype.import; } -if(SUPPORT_ENCODER){ - - registerCharset("latin:default", charset_default); - registerCharset("latin:simple", charset_simple); - registerCharset("latin:balance", charset_balance); - registerCharset("latin:advanced", charset_advanced); - registerCharset("latin:extra", charset_extra); +if (SUPPORT_ENCODER) { + registerCharset('latin:default', charset_default); + registerCharset('latin:simple', charset_simple); + registerCharset('latin:balance', charset_balance); + registerCharset('latin:advanced', charset_advanced); + registerCharset('latin:extra', charset_extra); } const root = self; let tmp; const FlexSearch = { - - "Index": Index, - "Document": SUPPORT_DOCUMENT ? Document : null, - "Worker": SUPPORT_WORKER ? WorkerIndex : null, - "registerCharset": registerCharset, - "registerLanguage": registerLanguage + Index: Index, + Document: SUPPORT_DOCUMENT ? Document : null, + Worker: SUPPORT_WORKER ? WorkerIndex : null, + registerCharset: registerCharset, + registerLanguage: registerLanguage, }; -if((tmp = root["define"]) && tmp["amd"]){ - - tmp([], function(){ - - return FlexSearch; - }); -} -else if(root["exports"]){ - - root["exports"] = FlexSearch; -} -else{ - - root["FlexSearch"] = FlexSearch; +if ((tmp = root['define']) && tmp['amd']) { + tmp([], function () { + return FlexSearch; + }); +} else if (root['exports']) { + root['exports'] = FlexSearch; +} else { + root['FlexSearch'] = FlexSearch; } diff --git a/src/worker/handler.js b/src/worker/handler.js index b63c847..5cbf153 100644 --- a/src/worker/handler.js +++ b/src/worker/handler.js @@ -1,51 +1,43 @@ -import Index from "../index.js"; +import Index from '../index.js'; -export default function(data) { +export default function (data) { + data = data['data']; - data = data["data"]; + /** @type Index */ + const index = self['_index']; + const args = data['args']; + const task = data['task']; - /** @type Index */ - const index = self["_index"]; - const args = data["args"]; - const task = data["task"]; + switch (task) { + case 'init': + const options = data['options'] || {}; + const factory = data['factory']; + const encode = options['encode']; - switch(task){ + options['cache'] = false; - case "init": + if (encode && encode.indexOf('function') === 0) { + options['encode'] = Function('return ' + encode)(); + } - const options = data["options"] || {}; - const factory = data["factory"]; - const encode = options["encode"]; + if (factory) { + // export the FlexSearch global payload to "self" + Function('return ' + factory)()(self); - options["cache"] = false; + /** @type Index */ + self['_index'] = new self['FlexSearch']['Index'](options); - if(encode && (encode.indexOf("function") === 0)){ + // destroy the exported payload + delete self['FlexSearch']; + } else { + self['_index'] = new Index(options); + } - options["encode"] = Function("return " + encode)(); - } + break; - if(factory){ - - // export the FlexSearch global payload to "self" - Function("return " + factory)()(self); - - /** @type Index */ - self["_index"] = new self["FlexSearch"]["Index"](options); - - // destroy the exported payload - delete self["FlexSearch"]; - } - else{ - - self["_index"] = new Index(options); - } - - break; - - default: - - const id = data["id"]; - const message = index[task].apply(index, args); - postMessage(task === "search" ? { "id": id, "msg": message } : { "id": id }); - } -}; + default: + const id = data['id']; + const message = index[task].apply(index, args); + postMessage(task === 'search' ? { id: id, msg: message } : { id: id }); + } +} diff --git a/src/worker/index.js b/src/worker/index.js index 7f0723c..cf3fdde 100644 --- a/src/worker/index.js +++ b/src/worker/index.js @@ -1,6 +1,6 @@ //import { promise as Promise } from "../polyfill.js"; -import { create_object, is_function, is_object, is_string } from "../common.js"; -import handler from "./handler.js"; +import { create_object, is_function, is_string } from '../common.js'; +import handler from './handler.js'; let pid = 0; @@ -9,149 +9,114 @@ let pid = 0; * @constructor */ -function WorkerIndex(options){ - - if(!(this instanceof WorkerIndex)) { - - return new WorkerIndex(options); - } - - let opt; - - if(options){ - - if(is_function(opt = options["encode"])){ - - options["encode"] = opt.toString(); - } - } - else{ - - options = {}; - } - - // the factory is the outer wrapper from the build - // we use "self" as a trap for node.js - - let factory = (self||window)["_factory"]; - - if(factory){ - - factory = factory.toString(); - } - - const is_node_js = typeof window === "undefined" && self["exports"]; - const _self = this; - - this.worker = create(factory, is_node_js, options["worker"]); - this.resolver = create_object(); - - if(!this.worker){ - - return; - } - - if(is_node_js){ - - this.worker["on"]("message", function(msg){ - - _self.resolver[msg["id"]](msg["msg"]) ; - delete _self.resolver[msg["id"]]; - }); - } - else{ - - this.worker.onmessage = function(msg){ - - msg = msg["data"]; - _self.resolver[msg["id"]](msg["msg"]); - delete _self.resolver[msg["id"]]; - }; - } - - this.worker.postMessage({ - - "task": "init", - "factory": factory, - "options": options - }); +function WorkerIndex(options) { + if (!(this instanceof WorkerIndex)) { + return new WorkerIndex(options); + } + + let opt; + + if (options) { + if (is_function((opt = options['encode']))) { + options['encode'] = opt.toString(); + } + } else { + options = {}; + } + + // the factory is the outer wrapper from the build + // we use "self" as a trap for node.js + + let factory = (self || window)['_factory']; + + if (factory) { + factory = factory.toString(); + } + + const is_node_js = typeof window === 'undefined' && self['exports']; + const _self = this; + + this.worker = create(factory, is_node_js, options['worker']); + this.resolver = create_object(); + + if (!this.worker) { + return; + } + + if (is_node_js) { + this.worker['on']('message', function (msg) { + _self.resolver[msg['id']](msg['msg']); + delete _self.resolver[msg['id']]; + }); + } else { + this.worker.onmessage = function (msg) { + msg = msg['data']; + _self.resolver[msg['id']](msg['msg']); + delete _self.resolver[msg['id']]; + }; + } + + this.worker.postMessage({ + task: 'init', + factory: factory, + options: options, + }); } export default WorkerIndex; -register("add"); -register("append"); -register("search"); -register("update"); -register("remove"); - -function register(key){ - - WorkerIndex.prototype[key] = - WorkerIndex.prototype[key + "Async"] = function(){ - - const self = this; - const args = [].slice.call(arguments); - const arg = args[args.length - 1]; - let callback; - - if(is_function(arg)){ - - callback = arg; - args.splice(args.length - 1, 1); - } - - const promise = new Promise(function(resolve){ - - setTimeout(function(){ - - self.resolver[++pid] = resolve; - self.worker.postMessage({ - - "task": key, - "id": pid, - "args": args - }); - }); - }); - - if(callback){ - - promise.then(callback); - return this; - } - else{ - - return promise; - } - }; +register('add'); +register('append'); +register('search'); +register('update'); +register('remove'); + +function register(key) { + WorkerIndex.prototype[key] = WorkerIndex.prototype[key + 'Async'] = function () { + const self = this; + const args = [].slice.call(arguments); + const arg = args[args.length - 1]; + let callback; + + if (is_function(arg)) { + callback = arg; + args.splice(args.length - 1, 1); + } + + const promise = new Promise(function (resolve) { + setTimeout(function () { + self.resolver[++pid] = resolve; + self.worker.postMessage({ + task: key, + id: pid, + args: args, + }); + }); + }); + + if (callback) { + promise.then(callback); + return this; + } else { + return promise; + } + }; } -function create(factory, is_node_js, worker_path){ - - let worker - - try{ - - worker = is_node_js ? - - eval('new (require("worker_threads")["Worker"])("../dist/node/node.js")') - :( - factory ? - - new Worker(URL.createObjectURL( - - new Blob([ - - "onmessage=" + handler.toString() - - ], { "type": "text/javascript" }) - )) - : - new Worker(is_string(worker_path) ? worker_path : "worker/worker.js", { type: "module" }) - ); - } - catch(e){} - - return worker; -} \ No newline at end of file +function create(factory, is_node_js, worker_path) { + let worker; + + try { + worker = is_node_js + ? eval('new (require("worker_threads")["Worker"])("../dist/node/node.js")') + : factory + ? new Worker( + URL.createObjectURL( + new Blob(['onmessage=' + handler.toString()], { type: 'text/javascript' }) + ) + ) + : new Worker(is_string(worker_path) ? worker_path : 'worker/worker.js', { type: 'module' }); + } catch (e) {} + + return worker; +} diff --git a/src/worker/node.js b/src/worker/node.js index 4e1a20b..f7b30e3 100644 --- a/src/worker/node.js +++ b/src/worker/node.js @@ -1,35 +1,30 @@ -const { parentPort } = require("worker_threads"); -const { Index } = require("../flexsearch.bundle.js"); +const { parentPort } = require('worker_threads'); +const { Index } = require('../flexsearch.bundle.js'); let index; -parentPort.on("message", function(data){ +parentPort.on('message', function (data) { + /** @type Index */ + const args = data['args']; + const task = data['task']; + const id = data['id']; - /** @type Index */ - const args = data["args"]; - const task = data["task"]; - const id = data["id"]; + switch (task) { + case 'init': + const options = data['options'] || {}; + const encode = options['encode']; - switch(task){ + options['cache'] = false; - case "init": + if (encode && encode.indexOf('function') === 0) { + options['encode'] = new Function('return ' + encode)(); + } - const options = data["options"] || {}; - const encode = options["encode"]; + index = new Index(options); + break; - options["cache"] = false; - - if(encode && (encode.indexOf("function") === 0)){ - - options["encode"] = new Function("return " + encode)(); - } - - index = new Index(options); - break; - - default: - - const message = index[task].apply(index, args); - parentPort.postMessage(task === "search" ? { "id": id, "msg": message } : { "id": id }); - } + default: + const message = index[task].apply(index, args); + parentPort.postMessage(task === 'search' ? { id: id, msg: message } : { id: id }); + } }); diff --git a/src/worker/worker.js b/src/worker/worker.js index 4772d6c..5a0cae4 100644 --- a/src/worker/worker.js +++ b/src/worker/worker.js @@ -1,2 +1,2 @@ -import handler from "./handler.js"; +import handler from './handler.js'; onmessage = handler; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..b153a9b --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,7 @@ +{ + "extends": "mauss/tsconfig.json", + "compilerOptions": { + "noEmit": true + }, + "include": ["src/**/*"] +}