import { MeiliSearchTimeOutError } from "./errors"; import { Config, WaitOptions, TaskStatus, TasksQuery, TasksResults, TaskObject, CancelTasksQuery, TasksResultsObject, DeleteTasksQuery, } from "./types"; import { HttpRequests, toQueryParams } from "./http-requests"; import { sleep } from "./utils"; import { EnqueuedTask } from "./enqueued-task"; class Task { indexUid: TaskObject["indexUid"]; status: TaskObject["status"]; type: TaskObject["type"]; uid: TaskObject["uid"]; canceledBy: TaskObject["canceledBy"]; details: TaskObject["details"]; error: TaskObject["error"]; duration: TaskObject["duration"]; startedAt: Date; enqueuedAt: Date; finishedAt: Date; constructor(task: TaskObject) { this.indexUid = task.indexUid; this.status = task.status; this.type = task.type; this.uid = task.uid; this.details = task.details; this.canceledBy = task.canceledBy; this.error = task.error; this.duration = task.duration; this.startedAt = new Date(task.startedAt); this.enqueuedAt = new Date(task.enqueuedAt); this.finishedAt = new Date(task.finishedAt); } } class TaskClient { httpRequest: HttpRequests; constructor(config: Config) { this.httpRequest = new HttpRequests(config); } /** * Get one task * * @param uid - Unique identifier of the task * @returns */ async getTask(uid: number): Promise { const url = `tasks/${uid}`; const taskItem = await this.httpRequest.get(url); return new Task(taskItem); } /** * Get tasks * * @param parameters - Parameters to browse the tasks * @returns Promise containing all tasks */ async getTasks(parameters: TasksQuery = {}): Promise { const url = `tasks`; const tasks = await this.httpRequest.get>( url, toQueryParams(parameters), ); return { ...tasks, results: tasks.results.map((task) => new Task(task)), }; } /** * Wait for a task to be processed. * * @param taskUid - Task identifier * @param options - Additional configuration options * @returns Promise returning a task after it has been processed */ async waitForTask( taskUid: number, { timeOutMs = 5000, intervalMs = 50 }: WaitOptions = {}, ): Promise { const startingTime = Date.now(); while (Date.now() - startingTime < timeOutMs) { const response = await this.getTask(taskUid); if ( !( [ TaskStatus.TASK_ENQUEUED, TaskStatus.TASK_PROCESSING, ] as readonly string[] ).includes(response.status) ) return response; await sleep(intervalMs); } throw new MeiliSearchTimeOutError( `timeout of ${timeOutMs}ms has exceeded on process ${taskUid} when waiting a task to be resolved.`, ); } /** * Waits for multiple tasks to be processed * * @param taskUids - Tasks identifier list * @param options - Wait options * @returns Promise returning a list of tasks after they have been processed */ async waitForTasks( taskUids: number[], { timeOutMs = 5000, intervalMs = 50 }: WaitOptions = {}, ): Promise { const tasks: Task[] = []; for (const taskUid of taskUids) { const task = await this.waitForTask(taskUid, { timeOutMs, intervalMs, }); tasks.push(task); } return tasks; } /** * Cancel a list of enqueued or processing tasks. * * @param parameters - Parameters to filter the tasks. * @returns Promise containing an EnqueuedTask */ async cancelTasks(parameters: CancelTasksQuery = {}): Promise { const url = `tasks/cancel`; const task = await this.httpRequest.post( url, {}, toQueryParams(parameters), ); return new EnqueuedTask(task); } /** * Delete a list tasks. * * @param parameters - Parameters to filter the tasks. * @returns Promise containing an EnqueuedTask */ async deleteTasks(parameters: DeleteTasksQuery = {}): Promise { const url = `tasks`; const task = await this.httpRequest.delete( url, {}, toQueryParams(parameters), ); return new EnqueuedTask(task); } } export { TaskClient, Task };