UNPKG

@fal-ai/client

Version:

The fal.ai client for JavaScript and TypeScript

225 lines 11.4 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __rest = (this && this.__rest) || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.createQueueClient = void 0; const request_1 = require("./request"); const response_1 = require("./response"); const streaming_1 = require("./streaming"); const utils_1 = require("./utils"); const DEFAULT_POLL_INTERVAL = 500; const createQueueClient = ({ config, storage, }) => { const ref = { submit(endpointId, options) { return __awaiter(this, void 0, void 0, function* () { const { webhookUrl, priority } = options, runOptions = __rest(options, ["webhookUrl", "priority"]); const input = options.input ? yield storage.transformInput(options.input) : undefined; return (0, request_1.dispatchRequest)({ method: options.method, targetUrl: (0, request_1.buildUrl)(endpointId, Object.assign(Object.assign({}, runOptions), { subdomain: "queue", query: webhookUrl ? { fal_webhook: webhookUrl } : undefined })), headers: { "x-fal-queue-priority": priority !== null && priority !== void 0 ? priority : "normal", }, input: input, config, options: { signal: options.abortSignal, }, }); }); }, status(endpointId_1, _a) { return __awaiter(this, arguments, void 0, function* (endpointId, { requestId, logs = false, abortSignal }) { const appId = (0, utils_1.parseEndpointId)(endpointId); const prefix = appId.namespace ? `${appId.namespace}/` : ""; return (0, request_1.dispatchRequest)({ method: "get", targetUrl: (0, request_1.buildUrl)(`${prefix}${appId.owner}/${appId.alias}`, { subdomain: "queue", query: { logs: logs ? "1" : "0" }, path: `/requests/${requestId}/status`, }), config, options: { signal: abortSignal, }, }); }); }, streamStatus(endpointId_1, _a) { return __awaiter(this, arguments, void 0, function* (endpointId, { requestId, logs = false, connectionMode }) { const appId = (0, utils_1.parseEndpointId)(endpointId); const prefix = appId.namespace ? `${appId.namespace}/` : ""; const queryParams = { logs: logs ? "1" : "0", }; const url = (0, request_1.buildUrl)(`${prefix}${appId.owner}/${appId.alias}`, { subdomain: "queue", path: `/requests/${requestId}/status/stream`, query: queryParams, }); return new streaming_1.FalStream(endpointId, config, { url, method: "get", connectionMode, queryParams, }); }); }, subscribeToStatus(endpointId, options) { return __awaiter(this, void 0, void 0, function* () { const requestId = options.requestId; const timeout = options.timeout; let timeoutId = undefined; const handleCancelError = () => { // Ignore errors as the client will follow through with the timeout // regardless of the server response. In case cancelation fails, we // still want to reject the promise and consider the client call canceled. }; if (options.mode === "streaming") { const status = yield ref.streamStatus(endpointId, { requestId, logs: options.logs, connectionMode: "connectionMode" in options ? options.connectionMode : undefined, }); const logs = []; if (timeout) { timeoutId = setTimeout(() => { status.abort(); ref.cancel(endpointId, { requestId }).catch(handleCancelError); // TODO this error cannot bubble up to the user since it's thrown in // a closure in the global scope due to setTimeout behavior. // User will get a platform error instead. We should find a way to // make this behavior aligned with polling. throw new Error(`Client timed out waiting for the request to complete after ${timeout}ms`); }, timeout); } status.on("data", (data) => { if (options.onQueueUpdate) { // accumulate logs to match previous polling behavior if ("logs" in data && Array.isArray(data.logs) && data.logs.length > 0) { logs.push(...data.logs); } options.onQueueUpdate("logs" in data ? Object.assign(Object.assign({}, data), { logs }) : data); } }); const doneStatus = yield status.done(); if (timeoutId) { clearTimeout(timeoutId); } return doneStatus; } // default to polling until status streaming is stable and faster return new Promise((resolve, reject) => { var _a; let pollingTimeoutId; // type resolution isn't great in this case, so check for its presence // and and type so the typechecker behaves as expected const pollInterval = "pollInterval" in options && typeof options.pollInterval === "number" ? ((_a = options.pollInterval) !== null && _a !== void 0 ? _a : DEFAULT_POLL_INTERVAL) : DEFAULT_POLL_INTERVAL; const clearScheduledTasks = () => { if (timeoutId) { clearTimeout(timeoutId); } if (pollingTimeoutId) { clearTimeout(pollingTimeoutId); } }; if (timeout) { timeoutId = setTimeout(() => { clearScheduledTasks(); ref.cancel(endpointId, { requestId }).catch(handleCancelError); reject(new Error(`Client timed out waiting for the request to complete after ${timeout}ms`)); }, timeout); } const poll = () => __awaiter(this, void 0, void 0, function* () { var _a; try { const requestStatus = yield ref.status(endpointId, { requestId, logs: (_a = options.logs) !== null && _a !== void 0 ? _a : false, abortSignal: options.abortSignal, }); if (options.onQueueUpdate) { options.onQueueUpdate(requestStatus); } if (requestStatus.status === "COMPLETED") { clearScheduledTasks(); resolve(requestStatus); return; } pollingTimeoutId = setTimeout(poll, pollInterval); } catch (error) { clearScheduledTasks(); reject(error); } }); poll().catch(reject); }); }); }, result(endpointId_1, _a) { return __awaiter(this, arguments, void 0, function* (endpointId, { requestId, abortSignal }) { const appId = (0, utils_1.parseEndpointId)(endpointId); const prefix = appId.namespace ? `${appId.namespace}/` : ""; return (0, request_1.dispatchRequest)({ method: "get", targetUrl: (0, request_1.buildUrl)(`${prefix}${appId.owner}/${appId.alias}`, { subdomain: "queue", path: `/requests/${requestId}`, }), config: Object.assign(Object.assign({}, config), { responseHandler: response_1.resultResponseHandler }), options: { signal: abortSignal, }, }); }); }, cancel(endpointId_1, _a) { return __awaiter(this, arguments, void 0, function* (endpointId, { requestId, abortSignal }) { const appId = (0, utils_1.parseEndpointId)(endpointId); const prefix = appId.namespace ? `${appId.namespace}/` : ""; yield (0, request_1.dispatchRequest)({ method: "put", targetUrl: (0, request_1.buildUrl)(`${prefix}${appId.owner}/${appId.alias}`, { subdomain: "queue", path: `/requests/${requestId}/cancel`, }), config, options: { signal: abortSignal, }, }); }); }, }; return ref; }; exports.createQueueClient = createQueueClient; //# sourceMappingURL=queue.js.map