diff --git a/src/assets/javascripts/modules/search/_/index.ts b/src/assets/javascripts/modules/search/_/index.ts index 7681fd3db..3d1455195 100644 --- a/src/assets/javascripts/modules/search/_/index.ts +++ b/src/assets/javascripts/modules/search/_/index.ts @@ -70,7 +70,7 @@ export interface SearchIndex { config: SearchIndexConfig /* Search index configuration */ docs: SearchIndexDocument[] /* Search index documents */ options?: SearchIndexOptions /* Search index options */ - index?: object /* Prebuilt index */ + index?: object | string /* Prebuilt or serialized index */ } /* ------------------------------------------------------------------------- */ @@ -149,9 +149,13 @@ export class Search { this.add(doc) }) - /* Prebuilt index */ + /* Prebuilt or serialized index */ } else { - this.index = lunr.Index.load(index) + this.index = lunr.Index.load( + typeof index === "string" + ? JSON.parse(index) + : index + ) } } @@ -174,7 +178,7 @@ export class Search { public search(query: string): SearchResult[] { const groups = this.index.search(query) - /* Group sections results by article */ + /* Group sections by containing article */ .reduce((results, result) => { const document = this.documents.get(result.ref) if (typeof document !== "undefined") { @@ -201,9 +205,9 @@ export class Search { /** * Serialize index * - * @return JSON representation + * @return String representation */ - public toJSON(): object { - return this.index.toJSON() + public toString(): string { + return JSON.stringify(this.index) } } diff --git a/src/assets/javascripts/workers/index.ts b/src/assets/javascripts/workers/index.ts index 22bd0bc2c..978da95fa 100644 --- a/src/assets/javascripts/workers/index.ts +++ b/src/assets/javascripts/workers/index.ts @@ -20,5 +20,5 @@ * IN THE SOFTWARE. */ -export { PackerMessage, PackerMessageType } from "./packer" -export { SearchMessage, SearchMessageType } from "./search" +export * from "./packer" +export * from "./search" diff --git a/src/assets/javascripts/workers/packer/_/index.ts b/src/assets/javascripts/workers/packer/_/index.ts new file mode 100644 index 000000000..657da1d64 --- /dev/null +++ b/src/assets/javascripts/workers/packer/_/index.ts @@ -0,0 +1,61 @@ + +/* + * Copyright (c) 2016-2019 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Types + * ------------------------------------------------------------------------- */ + +/** + * Packer message type + */ +export const enum PackerMessageType { + STRING, /* String data */ + PACKED /* Packed data */ +} + +/* ------------------------------------------------------------------------- */ + +/** + * A message containing an unpacked string + */ +interface StringMessage { + type: PackerMessageType.STRING /* Message type */ + data: string /* Message data */ +} + +/** + * A message containing a packed string + */ +interface PackedMessage { + type: PackerMessageType.PACKED /* Message type */ + data: string /* Message data */ +} + +/* ------------------------------------------------------------------------- */ + +/** + * A message exchanged with the packer worker + */ +export type PackerMessage = + | StringMessage + | PackedMessage diff --git a/src/assets/javascripts/workers/packer/index.ts b/src/assets/javascripts/workers/packer/index.ts index 81dd14937..d41a92f82 100644 --- a/src/assets/javascripts/workers/packer/index.ts +++ b/src/assets/javascripts/workers/packer/index.ts @@ -1,4 +1,3 @@ - /* * Copyright (c) 2016-2019 Martin Donath * @@ -21,81 +20,4 @@ * IN THE SOFTWARE. */ -import { compress, decompress } from "lz-string" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Packer message type - */ -export const enum PackerMessageType { - STRING, /* String data */ - PACKED /* Packed data */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * A message containing an unpacked string - */ -interface StringMessage { - type: PackerMessageType.STRING /* Message type */ - data: string /* Message data */ -} - -/** - * A message containing a packed string - */ -interface PackedMessage { - type: PackerMessageType.PACKED /* Message type */ - data: string /* Message data */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * A message exchanged with the packer worker - */ -export type PackerMessage = - | StringMessage - | PackedMessage - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Message handler - * - * @param message - Source message - * - * @return Target message - */ -export function handler(message: PackerMessage): PackerMessage { - switch (message.type) { - - /* Pack an unpacked string */ - case PackerMessageType.STRING: - return { - type: PackerMessageType.PACKED, - data: compress(message.data) - } - - /* Unpack a packed string */ - case PackerMessageType.PACKED: - return { - type: PackerMessageType.STRING, - data: decompress(message.data) - } - } -} - -/* ---------------------------------------------------------------------------- - * Worker - * ------------------------------------------------------------------------- */ - -addEventListener("message", ev => { - postMessage(handler(ev.data)) -}) +export * from "./_" diff --git a/src/assets/javascripts/workers/packer/main/index.ts b/src/assets/javascripts/workers/packer/main/index.ts new file mode 100644 index 000000000..284b94e58 --- /dev/null +++ b/src/assets/javascripts/workers/packer/main/index.ts @@ -0,0 +1,64 @@ + +/* + * Copyright (c) 2016-2019 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import { compress, decompress } from "lz-string" + +import { PackerMessage, PackerMessageType } from "../_" + +/* ---------------------------------------------------------------------------- + * Functions + * ------------------------------------------------------------------------- */ + +/** + * Message handler + * + * @param message - Source message + * + * @return Target message + */ +export function handler(message: PackerMessage): PackerMessage { + switch (message.type) { + + /* Pack an unpacked string */ + case PackerMessageType.STRING: + return { + type: PackerMessageType.PACKED, + data: compress(message.data) + } + + /* Unpack a packed string */ + case PackerMessageType.PACKED: + return { + type: PackerMessageType.STRING, + data: decompress(message.data) + } + } +} + +/* ---------------------------------------------------------------------------- + * Worker + * ------------------------------------------------------------------------- */ + +addEventListener("message", ev => { + postMessage(handler(ev.data)) +}) diff --git a/src/assets/javascripts/workers/search/_/index.ts b/src/assets/javascripts/workers/search/_/index.ts new file mode 100644 index 000000000..178d62468 --- /dev/null +++ b/src/assets/javascripts/workers/search/_/index.ts @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2016-2019 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import { SearchIndex, SearchResult } from "../../../modules" + +/* ---------------------------------------------------------------------------- + * Types + * ------------------------------------------------------------------------- */ + +/** + * Search message type + */ +export const enum SearchMessageType { + SETUP, /* Search index setup */ + DUMP, /* Search index dump */ + QUERY, /* Search query */ + RESULT /* Search results */ +} + +/* ------------------------------------------------------------------------- */ + +/** + * A message containing the data necessary to setup the search index + */ +interface SetupMessage { + type: SearchMessageType.SETUP /* Message type */ + data: SearchIndex /* Message data */ +} + +/** + * A message containing the a dump of the search index + */ +interface DumpMessage { + type: SearchMessageType.DUMP /* Message type */ + data: string /* Message data */ +} + +/** + * A message containing a search query + */ +interface QueryMessage { + type: SearchMessageType.QUERY /* Message type */ + data: string /* Message data */ +} + +/** + * A message containing results for a search query + */ +interface ResultMessage { + type: SearchMessageType.RESULT /* Message type */ + data: SearchResult[] /* Message data */ +} + +/* ------------------------------------------------------------------------- */ + +/** + * A message exchanged with the search worker + */ +export type SearchMessage = + | SetupMessage + | DumpMessage + | QueryMessage + | ResultMessage diff --git a/src/assets/javascripts/workers/search/index.ts b/src/assets/javascripts/workers/search/index.ts index d6a56d5f7..d41a92f82 100644 --- a/src/assets/javascripts/workers/search/index.ts +++ b/src/assets/javascripts/workers/search/index.ts @@ -13,122 +13,11 @@ * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ -import { Search, SearchIndex, SearchResult } from "../../modules" - -/* ---------------------------------------------------------------------------- - * Types - * ------------------------------------------------------------------------- */ - -/** - * Search message type - */ -export const enum SearchMessageType { - SETUP, /* Search index setup */ - DUMP, /* Search index dump */ - QUERY, /* Search query */ - RESULT /* Search results */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * A message containing the data necessary to setup the search index - */ -interface SetupMessage { - type: SearchMessageType.SETUP /* Message type */ - data: SearchIndex /* Message data */ -} - -/** - * A message containing the a dump of the search index - */ -interface DumpMessage { - type: SearchMessageType.DUMP /* Message type */ - data: object /* Message data */ -} - -/** - * A message containing a search query - */ -interface QueryMessage { - type: SearchMessageType.QUERY /* Message type */ - data: string /* Message data */ -} - -/** - * A message containing results for a search query - */ -interface ResultMessage { - type: SearchMessageType.RESULT /* Message type */ - data: SearchResult[] /* Message data */ -} - -/* ------------------------------------------------------------------------- */ - -/** - * A message exchanged with the search worker - */ -export type SearchMessage = - | SetupMessage - | DumpMessage - | QueryMessage - | ResultMessage - -/* ---------------------------------------------------------------------------- - * Data - * ------------------------------------------------------------------------- */ - -/** - * Search index - */ -let index: Search - -/* ---------------------------------------------------------------------------- - * Functions - * ------------------------------------------------------------------------- */ - -/** - * Message handler - * - * @param message - Source message - * - * @return Target message - */ -export function handler(message: SearchMessage): SearchMessage { - switch (message.type) { - - /* Setup search index */ - case SearchMessageType.SETUP: - index = new Search(message.data) - return { - type: SearchMessageType.DUMP, - data: index.toJSON() - } - - /* Query search index */ - case SearchMessageType.QUERY: - return { - type: SearchMessageType.RESULT, - data: index.search(message.data) - } - - /* All other messages */ - default: - throw new TypeError("Invalid message type") - } -} - -/* ---------------------------------------------------------------------------- - * Worker - * ------------------------------------------------------------------------- */ - -addEventListener("message", ev => { - postMessage(handler(ev.data)) -}) +export * from "./_" diff --git a/src/assets/javascripts/workers/search/main/index.ts b/src/assets/javascripts/workers/search/main/index.ts new file mode 100644 index 000000000..9aed6dddd --- /dev/null +++ b/src/assets/javascripts/workers/search/main/index.ts @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2016-2019 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import { Search } from "../../../modules" +import { SearchMessage, SearchMessageType } from "../_" + +/* ---------------------------------------------------------------------------- + * Data + * ------------------------------------------------------------------------- */ + +/** + * Search index + */ +let index: Search + +/* ---------------------------------------------------------------------------- + * Functions + * ------------------------------------------------------------------------- */ + +/** + * Message handler + * + * @param message - Source message + * + * @return Target message + */ +export function handler(message: SearchMessage): SearchMessage { + switch (message.type) { + + /* Setup search index */ + case SearchMessageType.SETUP: + index = new Search(message.data) + return { + type: SearchMessageType.DUMP, + data: index.toString() + } + + /* Query search index */ + case SearchMessageType.QUERY: + return { + type: SearchMessageType.RESULT, + data: index.search(message.data) + } + + /* All other messages */ + default: + throw new TypeError("Invalid message type") + } +} + +/* ---------------------------------------------------------------------------- + * Worker + * ------------------------------------------------------------------------- */ + +addEventListener("message", ev => { + postMessage(handler(ev.data)) +}) diff --git a/webpack.config.ts b/webpack.config.ts index 8c7b69937..b018714c8 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -109,7 +109,7 @@ export default (_env: never, args: Configuration): Configuration[] => ([ /* Search worker */ { ...config(args), - entry: "src/assets/javascripts/workers/search", + entry: "src/assets/javascripts/workers/search/main", output: { path: path.resolve(__dirname, "material/assets/javascripts"), filename: "search.js", @@ -120,7 +120,7 @@ export default (_env: never, args: Configuration): Configuration[] => ([ /* Packer worker */ { ...config(args), - entry: "src/assets/javascripts/workers/packer", + entry: "src/assets/javascripts/workers/packer/main", output: { path: path.resolve(__dirname, "material/assets/javascripts"), filename: "packer.js",