@fal-ai/client
Version:
The fal.ai client for JavaScript and TypeScript
135 lines • 4.73 kB
JavaScript
;
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());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ensureEndpointIdFormat = ensureEndpointIdFormat;
exports.parseEndpointId = parseEndpointId;
exports.resolveEndpointPath = resolveEndpointPath;
exports.isValidUrl = isValidUrl;
exports.throttle = throttle;
exports.isReact = isReact;
exports.isPlainObject = isPlainObject;
exports.sleep = sleep;
function ensureEndpointIdFormat(id) {
const parts = id.split("/");
if (parts.length > 1) {
return id;
}
const [, appOwner, appId] = /^([0-9]+)-([a-zA-Z0-9-]+)$/.exec(id) || [];
if (appOwner && appId) {
return `${appOwner}/${appId}`;
}
throw new Error(`Invalid app id: ${id}. Must be in the format <appOwner>/<appId>`);
}
const ENDPOINT_NAMESPACES = ["workflows", "comfy"];
function parseEndpointId(id) {
const normalizedId = ensureEndpointIdFormat(id);
const parts = normalizedId.split("/");
if (ENDPOINT_NAMESPACES.includes(parts[0])) {
return {
owner: parts[1],
alias: parts[2],
path: parts.slice(3).join("/") || undefined,
namespace: parts[0],
};
}
return {
owner: parts[0],
alias: parts[1],
path: parts.slice(2).join("/") || undefined,
};
}
/**
* Resolves the endpoint path, normalizing it and applying a default.
* If no explicit path is provided and the app already ends with the
* default path, returns undefined to avoid duplication.
*
* @param app - The app/endpoint identifier
* @param path - An explicitly provided path (always used if present)
* @param defaultPath - The default path to use (e.g. "/realtime")
* @returns The resolved path, or undefined if the app already includes it
*/
function resolveEndpointPath(app, path, defaultPath) {
if (path) {
return `/${path.replace(/^\/+/, "")}`;
}
if (app.endsWith(defaultPath)) {
return undefined;
}
return defaultPath;
}
function isValidUrl(url) {
try {
const { host } = new URL(url);
return /(fal\.(ai|run))$/.test(host);
}
catch (_) {
return false;
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function throttle(func, limit, leading = false) {
let lastFunc;
let lastRan;
return (...args) => {
if (!lastRan && leading) {
func(...args);
lastRan = Date.now();
}
else {
if (lastFunc) {
clearTimeout(lastFunc);
}
lastFunc = setTimeout(() => {
if (Date.now() - lastRan >= limit) {
func(...args);
lastRan = Date.now();
}
}, limit - (Date.now() - lastRan));
}
};
}
let isRunningInReact;
/**
* Not really the most optimal way to detect if we're running in React,
* but the idea here is that we can support multiple rendering engines
* (starting with React), with all their peculiarities, without having
* to add a dependency or creating custom integrations (e.g. custom hooks).
*
* Yes, a bit of magic to make things works out-of-the-box.
* @returns `true` if running in React, `false` otherwise.
*/
function isReact() {
if (isRunningInReact === undefined) {
const stack = new Error().stack;
isRunningInReact =
!!stack &&
(stack.includes("node_modules/react-dom/") ||
stack.includes("node_modules/next/"));
}
return isRunningInReact;
}
/**
* Check if a value is a plain object.
* @param value - The value to check.
* @returns `true` if the value is a plain object, `false` otherwise.
*/
function isPlainObject(value) {
return !!value && Object.getPrototypeOf(value) === Object.prototype;
}
/**
* Utility function to sleep for a given number of milliseconds
*/
function sleep(ms) {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve) => setTimeout(resolve, ms));
});
}
//# sourceMappingURL=utils.js.map