diff --git a/pagefind/src/lib.rs b/pagefind/src/lib.rs index 403a7675..73f235c3 100644 --- a/pagefind/src/lib.rs +++ b/pagefind/src/lib.rs @@ -1,6 +1,6 @@ use std::{cmp::Ordering, path::PathBuf}; -use anyhow::{bail, Result}; +use anyhow::{bail, Result, anyhow}; use fossick::{FossickedData, Fossicker}; use futures::future::join_all; use hashbrown::HashMap; @@ -27,6 +27,10 @@ mod utils; const PAGEFIND_VERSION: &str = env!("CARGO_PKG_VERSION"); +pub struct IndexCatalogueRepresentation { + entries: Vec<(String, String)> +} + struct SearchState { options: SearchOptions, fossicked_pages: Vec, @@ -312,6 +316,19 @@ impl SearchState { outdir } + pub async fn get_index_catalogue(&self) -> Result { + if self.built_indexes.is_empty() { + return Err(anyhow!("Indexes empty, are they built yet? (run get_files/write_files)")); + } + let entries: Vec<(String, String)> = self + .built_indexes + .iter() + .map(|indexes| indexes.fragments.clone() + .into_iter() + ).flatten().collect(); + Ok(IndexCatalogueRepresentation { entries }) + } + pub async fn get_files(&self) -> Vec { let outdir = &self.options.bundle_output; diff --git a/pagefind/src/service/api.rs b/pagefind/src/service/api.rs index 8df40cf3..825c90c8 100644 --- a/pagefind/src/service/api.rs +++ b/pagefind/src/service/api.rs @@ -41,7 +41,7 @@ use std::{collections::BTreeMap, path::PathBuf}; use crate::{ fossick::{parser::DomParserResult, Fossicker}, options::PagefindServiceConfig, - PagefindInboundConfig, SearchOptions, SearchState, + PagefindInboundConfig, SearchOptions, SearchState, IndexCatalogueRepresentation, }; #[derive(Debug)] @@ -208,6 +208,14 @@ impl PagefindIndex { self.search_index.build_indexes().await?; Ok(self.search_index.get_files().await) } + + /// Get the catalogue mappings from hashes to encoded data. + /// + /// # Returns + /// An IndexCatalogueRepresentation containing the hash and content of each fragment. + pub async fn get_index_catalogue(&mut self) -> Result { + self.search_index.get_index_catalogue().await + } } #[cfg(test)] diff --git a/pagefind/src/service/mod.rs b/pagefind/src/service/mod.rs index 41d772ad..ee4c5109 100644 --- a/pagefind/src/service/mod.rs +++ b/pagefind/src/service/mod.rs @@ -222,6 +222,19 @@ pub async fn run_service() { } } } + RequestAction::GetIndexCatalogue { index_id } => { + if let Some(index) = get_index(&mut indexes, index_id, err) { + match index.get_index_catalogue().await { + Ok(index_catalogue) => { + send(ResponseAction::GetIndexCatalogue { + entry_count: index_catalogue.entries.len(), + entries: index_catalogue.entries, + }) + } + Err(e) => err(&e.to_string()), + } + } + } RequestAction::GetFiles { index_id } => { if let Some(index) = get_index(&mut indexes, index_id, err) { match index.build_indexes().await { diff --git a/pagefind/src/service/requests.rs b/pagefind/src/service/requests.rs index 83654fc0..1f0dac76 100644 --- a/pagefind/src/service/requests.rs +++ b/pagefind/src/service/requests.rs @@ -46,6 +46,9 @@ pub(super) enum RequestAction { GetFiles { index_id: u32, }, + GetIndexCatalogue { + index_id: u32, + }, DeleteIndex { index_id: u32, }, diff --git a/pagefind/src/service/responses.rs b/pagefind/src/service/responses.rs index e021d081..8166afbe 100644 --- a/pagefind/src/service/responses.rs +++ b/pagefind/src/service/responses.rs @@ -33,6 +33,10 @@ pub(super) enum ResponseAction { GetFiles { files: Vec, }, + GetIndexCatalogue { + entries: Vec<(String, String)>, + entry_count: usize, + }, DeleteIndex {}, } diff --git a/wrappers/node/lib/index.js b/wrappers/node/lib/index.js index 48993ca5..b6ff5727 100644 --- a/wrappers/node/lib/index.js +++ b/wrappers/node/lib/index.js @@ -96,6 +96,7 @@ const indexFns = (indexId) => { addDirectory: (dir) => addDirectory(indexId, dir), writeFiles: (options) => writeFiles(indexId, options), getFiles: () => getFiles(indexId), + getIndexCatalogue: () => getIndexCatalogue(indexId), deleteIndex: () => deleteIndex(indexId) } } @@ -276,6 +277,36 @@ const getFiles = (indexId) => new Promise((resolve, reject) => { ); }); +/** + * @typedef {import ('pagefindService').GetIndexCatalogueResponse} GetIndexCatalogueResponse + * + * @param {number} indexId + * @returns {Promise} + */ +const getIndexCatalogue = (indexId) => new Promise((resolve, reject) => { + const action = 'GetIndexCatalogue'; + launch().sendMessage( + { + type: action, + index_id: indexId, + }, (response) => { + /** @type {function(InternalResponsePayload): Omit?} */ + const successCallback = (success) => { + if (success.type !== action) { + reject(`Message returned from backend should have been ${action}, but was ${success.type}`); + return null; + } + + return { + entries: success.entries, + entryCount: success.entry_count + } + }; + handleApiResponse(resolve, reject, response, successCallback); + } + ); +}); + /** * @param {number} indexId * @returns {Promise}