meilisearch
Version:
The Meilisearch JS client for Node.js and the browser.
126 lines • 5.05 kB
JavaScript
import { MeiliSearchTaskTimeOutError } from "./errors/index.js";
/**
* Used to identify whether an error is a timeout error in
* {@link TaskClient.waitForTask}.
*/
const TIMEOUT_ID = Symbol("<task timeout>");
/**
* @returns A function which defines an extra function property on a
* {@link Promise}, which resolves to {@link EnqueuedTask}, which awaits it and
* resolves to a {@link Task}.
*/
function getWaitTaskApplier(taskClient) {
return function (enqueuedTaskPromise) {
return Object.defineProperty(enqueuedTaskPromise, "waitTask", {
async value(waitOptions) {
return await taskClient.waitForTask(await enqueuedTaskPromise, waitOptions);
},
});
};
}
const getTaskUid = (taskUidOrEnqueuedTask) => typeof taskUidOrEnqueuedTask === "number"
? taskUidOrEnqueuedTask
: taskUidOrEnqueuedTask.taskUid;
/**
* Class for handling tasks.
*
* @see {@link https://www.meilisearch.com/docs/reference/api/tasks}
*/
export class TaskClient {
#httpRequest;
#defaultTimeout;
#defaultInterval;
#applyWaitTask;
constructor(httpRequest, defaultWaitOptions) {
this.#httpRequest = httpRequest;
this.#defaultTimeout = defaultWaitOptions?.timeout ?? 5_000;
this.#defaultInterval = defaultWaitOptions?.interval ?? 50;
this.#applyWaitTask = getWaitTaskApplier(this);
}
/** {@link https://www.meilisearch.com/docs/reference/api/tasks#get-one-task} */
async getTask(uid,
// TODO: Need to do this for all other methods: https://github.com/meilisearch/meilisearch-js/issues/1476
extraRequestInit) {
return await this.#httpRequest.get({
path: `tasks/${uid}`,
extraRequestInit,
});
}
/** {@link https://www.meilisearch.com/docs/reference/api/tasks#get-tasks} */
async getTasks(params) {
return await this.#httpRequest.get({ path: "tasks", params });
}
/**
* Wait for an enqueued task to be processed. This is done through polling
* with {@link TaskClient.getTask}.
*
* @remarks
* If an {@link EnqueuedTask} needs to be awaited instantly, it is recommended
* to instead use {@link EnqueuedTaskPromise.waitTask}, which is available on
* any method that returns an {@link EnqueuedTaskPromise}.
*/
async waitForTask(taskUidOrEnqueuedTask, options) {
const taskUid = getTaskUid(taskUidOrEnqueuedTask);
const timeout = options?.timeout ?? this.#defaultTimeout;
const interval = options?.interval ?? this.#defaultInterval;
const ac = timeout > 0 ? new AbortController() : null;
const toId = ac !== null
? setTimeout(() => void ac.abort(TIMEOUT_ID), timeout)
: undefined;
try {
for (;;) {
const task = await this.getTask(taskUid, { signal: ac?.signal });
if (task.status !== "enqueued" && task.status !== "processing") {
clearTimeout(toId);
return task;
}
if (interval > 0) {
await new Promise((resolve) => setTimeout(resolve, interval));
}
}
}
catch (error) {
throw Object.is(error.cause, TIMEOUT_ID)
? new MeiliSearchTaskTimeOutError(taskUid, timeout)
: error;
}
}
/**
* Lazily wait for multiple enqueued tasks to be processed.
*
* @remarks
* In this case {@link WaitOptions.timeout} is the maximum time to wait for any
* one task, not for all of the tasks to complete.
*/
async *waitForTasksIter(taskUidsOrEnqueuedTasks, options) {
for await (const taskUidOrEnqueuedTask of taskUidsOrEnqueuedTasks) {
yield await this.waitForTask(taskUidOrEnqueuedTask, options);
}
}
/** Wait for multiple enqueued tasks to be processed. */
async waitForTasks(...params) {
const tasks = [];
for await (const task of this.waitForTasksIter(...params)) {
tasks.push(task);
}
return tasks;
}
/** {@link https://www.meilisearch.com/docs/reference/api/tasks#cancel-tasks} */
cancelTasks(params) {
return this.#applyWaitTask(this.#httpRequest.post({ path: "tasks/cancel", params }));
}
/** {@link https://www.meilisearch.com/docs/reference/api/tasks#delete-tasks} */
deleteTasks(params) {
return this.#applyWaitTask(this.#httpRequest.delete({ path: "tasks", params }));
}
}
export function getHttpRequestsWithEnqueuedTaskPromise(httpRequest, taskClient) {
const applyWaitTask = getWaitTaskApplier(taskClient);
return {
post: (...params) => applyWaitTask(httpRequest.post(...params)),
put: (...params) => applyWaitTask(httpRequest.put(...params)),
patch: (...params) => applyWaitTask(httpRequest.patch(...params)),
delete: (...params) => applyWaitTask(httpRequest.delete(...params)),
};
}
//# sourceMappingURL=task.js.map