resources/Jobs.js

import { PollTimeout } from "../error.js";
import { constructParams } from "../util.js";
function mapAsset(a) {
    return {
        ...a,
        created: new Date(a.created),
        modified: new Date(a.modified),
    };
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function* iterOwn(m) {
    for (const [k, v] of Object.entries(m)) {
        if (Object.hasOwn(m, k))
            yield [k, v];
    }
}
function mapIO(io) {
    const obj = { params: io.params };
    if (io.assets) {
        const assets = Object.fromEntries(Array.from(iterOwn(io.assets)).map(([k, v]) => [k, mapAsset(v)]));
        obj.assets = assets;
    }
    return obj;
}
function job(j) {
    return {
        ...j,
        created: new Date(j.created),
        started: j.started ? new Date(j.started) : null,
        finished: j.finished ? new Date(j.finished) : null,
        inputs: mapIO(j.inputs),
        outputs: mapIO(j.outputs),
        assets: j.assets?.map(mapAsset)
    };
}
/** Metafold jobs endpoint. */
export class Jobs {
    client;
    constructor(client) {
        this.client = client;
    }
    /**
     * List jobs.
     *
     * @param {Object} [params] - Optional list parameters.
     * @param {string} [params.sort] - Sort string. For details on syntax see the Metafold API docs.
     *   Supported sorting fields are: "id", "name", "created", "started", or "finished".
     * @param {string} [params.q] - Query string. For details on syntax see the Metafold API docs.
     *   Supported search fields are: "id", "name", "type", and "state".
     * @returns List of job resources.
     */
    async list({ sort, q } = {}) {
        const params = constructParams({ sort, q });
        const r = await this.client.get(`/projects/${this.client.projectID}/jobs`, { params });
        return r.data.map(job);
    }
    /**
     * Get a job.
     *
     * @param {string} id - ID of job to get.
     * @returns Job resource.
     */
    async get(id) {
        const r = await this.client.get(`/projects/${this.client.projectID}/jobs/${id}`);
        return job(r.data);
    }
    /**
     * Dispatch a new job and wait for the result.
     *
     * See Metafold API docs for the full list of jobs.
     *
     * @param {string} type - Job type.
     * @param {Object} params - Job parameters.
     * @param {string} [name] - Job name.
     * @param {number} [timeout=12000] - Time in seconds to wait for a result.
     * @returns Completed job resource.
     */
    async run(type, params, name, timeout = 1000 * 60 * 2) {
        const url = await this.runStatus(type, params, name);
        let r = null;
        try {
            r = await this.client.poll(url, timeout, 1);
        }
        catch (e) {
            if (e instanceof PollTimeout) {
                throw new Error(`Job '${name ?? type}' failed to complete within ${timeout} ms`, { cause: e });
            }
            else {
                throw e;
            }
        }
        return job(r.data);
    }
    /**
     * Poll the given URL every one second.
     *
     * Helpful for waiting on job results given a status URL.
     *
     * @param {string} url - Workflow status url.
     * @param {number} [timeout=12000] - Time in seconds to wait for a result.
     * @param {number} [every=1] - Frequency in seconds.
     * @returns HTTP response.
     *
     * @deprecated Use Client.poll instead.
     */
    poll(url, timeout = 1000 * 60 * 2, every = 1) {
        console.warn("Jobs.poll is deprecated, please use Client.poll instead");
        return this.client.poll(url, timeout, every);
    }
    /**
     * Dispatch a new job and return immediately without waiting for result.
     *
     * See Metafold API docs for the full list of jobs.
     *
     * @param {string} type - Job type.
     * @param {Object} params - Job parameters.
     * @param {string} [name] - Job name.
     * @returns {string} Job status url.
     */
    async runStatus(type, params, name) {
        const data = constructParams({ type, parameters: params, name });
        const r = await this.client.post(`/projects/${this.client.projectID}/jobs`, data, {
            headers: { "Content-Type": "application/json" },
        });
        return r.data.link;
    }
    /**
     * Update a job.
     *
     * @param {string} id - ID of job to update.
     * @param {Object} [params] - Optional update parameters.
     * @param {string} [params.name] - New job name. The existing name remains unchanged if undefined.
     * @returns Updated job resource.
     */
    async update(id, { name } = {}) {
        const data = constructParams({ name });
        const r = await this.client.patch(`/projects/${this.client.projectID}/jobs/${id}`, data);
        return job(r.data);
    }
}