Upstream Pagefind/pagefind state of the touched files before f1eedafd11
This commit is contained in:
1 parent
b572112ae7
commit
1308f3c1bb
10 files changed
+1706
-79
No files matched your search
@@ -0,0 +1,303 @@
|
||||
import { PagefindService } from "./service.js";
|
||||
import { decode } from "./encoding.js";
|
||||
|
||||
/**
|
||||
* @typedef {import('pagefindInternal').InternalResponseCallback} InternalResponseCallback
|
||||
* @typedef {import('pagefindInternal').InternalResponsePayload} InternalResponsePayload
|
||||
*/
|
||||
|
||||
/**
|
||||
* @type {PagefindService?}
|
||||
*/
|
||||
let persistentService;
|
||||
const launch = () => {
|
||||
if (!persistentService) {
|
||||
persistentService = new PagefindService();
|
||||
}
|
||||
return persistentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* @template T
|
||||
* @param {function(any): void} resolve
|
||||
* @param {function(any): void} reject
|
||||
* @param {InternalResponseCallback} response_callback
|
||||
* @param {function(InternalResponsePayload): T} resultFn
|
||||
*/
|
||||
const handleApiResponse = (resolve, reject, { exception, err, result }, resultFn) => {
|
||||
if (exception) {
|
||||
reject(exception);
|
||||
} else {
|
||||
resolve({
|
||||
errors: err ? [err.message] : [],
|
||||
...(result ? resultFn(result) : {})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import('pagefindService').NewIndexResponse} NewIndexResponse
|
||||
*
|
||||
* @param {import('pagefindService').PagefindServiceConfig=} config
|
||||
* @type {import('pagefindService').createIndex}
|
||||
* */
|
||||
export const createIndex = (config) => new Promise((resolve, reject) => {
|
||||
|
||||
// TODO: Validate `config` here, instead of waiting for the backend to throw an error.
|
||||
// Ideally we create a global Pagefind config JSON schema that (a subset of) can be used here.
|
||||
|
||||
const action = 'NewIndex';
|
||||
launch().sendMessage(
|
||||
{
|
||||
type: action,
|
||||
config: {
|
||||
root_selector: config?.rootSelector,
|
||||
exclude_selectors: config?.excludeSelectors,
|
||||
force_language: config?.forceLanguage,
|
||||
verbose: config?.verbose,
|
||||
logfile: config?.logfile,
|
||||
keep_index_url: config?.keepIndexUrl,
|
||||
write_playground: config?.writePlayground,
|
||||
include_characters: config?.includeCharacters,
|
||||
}
|
||||
}, (response) => {
|
||||
/** @type {function(InternalResponsePayload): Omit<NewIndexResponse, 'errors'>?} */
|
||||
const successCallback = (success) => {
|
||||
if (success.type !== action) {
|
||||
reject(`Message returned from backend should have been ${action}, but was ${success.type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
index: indexFns(success.index_id),
|
||||
}
|
||||
};
|
||||
handleApiResponse(resolve, reject, response, successCallback);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {import('pagefindService').close}
|
||||
*/
|
||||
export const close = () => new Promise((resolve, reject) => {
|
||||
persistentService?.close(null);
|
||||
persistentService = null;
|
||||
resolve(null);
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {number} indexId
|
||||
* @returns {import ('pagefindService').PagefindIndex}
|
||||
*/
|
||||
const indexFns = (indexId) => {
|
||||
return {
|
||||
addHTMLFile: (file) => addHTMLFile(indexId, file),
|
||||
addCustomRecord: (record) => addCustomRecord(indexId, record),
|
||||
addDirectory: (dir) => addDirectory(indexId, dir),
|
||||
writeFiles: (options) => writeFiles(indexId, options),
|
||||
getFiles: () => getFiles(indexId),
|
||||
deleteIndex: () => deleteIndex(indexId)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import('pagefindService').NewFileResponse} NewFileResponse
|
||||
*
|
||||
* @param {number} indexId
|
||||
* @param {import('pagefindService').HTMLFile} file
|
||||
* @returns {Promise<NewFileResponse>}
|
||||
*/
|
||||
const addHTMLFile = (indexId, file) => new Promise((resolve, reject) => {
|
||||
const action = 'AddFile';
|
||||
const responseAction = 'IndexedFile';
|
||||
launch().sendMessage(
|
||||
{
|
||||
type: action,
|
||||
index_id: indexId,
|
||||
file_path: file.sourcePath,
|
||||
url: file.url,
|
||||
file_contents: file.content
|
||||
}, (response) => {
|
||||
/** @type {function(InternalResponsePayload): Omit<NewFileResponse, 'errors'>?} */
|
||||
const successCallback = (success) => {
|
||||
if (success.type !== responseAction) {
|
||||
reject(`Message returned from backend should have been ${action}, but was ${success.type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
file: {
|
||||
uniqueWords: success.page_word_count,
|
||||
url: success.page_url,
|
||||
meta: success.page_meta,
|
||||
}
|
||||
}
|
||||
};
|
||||
handleApiResponse(resolve, reject, response, successCallback);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {number} indexId
|
||||
* @param {import('pagefindService').CustomRecord} record
|
||||
* @returns {Promise<NewFileResponse>}
|
||||
*/
|
||||
const addCustomRecord = (indexId, record) => new Promise((resolve, reject) => {
|
||||
const action = 'AddRecord';
|
||||
const responseAction = 'IndexedFile';
|
||||
launch().sendMessage(
|
||||
{
|
||||
type: action,
|
||||
index_id: indexId,
|
||||
url: record.url,
|
||||
content: record.content,
|
||||
language: record.language,
|
||||
meta: record.meta,
|
||||
filters: record.filters,
|
||||
sort: record.sort,
|
||||
}, (response) => {
|
||||
/** @type {function(InternalResponsePayload): Omit<NewFileResponse, 'errors'>?} */
|
||||
const successCallback = (success) => {
|
||||
if (success.type !== responseAction) {
|
||||
reject(`Message returned from backend should have been ${action}, but was ${success.type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
file: {
|
||||
uniqueWords: success.page_word_count,
|
||||
url: success.page_url,
|
||||
meta: success.page_meta,
|
||||
}
|
||||
}
|
||||
};
|
||||
handleApiResponse(resolve, reject, response, successCallback);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {import('pagefindService').IndexingResponse} IndexingResponse
|
||||
*
|
||||
* @param {number} indexId
|
||||
* @param {import('pagefindService').SiteDirectory} dir
|
||||
* @returns {Promise<IndexingResponse>}
|
||||
*/
|
||||
const addDirectory = (indexId, dir) => new Promise((resolve, reject) => {
|
||||
const action = 'AddDir';
|
||||
const responseAction = 'IndexedDir';
|
||||
launch().sendMessage(
|
||||
{
|
||||
type: action,
|
||||
index_id: indexId,
|
||||
path: dir.path,
|
||||
glob: dir.glob
|
||||
}, (response) => {
|
||||
/** @type {function(InternalResponsePayload): Omit<IndexingResponse, 'errors'>?} */
|
||||
const successCallback = (success) => {
|
||||
if (success.type !== responseAction) {
|
||||
reject(`Message returned from backend should have been ${action}, but was ${success.type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
page_count: success.page_count
|
||||
}
|
||||
};
|
||||
handleApiResponse(resolve, reject, response, successCallback);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* @typedef {import ('pagefindService').WriteFilesResponse} WriteFilesResponse
|
||||
*
|
||||
* @param {number} indexId
|
||||
* @param {import('pagefindService').WriteOptions=} options
|
||||
* @returns {Promise<WriteFilesResponse>}
|
||||
*/
|
||||
const writeFiles = (indexId, options) => new Promise((resolve, reject) => {
|
||||
const action = 'WriteFiles';
|
||||
launch().sendMessage(
|
||||
{
|
||||
type: action,
|
||||
index_id: indexId,
|
||||
output_path: options?.outputPath
|
||||
}, (response) => {
|
||||
/** @type {function(InternalResponsePayload): Omit<WriteFilesResponse, 'errors'>?} */
|
||||
const successCallback = (success) => {
|
||||
if (success.type !== action) {
|
||||
reject(`Message returned from backend should have been ${action}, but was ${success.type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
outputPath: success.output_path
|
||||
}
|
||||
};
|
||||
handleApiResponse(resolve, reject, response, successCallback);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* @typedef {import ('pagefindService').GetFilesResponse} GetFilesResponse
|
||||
*
|
||||
* @param {number} indexId
|
||||
* @returns {Promise<GetFilesResponse>}
|
||||
*/
|
||||
const getFiles = (indexId) => new Promise((resolve, reject) => {
|
||||
const action = 'GetFiles';
|
||||
launch().sendMessage(
|
||||
{
|
||||
type: action,
|
||||
index_id: indexId,
|
||||
}, (response) => {
|
||||
/** @type {function(InternalResponsePayload): Omit<GetFilesResponse, 'errors'>?} */
|
||||
const successCallback = (success) => {
|
||||
if (success.type !== action) {
|
||||
reject(`Message returned from backend should have been ${action}, but was ${success.type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
files: success.files.map(file => {
|
||||
return {
|
||||
path: file.path,
|
||||
content: decode(file.content)
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
handleApiResponse(resolve, reject, response, successCallback);
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {number} indexId
|
||||
* @returns {Promise<null>}
|
||||
*/
|
||||
const deleteIndex = (indexId) => new Promise((resolve, reject) => {
|
||||
const action = 'DeleteIndex';
|
||||
launch().sendMessage(
|
||||
{
|
||||
type: action,
|
||||
index_id: indexId,
|
||||
}, (response) => {
|
||||
/** @type {function(InternalResponsePayload): Omit<GetFilesResponse, 'errors'>?} */
|
||||
const successCallback = (success) => {
|
||||
if (success.type !== action) {
|
||||
reject(`Message returned from backend should have been ${action}, but was ${success.type}`);
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
handleApiResponse(resolve, reject, response, successCallback);
|
||||
}
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user