Spaces:
Paused
Paused
var __defProp = Object.defineProperty; | |
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | |
var __publicField = (obj, key, value) => { | |
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | |
return value; | |
}; | |
var __accessCheck = (obj, member, msg) => { | |
if (!member.has(obj)) | |
throw TypeError("Cannot " + msg); | |
}; | |
var __privateGet = (obj, member, getter) => { | |
__accessCheck(obj, member, "read from private field"); | |
return getter ? getter.call(obj) : member.get(obj); | |
}; | |
var __privateAdd = (obj, member, value) => { | |
if (member.has(obj)) | |
throw TypeError("Cannot add the same private member more than once"); | |
member instanceof WeakSet ? member.add(obj) : member.set(obj, value); | |
}; | |
var __privateSet = (obj, member, value, setter) => { | |
__accessCheck(obj, member, "write to private field"); | |
setter ? setter.call(obj, value) : member.set(obj, value); | |
return value; | |
}; | |
var _currentLine; | |
var fn = new Intl.Collator(0, { numeric: 1 }).compare; | |
function semiver(a, b, bool) { | |
a = a.split("."); | |
b = b.split("."); | |
return fn(a[0], b[0]) || fn(a[1], b[1]) || (b[2] = b.slice(2).join("."), bool = /[.-]/.test(a[2] = a.slice(2).join(".")), bool == /[.-]/.test(b[2]) ? fn(a[2], b[2]) : bool ? -1 : 1); | |
} | |
const HOST_URL = "host"; | |
const UPLOAD_URL = "upload"; | |
const LOGIN_URL = "login"; | |
const CONFIG_URL = "config"; | |
const API_INFO_URL = "info"; | |
const RUNTIME_URL = "runtime"; | |
const SLEEPTIME_URL = "sleeptime"; | |
const SPACE_FETCHER_URL = "https://gradio-space-api-fetcher-v2.hf.space/api"; | |
const QUEUE_FULL_MSG = "This application is currently busy. Please try again. "; | |
const BROKEN_CONNECTION_MSG = "Connection errored out. "; | |
const CONFIG_ERROR_MSG = "Could not resolve app config. "; | |
const SPACE_STATUS_ERROR_MSG = "Could not get space status. "; | |
const API_INFO_ERROR_MSG = "Could not get API info. "; | |
const SPACE_METADATA_ERROR_MSG = "Space metadata could not be loaded. "; | |
const INVALID_URL_MSG = "Invalid URL. A full URL path is required."; | |
const UNAUTHORIZED_MSG = "Not authorized to access this space. "; | |
const INVALID_CREDENTIALS_MSG = "Invalid credentials. Could not login. "; | |
const MISSING_CREDENTIALS_MSG = "Login credentials are required to access this space."; | |
const NODEJS_FS_ERROR_MSG = "File system access is only available in Node.js environments"; | |
const ROOT_URL_ERROR_MSG = "Root URL not found in client config"; | |
const FILE_PROCESSING_ERROR_MSG = "Error uploading file"; | |
function resolve_root(base_url, root_path, prioritize_base) { | |
if (root_path.startsWith("http://") || root_path.startsWith("https://")) { | |
return prioritize_base ? base_url : root_path; | |
} | |
return base_url + root_path; | |
} | |
async function get_jwt(space, token, cookies) { | |
try { | |
const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, { | |
headers: { | |
Authorization: `Bearer ${token}`, | |
...cookies ? { Cookie: cookies } : {} | |
} | |
}); | |
const jwt = (await r.json()).token; | |
return jwt || false; | |
} catch (e) { | |
return false; | |
} | |
} | |
function map_names_to_ids(fns) { | |
let apis = {}; | |
fns.forEach(({ api_name, id }) => { | |
if (api_name) | |
apis[api_name] = id; | |
}); | |
return apis; | |
} | |
async function resolve_config(endpoint) { | |
var _a; | |
const headers = this.options.hf_token ? { Authorization: `Bearer ${this.options.hf_token}` } : {}; | |
headers["Content-Type"] = "application/json"; | |
if (typeof window !== "undefined" && window.gradio_config && location.origin !== "http://localhost:9876" && !window.gradio_config.dev_mode) { | |
const path = window.gradio_config.root; | |
const config = window.gradio_config; | |
let config_root = resolve_root(endpoint, config.root, false); | |
config.root = config_root; | |
return { ...config, path }; | |
} else if (endpoint) { | |
const config_url = join_urls(endpoint, CONFIG_URL); | |
const response = await this.fetch(config_url, { | |
headers, | |
credentials: "include" | |
}); | |
if ((response == null ? void 0 : response.status) === 401 && !this.options.auth) { | |
throw new Error(MISSING_CREDENTIALS_MSG); | |
} else if ((response == null ? void 0 : response.status) === 401 && this.options.auth) { | |
throw new Error(INVALID_CREDENTIALS_MSG); | |
} | |
if ((response == null ? void 0 : response.status) === 200) { | |
let config = await response.json(); | |
config.path = config.path ?? ""; | |
config.root = endpoint; | |
(_a = config.dependencies) == null ? void 0 : _a.forEach((dep, i) => { | |
if (dep.id === void 0) { | |
dep.id = i; | |
} | |
}); | |
return config; | |
} else if ((response == null ? void 0 : response.status) === 401) { | |
throw new Error(UNAUTHORIZED_MSG); | |
} | |
throw new Error(CONFIG_ERROR_MSG); | |
} | |
throw new Error(CONFIG_ERROR_MSG); | |
} | |
async function resolve_cookies() { | |
const { http_protocol, host } = await process_endpoint( | |
this.app_reference, | |
this.options.hf_token | |
); | |
try { | |
if (this.options.auth) { | |
const cookie_header = await get_cookie_header( | |
http_protocol, | |
host, | |
this.options.auth, | |
this.fetch, | |
this.options.hf_token | |
); | |
if (cookie_header) | |
this.set_cookies(cookie_header); | |
} | |
} catch (e) { | |
throw Error(e.message); | |
} | |
} | |
async function get_cookie_header(http_protocol, host, auth, _fetch, hf_token) { | |
const formData = new FormData(); | |
formData.append("username", auth == null ? void 0 : auth[0]); | |
formData.append("password", auth == null ? void 0 : auth[1]); | |
let headers = {}; | |
if (hf_token) { | |
headers.Authorization = `Bearer ${hf_token}`; | |
} | |
const res = await _fetch(`${http_protocol}//${host}/${LOGIN_URL}`, { | |
headers, | |
method: "POST", | |
body: formData, | |
credentials: "include" | |
}); | |
if (res.status === 200) { | |
return res.headers.get("set-cookie"); | |
} else if (res.status === 401) { | |
throw new Error(INVALID_CREDENTIALS_MSG); | |
} else { | |
throw new Error(SPACE_METADATA_ERROR_MSG); | |
} | |
} | |
function determine_protocol(endpoint) { | |
if (endpoint.startsWith("http")) { | |
const { protocol, host, pathname } = new URL(endpoint); | |
if (host.endsWith("hf.space")) { | |
return { | |
ws_protocol: "wss", | |
host, | |
http_protocol: protocol | |
}; | |
} | |
return { | |
ws_protocol: protocol === "https:" ? "wss" : "ws", | |
http_protocol: protocol, | |
host: host + (pathname !== "/" ? pathname : "") | |
}; | |
} else if (endpoint.startsWith("file:")) { | |
return { | |
ws_protocol: "ws", | |
http_protocol: "http:", | |
host: "lite.local" | |
// Special fake hostname only used for this case. This matches the hostname allowed in `is_self_host()` in `js/wasm/network/host.ts`. | |
}; | |
} | |
return { | |
ws_protocol: "wss", | |
http_protocol: "https:", | |
host: endpoint | |
}; | |
} | |
const parse_and_set_cookies = (cookie_header) => { | |
let cookies = []; | |
const parts = cookie_header.split(/,(?=\s*[^\s=;]+=[^\s=;]+)/); | |
parts.forEach((cookie) => { | |
const [cookie_name, cookie_value] = cookie.split(";")[0].split("="); | |
if (cookie_name && cookie_value) { | |
cookies.push(`${cookie_name.trim()}=${cookie_value.trim()}`); | |
} | |
}); | |
return cookies; | |
}; | |
const RE_SPACE_NAME = /^[a-zA-Z0-9_\-\.]+\/[a-zA-Z0-9_\-\.]+$/; | |
const RE_SPACE_DOMAIN = /.*hf\.space\/{0,1}$/; | |
async function process_endpoint(app_reference, hf_token) { | |
const headers = {}; | |
if (hf_token) { | |
headers.Authorization = `Bearer ${hf_token}`; | |
} | |
const _app_reference = app_reference.trim().replace(/\/$/, ""); | |
if (RE_SPACE_NAME.test(_app_reference)) { | |
try { | |
const res = await fetch( | |
`https://huggingface.co/api/spaces/${_app_reference}/${HOST_URL}`, | |
{ headers } | |
); | |
const _host = (await res.json()).host; | |
return { | |
space_id: app_reference, | |
...determine_protocol(_host) | |
}; | |
} catch (e) { | |
throw new Error(SPACE_METADATA_ERROR_MSG); | |
} | |
} | |
if (RE_SPACE_DOMAIN.test(_app_reference)) { | |
const { ws_protocol, http_protocol, host } = determine_protocol(_app_reference); | |
return { | |
space_id: host.replace(".hf.space", ""), | |
ws_protocol, | |
http_protocol, | |
host | |
}; | |
} | |
return { | |
space_id: false, | |
...determine_protocol(_app_reference) | |
}; | |
} | |
const join_urls = (...urls) => { | |
try { | |
return urls.reduce((base_url, part) => { | |
base_url = base_url.replace(/\/+$/, ""); | |
part = part.replace(/^\/+/, ""); | |
return new URL(part, base_url + "/").toString(); | |
}); | |
} catch (e) { | |
throw new Error(INVALID_URL_MSG); | |
} | |
}; | |
function transform_api_info(api_info, config, api_map) { | |
const transformed_info = { | |
named_endpoints: {}, | |
unnamed_endpoints: {} | |
}; | |
Object.keys(api_info).forEach((category) => { | |
if (category === "named_endpoints" || category === "unnamed_endpoints") { | |
transformed_info[category] = {}; | |
Object.entries(api_info[category]).forEach( | |
([endpoint, { parameters, returns }]) => { | |
var _a, _b, _c, _d; | |
const dependencyIndex = ((_a = config.dependencies.find( | |
(dep) => dep.api_name === endpoint || dep.api_name === endpoint.replace("/", "") | |
)) == null ? void 0 : _a.id) || api_map[endpoint.replace("/", "")] || -1; | |
const dependencyTypes = dependencyIndex !== -1 ? (_b = config.dependencies.find((dep) => dep.id == dependencyIndex)) == null ? void 0 : _b.types : { continuous: false, generator: false, cancel: false }; | |
if (dependencyIndex !== -1 && ((_d = (_c = config.dependencies.find((dep) => dep.id == dependencyIndex)) == null ? void 0 : _c.inputs) == null ? void 0 : _d.length) !== parameters.length) { | |
const components = config.dependencies.find((dep) => dep.id == dependencyIndex).inputs.map( | |
(input) => { | |
var _a2; | |
return (_a2 = config.components.find((c) => c.id === input)) == null ? void 0 : _a2.type; | |
} | |
); | |
try { | |
components.forEach((comp, idx) => { | |
if (comp === "state") { | |
const new_param = { | |
component: "state", | |
example: null, | |
parameter_default: null, | |
parameter_has_default: true, | |
parameter_name: null, | |
hidden: true | |
}; | |
parameters.splice(idx, 0, new_param); | |
} | |
}); | |
} catch (e) { | |
console.error(e); | |
} | |
} | |
const transform_type = (data, component, serializer, signature_type) => ({ | |
...data, | |
description: get_description(data == null ? void 0 : data.type, serializer), | |
type: get_type(data == null ? void 0 : data.type, component, serializer, signature_type) || "" | |
}); | |
transformed_info[category][endpoint] = { | |
parameters: parameters.map( | |
(p) => transform_type(p, p == null ? void 0 : p.component, p == null ? void 0 : p.serializer, "parameter") | |
), | |
returns: returns.map( | |
(r) => transform_type(r, r == null ? void 0 : r.component, r == null ? void 0 : r.serializer, "return") | |
), | |
type: dependencyTypes | |
}; | |
} | |
); | |
} | |
}); | |
return transformed_info; | |
} | |
function get_type(type, component, serializer, signature_type) { | |
switch (type == null ? void 0 : type.type) { | |
case "string": | |
return "string"; | |
case "boolean": | |
return "boolean"; | |
case "number": | |
return "number"; | |
} | |
if (serializer === "JSONSerializable" || serializer === "StringSerializable") { | |
return "any"; | |
} else if (serializer === "ListStringSerializable") { | |
return "string[]"; | |
} else if (component === "Image") { | |
return signature_type === "parameter" ? "Blob | File | Buffer" : "string"; | |
} else if (serializer === "FileSerializable") { | |
if ((type == null ? void 0 : type.type) === "array") { | |
return signature_type === "parameter" ? "(Blob | File | Buffer)[]" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`; | |
} | |
return signature_type === "parameter" ? "Blob | File | Buffer" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`; | |
} else if (serializer === "GallerySerializable") { | |
return signature_type === "parameter" ? "[(Blob | File | Buffer), (string | null)][]" : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`; | |
} | |
} | |
function get_description(type, serializer) { | |
if (serializer === "GallerySerializable") { | |
return "array of [file, label] tuples"; | |
} else if (serializer === "ListStringSerializable") { | |
return "array of strings"; | |
} else if (serializer === "FileSerializable") { | |
return "array of files or single file"; | |
} | |
return type == null ? void 0 : type.description; | |
} | |
function handle_message(data, last_status) { | |
const queue = true; | |
switch (data.msg) { | |
case "send_data": | |
return { type: "data" }; | |
case "send_hash": | |
return { type: "hash" }; | |
case "queue_full": | |
return { | |
type: "update", | |
status: { | |
queue, | |
message: QUEUE_FULL_MSG, | |
stage: "error", | |
code: data.code, | |
success: data.success | |
} | |
}; | |
case "heartbeat": | |
return { | |
type: "heartbeat" | |
}; | |
case "unexpected_error": | |
return { | |
type: "unexpected_error", | |
status: { | |
queue, | |
message: data.message, | |
stage: "error", | |
success: false | |
} | |
}; | |
case "estimation": | |
return { | |
type: "update", | |
status: { | |
queue, | |
stage: last_status || "pending", | |
code: data.code, | |
size: data.queue_size, | |
position: data.rank, | |
eta: data.rank_eta, | |
success: data.success | |
} | |
}; | |
case "progress": | |
return { | |
type: "update", | |
status: { | |
queue, | |
stage: "pending", | |
code: data.code, | |
progress_data: data.progress_data, | |
success: data.success | |
} | |
}; | |
case "log": | |
return { type: "log", data }; | |
case "process_generating": | |
return { | |
type: "generating", | |
status: { | |
queue, | |
message: !data.success ? data.output.error : null, | |
stage: data.success ? "generating" : "error", | |
code: data.code, | |
progress_data: data.progress_data, | |
eta: data.average_duration | |
}, | |
data: data.success ? data.output : null | |
}; | |
case "process_completed": | |
if ("error" in data.output) { | |
return { | |
type: "update", | |
status: { | |
queue, | |
message: data.output.error, | |
stage: "error", | |
code: data.code, | |
success: data.success | |
} | |
}; | |
} | |
return { | |
type: "complete", | |
status: { | |
queue, | |
message: !data.success ? data.output.error : void 0, | |
stage: data.success ? "complete" : "error", | |
code: data.code, | |
progress_data: data.progress_data, | |
changed_state_ids: data.success ? data.output.changed_state_ids : void 0 | |
}, | |
data: data.success ? data.output : null | |
}; | |
case "process_starts": | |
return { | |
type: "update", | |
status: { | |
queue, | |
stage: "pending", | |
code: data.code, | |
size: data.rank, | |
position: 0, | |
success: data.success, | |
eta: data.eta | |
} | |
}; | |
} | |
return { type: "none", status: { stage: "error", queue } }; | |
} | |
const map_data_to_params = (data, api_info) => { | |
const parameters = Object.values(api_info.named_endpoints).flatMap( | |
(values) => values.parameters | |
); | |
if (Array.isArray(data)) { | |
if (data.length > parameters.length) { | |
console.warn("Too many arguments provided for the endpoint."); | |
} | |
return data; | |
} | |
const resolved_data = []; | |
const provided_keys = Object.keys(data); | |
parameters.forEach((param, index) => { | |
if (data.hasOwnProperty(param.parameter_name)) { | |
resolved_data[index] = data[param.parameter_name]; | |
} else if (param.parameter_has_default) { | |
resolved_data[index] = param.parameter_default; | |
} else { | |
throw new Error( | |
`No value provided for required parameter: ${param.parameter_name}` | |
); | |
} | |
}); | |
provided_keys.forEach((key) => { | |
if (!parameters.some((param) => param.parameter_name === key)) { | |
throw new Error( | |
`Parameter \`${key}\` is not a valid keyword argument. Please refer to the API for usage.` | |
); | |
} | |
}); | |
resolved_data.forEach((value, idx) => { | |
if (value === void 0 && !parameters[idx].parameter_has_default) { | |
throw new Error( | |
`No value provided for required parameter: ${parameters[idx].parameter_name}` | |
); | |
} | |
}); | |
return resolved_data; | |
}; | |
async function view_api() { | |
if (this.api_info) | |
return this.api_info; | |
const { hf_token } = this.options; | |
const { config } = this; | |
const headers = { "Content-Type": "application/json" }; | |
if (hf_token) { | |
headers.Authorization = `Bearer ${hf_token}`; | |
} | |
if (!config) { | |
return; | |
} | |
try { | |
let response; | |
if (semiver((config == null ? void 0 : config.version) || "2.0.0", "3.30") < 0) { | |
response = await this.fetch(SPACE_FETCHER_URL, { | |
method: "POST", | |
body: JSON.stringify({ | |
serialize: false, | |
config: JSON.stringify(config) | |
}), | |
headers, | |
credentials: "include" | |
}); | |
} else { | |
const url = join_urls(config.root, API_INFO_URL); | |
response = await this.fetch(url, { | |
headers, | |
credentials: "include" | |
}); | |
} | |
if (!response.ok) { | |
throw new Error(BROKEN_CONNECTION_MSG); | |
} | |
let api_info = await response.json(); | |
if ("api" in api_info) { | |
api_info = api_info.api; | |
} | |
if (api_info.named_endpoints["/predict"] && !api_info.unnamed_endpoints["0"]) { | |
api_info.unnamed_endpoints[0] = api_info.named_endpoints["/predict"]; | |
} | |
return transform_api_info(api_info, config, this.api_map); | |
} catch (e) { | |
"Could not get API info. " + e.message; | |
} | |
} | |
async function upload_files(root_url, files, upload_id) { | |
var _a; | |
const headers = {}; | |
if ((_a = this == null ? void 0 : this.options) == null ? void 0 : _a.hf_token) { | |
headers.Authorization = `Bearer ${this.options.hf_token}`; | |
} | |
const chunkSize = 1e3; | |
const uploadResponses = []; | |
let response; | |
for (let i = 0; i < files.length; i += chunkSize) { | |
const chunk = files.slice(i, i + chunkSize); | |
const formData = new FormData(); | |
chunk.forEach((file) => { | |
formData.append("files", file); | |
}); | |
try { | |
const upload_url = upload_id ? `${root_url}/${UPLOAD_URL}?upload_id=${upload_id}` : `${root_url}/${UPLOAD_URL}`; | |
response = await this.fetch(upload_url, { | |
method: "POST", | |
body: formData, | |
headers, | |
credentials: "include" | |
}); | |
} catch (e) { | |
throw new Error(BROKEN_CONNECTION_MSG + e.message); | |
} | |
if (!response.ok) { | |
const error_text = await response.text(); | |
return { error: `HTTP ${response.status}: ${error_text}` }; | |
} | |
const output = await response.json(); | |
if (output) { | |
uploadResponses.push(...output); | |
} | |
} | |
return { files: uploadResponses }; | |
} | |
async function upload(file_data, root_url, upload_id, max_file_size) { | |
let files = (Array.isArray(file_data) ? file_data : [file_data]).map( | |
(file_data2) => file_data2.blob | |
); | |
const oversized_files = files.filter( | |
(f) => f.size > (max_file_size ?? Infinity) | |
); | |
if (oversized_files.length) { | |
throw new Error( | |
`File size exceeds the maximum allowed size of ${max_file_size} bytes: ${oversized_files.map((f) => f.name).join(", ")}` | |
); | |
} | |
return await Promise.all( | |
await this.upload_files(root_url, files, upload_id).then( | |
async (response) => { | |
if (response.error) { | |
throw new Error(response.error); | |
} else { | |
if (response.files) { | |
return response.files.map((f, i) => { | |
const file = new FileData({ | |
...file_data[i], | |
path: f, | |
url: root_url + "/file=" + f | |
}); | |
return file; | |
}); | |
} | |
return []; | |
} | |
} | |
) | |
); | |
} | |
async function prepare_files(files, is_stream) { | |
return files.map( | |
(f) => new FileData({ | |
path: f.name, | |
orig_name: f.name, | |
blob: f, | |
size: f.size, | |
mime_type: f.type, | |
is_stream | |
}) | |
); | |
} | |
class FileData { | |
constructor({ | |
path, | |
url, | |
orig_name, | |
size, | |
blob, | |
is_stream, | |
mime_type, | |
alt_text | |
}) { | |
__publicField(this, "path"); | |
__publicField(this, "url"); | |
__publicField(this, "orig_name"); | |
__publicField(this, "size"); | |
__publicField(this, "blob"); | |
__publicField(this, "is_stream"); | |
__publicField(this, "mime_type"); | |
__publicField(this, "alt_text"); | |
__publicField(this, "meta", { _type: "gradio.FileData" }); | |
this.path = path; | |
this.url = url; | |
this.orig_name = orig_name; | |
this.size = size; | |
this.blob = url ? void 0 : blob; | |
this.is_stream = is_stream; | |
this.mime_type = mime_type; | |
this.alt_text = alt_text; | |
} | |
} | |
class Command { | |
constructor(command, meta) { | |
__publicField(this, "type"); | |
__publicField(this, "command"); | |
__publicField(this, "meta"); | |
__publicField(this, "fileData"); | |
this.type = "command"; | |
this.command = command; | |
this.meta = meta; | |
} | |
} | |
const is_node = typeof process !== "undefined" && process.versions && process.versions.node; | |
function update_object(object, newValue, stack) { | |
while (stack.length > 1) { | |
const key2 = stack.shift(); | |
if (typeof key2 === "string" || typeof key2 === "number") { | |
object = object[key2]; | |
} else { | |
throw new Error("Invalid key type"); | |
} | |
} | |
const key = stack.shift(); | |
if (typeof key === "string" || typeof key === "number") { | |
object[key] = newValue; | |
} else { | |
throw new Error("Invalid key type"); | |
} | |
} | |
async function walk_and_store_blobs(data, type = void 0, path = [], root = false, endpoint_info = void 0) { | |
if (Array.isArray(data)) { | |
let blob_refs = []; | |
await Promise.all( | |
data.map(async (_, index) => { | |
var _a; | |
let new_path = path.slice(); | |
new_path.push(String(index)); | |
const array_refs = await walk_and_store_blobs( | |
data[index], | |
root ? ((_a = endpoint_info == null ? void 0 : endpoint_info.parameters[index]) == null ? void 0 : _a.component) || void 0 : type, | |
new_path, | |
false, | |
endpoint_info | |
); | |
blob_refs = blob_refs.concat(array_refs); | |
}) | |
); | |
return blob_refs; | |
} else if (globalThis.Buffer && data instanceof globalThis.Buffer || data instanceof Blob) { | |
return [ | |
{ | |
path, | |
blob: new Blob([data]), | |
type | |
} | |
]; | |
} else if (typeof data === "object" && data !== null) { | |
let blob_refs = []; | |
for (const key of Object.keys(data)) { | |
const new_path = [...path, key]; | |
const value = data[key]; | |
blob_refs = blob_refs.concat( | |
await walk_and_store_blobs( | |
value, | |
void 0, | |
new_path, | |
false, | |
endpoint_info | |
) | |
); | |
} | |
return blob_refs; | |
} | |
return []; | |
} | |
function skip_queue(id, config) { | |
var _a, _b; | |
let fn_queue = (_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a.find((dep) => dep.id == id)) == null ? void 0 : _b.queue; | |
if (fn_queue != null) { | |
return !fn_queue; | |
} | |
return !config.enable_queue; | |
} | |
function post_message(message, origin) { | |
return new Promise((res, _rej) => { | |
const channel = new MessageChannel(); | |
channel.port1.onmessage = ({ data }) => { | |
channel.port1.close(); | |
res(data); | |
}; | |
window.parent.postMessage(message, origin, [channel.port2]); | |
}); | |
} | |
function handle_file(file_or_url) { | |
if (typeof file_or_url === "string") { | |
if (file_or_url.startsWith("http://") || file_or_url.startsWith("https://")) { | |
return { | |
path: file_or_url, | |
url: file_or_url, | |
orig_name: file_or_url.split("/").pop() ?? "unknown", | |
meta: { _type: "gradio.FileData" } | |
}; | |
} | |
if (is_node) { | |
return new Command("upload_file", { | |
path: file_or_url, | |
name: file_or_url, | |
orig_path: file_or_url | |
}); | |
} | |
} else if (typeof File !== "undefined" && file_or_url instanceof File) { | |
return { | |
path: file_or_url instanceof File ? file_or_url.name : "blob", | |
orig_name: file_or_url instanceof File ? file_or_url.name : "unknown", | |
// @ts-ignore | |
blob: file_or_url instanceof File ? file_or_url : new Blob([file_or_url]), | |
size: file_or_url instanceof Blob ? file_or_url.size : Buffer.byteLength(file_or_url), | |
mime_type: file_or_url instanceof File ? file_or_url.type : "application/octet-stream", | |
// Default MIME type for buffers | |
meta: { _type: "gradio.FileData" } | |
}; | |
} else if (file_or_url instanceof Buffer) { | |
return new Blob([file_or_url]); | |
} else if (file_or_url instanceof Blob) { | |
return file_or_url; | |
} | |
throw new Error( | |
"Invalid input: must be a URL, File, Blob, or Buffer object." | |
); | |
} | |
function handle_payload(resolved_payload, dependency, components, type, with_null_state = false) { | |
if (type === "input" && !with_null_state) { | |
throw new Error("Invalid code path. Cannot skip state inputs for input."); | |
} | |
if (type === "output" && with_null_state) { | |
return resolved_payload; | |
} | |
let updated_payload = []; | |
let payload_index = 0; | |
for (let i = 0; i < dependency.inputs.length; i++) { | |
const input_id = dependency.inputs[i]; | |
const component = components.find((c) => c.id === input_id); | |
if ((component == null ? void 0 : component.type) === "state") { | |
if (with_null_state) { | |
if (resolved_payload.length === dependency.inputs.length) { | |
const value = resolved_payload[payload_index]; | |
updated_payload.push(value); | |
payload_index++; | |
} else { | |
updated_payload.push(null); | |
} | |
} else { | |
payload_index++; | |
continue; | |
} | |
continue; | |
} else { | |
const value = resolved_payload[payload_index]; | |
updated_payload.push(value); | |
payload_index++; | |
} | |
} | |
return updated_payload; | |
} | |
async function handle_blob(endpoint, data, api_info) { | |
const self = this; | |
await process_local_file_commands(self, data); | |
const blobRefs = await walk_and_store_blobs( | |
data, | |
void 0, | |
[], | |
true, | |
api_info | |
); | |
const results = await Promise.all( | |
blobRefs.map(async ({ path, blob, type }) => { | |
if (!blob) | |
return { path, type }; | |
const response = await self.upload_files(endpoint, [blob]); | |
const file_url = response.files && response.files[0]; | |
return { | |
path, | |
file_url, | |
type, | |
name: blob instanceof File ? blob == null ? void 0 : blob.name : void 0 | |
}; | |
}) | |
); | |
results.forEach(({ path, file_url, type, name }) => { | |
if (type === "Gallery") { | |
update_object(data, file_url, path); | |
} else if (file_url) { | |
const file = new FileData({ path: file_url, orig_name: name }); | |
update_object(data, file, path); | |
} | |
}); | |
return data; | |
} | |
async function process_local_file_commands(client2, data) { | |
var _a, _b; | |
const root = ((_a = client2.config) == null ? void 0 : _a.root) || ((_b = client2.config) == null ? void 0 : _b.root_url); | |
if (!root) { | |
throw new Error(ROOT_URL_ERROR_MSG); | |
} | |
await recursively_process_commands(client2, data); | |
} | |
async function recursively_process_commands(client2, data, path = []) { | |
for (const key in data) { | |
if (data[key] instanceof Command) { | |
await process_single_command(client2, data, key); | |
} else if (typeof data[key] === "object" && data[key] !== null) { | |
await recursively_process_commands(client2, data[key], [...path, key]); | |
} | |
} | |
} | |
async function process_single_command(client2, data, key) { | |
var _a, _b; | |
let cmd_item = data[key]; | |
const root = ((_a = client2.config) == null ? void 0 : _a.root) || ((_b = client2.config) == null ? void 0 : _b.root_url); | |
if (!root) { | |
throw new Error(ROOT_URL_ERROR_MSG); | |
} | |
try { | |
let fileBuffer; | |
let fullPath; | |
if (typeof process !== "undefined" && process.versions && process.versions.node) { | |
const fs = await import("fs/promises"); | |
const path = await import("path"); | |
fullPath = path.resolve(process.cwd(), cmd_item.meta.path); | |
fileBuffer = await fs.readFile(fullPath); | |
} else { | |
throw new Error(NODEJS_FS_ERROR_MSG); | |
} | |
const file = new Blob([fileBuffer], { type: "application/octet-stream" }); | |
const response = await client2.upload_files(root, [file]); | |
const file_url = response.files && response.files[0]; | |
if (file_url) { | |
const fileData = new FileData({ | |
path: file_url, | |
orig_name: cmd_item.meta.name || "" | |
}); | |
data[key] = fileData; | |
} | |
} catch (error) { | |
console.error(FILE_PROCESSING_ERROR_MSG, error); | |
} | |
} | |
async function post_data(url, body, additional_headers) { | |
const headers = { "Content-Type": "application/json" }; | |
if (this.options.hf_token) { | |
headers.Authorization = `Bearer ${this.options.hf_token}`; | |
} | |
try { | |
var response = await this.fetch(url, { | |
method: "POST", | |
body: JSON.stringify(body), | |
headers: { ...headers, ...additional_headers }, | |
credentials: "include" | |
}); | |
} catch (e) { | |
return [{ error: BROKEN_CONNECTION_MSG }, 500]; | |
} | |
let output; | |
let status; | |
try { | |
output = await response.json(); | |
status = response.status; | |
} catch (e) { | |
output = { error: `Could not parse server response: ${e}` }; | |
status = 500; | |
} | |
return [output, status]; | |
} | |
async function predict(endpoint, data) { | |
let data_returned = false; | |
let status_complete = false; | |
let dependency; | |
if (!this.config) { | |
throw new Error("Could not resolve app config"); | |
} | |
if (typeof endpoint === "number") { | |
dependency = this.config.dependencies.find((dep) => dep.id == endpoint); | |
} else { | |
const trimmed_endpoint = endpoint.replace(/^\//, ""); | |
dependency = this.config.dependencies.find( | |
(dep) => dep.id == this.api_map[trimmed_endpoint] | |
); | |
} | |
if (dependency == null ? void 0 : dependency.types.continuous) { | |
throw new Error( | |
"Cannot call predict on this function as it may run forever. Use submit instead" | |
); | |
} | |
return new Promise(async (resolve, reject) => { | |
const app = this.submit(endpoint, data, null, null, true); | |
let result; | |
for await (const message of app) { | |
if (message.type === "data") { | |
if (status_complete) { | |
resolve(result); | |
} | |
data_returned = true; | |
result = message; | |
} | |
if (message.type === "status") { | |
if (message.stage === "error") | |
reject(message); | |
if (message.stage === "complete") { | |
status_complete = true; | |
if (data_returned) { | |
resolve(result); | |
} | |
} | |
} | |
} | |
}); | |
} | |
async function check_space_status(id, type, status_callback) { | |
let endpoint = type === "subdomain" ? `https://huggingface.co/api/spaces/by-subdomain/${id}` : `https://huggingface.co/api/spaces/${id}`; | |
let response; | |
let _status; | |
try { | |
response = await fetch(endpoint); | |
_status = response.status; | |
if (_status !== 200) { | |
throw new Error(); | |
} | |
response = await response.json(); | |
} catch (e) { | |
status_callback({ | |
status: "error", | |
load_status: "error", | |
message: SPACE_STATUS_ERROR_MSG, | |
detail: "NOT_FOUND" | |
}); | |
return; | |
} | |
if (!response || _status !== 200) | |
return; | |
const { | |
runtime: { stage }, | |
id: space_name | |
} = response; | |
switch (stage) { | |
case "STOPPED": | |
case "SLEEPING": | |
status_callback({ | |
status: "sleeping", | |
load_status: "pending", | |
message: "Space is asleep. Waking it up...", | |
detail: stage | |
}); | |
setTimeout(() => { | |
check_space_status(id, type, status_callback); | |
}, 1e3); | |
break; | |
case "PAUSED": | |
status_callback({ | |
status: "paused", | |
load_status: "error", | |
message: "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.", | |
detail: stage, | |
discussions_enabled: await discussions_enabled(space_name) | |
}); | |
break; | |
case "RUNNING": | |
case "RUNNING_BUILDING": | |
status_callback({ | |
status: "running", | |
load_status: "complete", | |
message: "", | |
detail: stage | |
}); | |
break; | |
case "BUILDING": | |
status_callback({ | |
status: "building", | |
load_status: "pending", | |
message: "Space is building...", | |
detail: stage | |
}); | |
setTimeout(() => { | |
check_space_status(id, type, status_callback); | |
}, 1e3); | |
break; | |
default: | |
status_callback({ | |
status: "space_error", | |
load_status: "error", | |
message: "This space is experiencing an issue.", | |
detail: stage, | |
discussions_enabled: await discussions_enabled(space_name) | |
}); | |
break; | |
} | |
} | |
const RE_DISABLED_DISCUSSION = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/; | |
async function discussions_enabled(space_id) { | |
try { | |
const r = await fetch( | |
`https://huggingface.co/api/spaces/${space_id}/discussions`, | |
{ | |
method: "HEAD" | |
} | |
); | |
const error = r.headers.get("x-error-message"); | |
if (!r.ok || error && RE_DISABLED_DISCUSSION.test(error)) | |
return false; | |
return true; | |
} catch (e) { | |
return false; | |
} | |
} | |
async function get_space_hardware(space_id, hf_token) { | |
const headers = {}; | |
if (hf_token) { | |
headers.Authorization = `Bearer ${hf_token}`; | |
} | |
try { | |
const res = await fetch( | |
`https://huggingface.co/api/spaces/${space_id}/${RUNTIME_URL}`, | |
{ headers } | |
); | |
if (res.status !== 200) | |
throw new Error("Space hardware could not be obtained."); | |
const { hardware } = await res.json(); | |
return hardware.current; | |
} catch (e) { | |
throw new Error(e.message); | |
} | |
} | |
async function set_space_timeout(space_id, timeout, hf_token) { | |
const headers = {}; | |
if (hf_token) { | |
headers.Authorization = `Bearer ${hf_token}`; | |
} | |
const body = { | |
seconds: timeout | |
}; | |
try { | |
const res = await fetch( | |
`https://huggingface.co/api/spaces/${space_id}/${SLEEPTIME_URL}`, | |
{ | |
method: "POST", | |
headers: { "Content-Type": "application/json", ...headers }, | |
body: JSON.stringify(body) | |
} | |
); | |
if (res.status !== 200) { | |
throw new Error( | |
"Could not set sleep timeout on duplicated Space. Please visit *ADD HF LINK TO SETTINGS* to set a timeout manually to reduce billing charges." | |
); | |
} | |
const response = await res.json(); | |
return response; | |
} catch (e) { | |
throw new Error(e.message); | |
} | |
} | |
const hardware_types = [ | |
"cpu-basic", | |
"cpu-upgrade", | |
"cpu-xl", | |
"t4-small", | |
"t4-medium", | |
"a10g-small", | |
"a10g-large", | |
"a10g-largex2", | |
"a10g-largex4", | |
"a100-large", | |
"zero-a10g", | |
"h100", | |
"h100x8" | |
]; | |
async function duplicate(app_reference, options) { | |
const { hf_token, private: _private, hardware, timeout, auth } = options; | |
if (hardware && !hardware_types.includes(hardware)) { | |
throw new Error( | |
`Invalid hardware type provided. Valid types are: ${hardware_types.map((v) => `"${v}"`).join(",")}.` | |
); | |
} | |
const { http_protocol, host } = await process_endpoint( | |
app_reference, | |
hf_token | |
); | |
let cookies = null; | |
if (auth) { | |
const cookie_header = await get_cookie_header( | |
http_protocol, | |
host, | |
auth, | |
fetch | |
); | |
if (cookie_header) | |
cookies = parse_and_set_cookies(cookie_header); | |
} | |
const headers = { | |
Authorization: `Bearer ${hf_token}`, | |
"Content-Type": "application/json", | |
...cookies ? { Cookie: cookies.join("; ") } : {} | |
}; | |
const user = (await (await fetch(`https://huggingface.co/api/whoami-v2`, { | |
headers | |
})).json()).name; | |
const space_name = app_reference.split("/")[1]; | |
const body = { | |
repository: `${user}/${space_name}` | |
}; | |
if (_private) { | |
body.private = true; | |
} | |
let original_hardware; | |
try { | |
if (!hardware) { | |
original_hardware = await get_space_hardware(app_reference, hf_token); | |
} | |
} catch (e) { | |
throw Error(SPACE_METADATA_ERROR_MSG + e.message); | |
} | |
const requested_hardware = hardware || original_hardware || "cpu-basic"; | |
body.hardware = requested_hardware; | |
try { | |
const response = await fetch( | |
`https://huggingface.co/api/spaces/${app_reference}/duplicate`, | |
{ | |
method: "POST", | |
headers, | |
body: JSON.stringify(body) | |
} | |
); | |
if (response.status === 409) { | |
try { | |
const client2 = await Client.connect(`${user}/${space_name}`, options); | |
return client2; | |
} catch (error) { | |
console.error("Failed to connect Client instance:", error); | |
throw error; | |
} | |
} else if (response.status !== 200) { | |
throw new Error(response.statusText); | |
} | |
const duplicated_space = await response.json(); | |
await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token); | |
return await Client.connect( | |
get_space_reference(duplicated_space.url), | |
options | |
); | |
} catch (e) { | |
throw new Error(e); | |
} | |
} | |
function get_space_reference(url) { | |
const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/; | |
const match = url.match(regex); | |
if (match) { | |
return match[1]; | |
} | |
} | |
class TextLineStream extends TransformStream { | |
/** Constructs a new instance. */ | |
constructor(options = { allowCR: false }) { | |
super({ | |
transform: (chars, controller) => { | |
chars = __privateGet(this, _currentLine) + chars; | |
while (true) { | |
const lfIndex = chars.indexOf("\n"); | |
const crIndex = options.allowCR ? chars.indexOf("\r") : -1; | |
if (crIndex !== -1 && crIndex !== chars.length - 1 && (lfIndex === -1 || lfIndex - 1 > crIndex)) { | |
controller.enqueue(chars.slice(0, crIndex)); | |
chars = chars.slice(crIndex + 1); | |
continue; | |
} | |
if (lfIndex === -1) | |
break; | |
const endIndex = chars[lfIndex - 1] === "\r" ? lfIndex - 1 : lfIndex; | |
controller.enqueue(chars.slice(0, endIndex)); | |
chars = chars.slice(lfIndex + 1); | |
} | |
__privateSet(this, _currentLine, chars); | |
}, | |
flush: (controller) => { | |
if (__privateGet(this, _currentLine) === "") | |
return; | |
const currentLine = options.allowCR && __privateGet(this, _currentLine).endsWith("\r") ? __privateGet(this, _currentLine).slice(0, -1) : __privateGet(this, _currentLine); | |
controller.enqueue(currentLine); | |
} | |
}); | |
__privateAdd(this, _currentLine, ""); | |
} | |
} | |
_currentLine = new WeakMap(); | |
function stream$1(input) { | |
let decoder = new TextDecoderStream(); | |
let split2 = new TextLineStream({ allowCR: true }); | |
return input.pipeThrough(decoder).pipeThrough(split2); | |
} | |
function split(input) { | |
let rgx = /[:]\s*/; | |
let match = rgx.exec(input); | |
let idx = match && match.index; | |
if (idx) { | |
return [ | |
input.substring(0, idx), | |
input.substring(idx + match[0].length) | |
]; | |
} | |
} | |
function fallback(headers, key, value) { | |
let tmp = headers.get(key); | |
if (!tmp) | |
headers.set(key, value); | |
} | |
async function* events(res, signal) { | |
if (!res.body) | |
return; | |
let iter = stream$1(res.body); | |
let line, reader = iter.getReader(); | |
let event; | |
for (; ; ) { | |
if (signal && signal.aborted) { | |
return reader.cancel(); | |
} | |
line = await reader.read(); | |
if (line.done) | |
return; | |
if (!line.value) { | |
if (event) | |
yield event; | |
event = void 0; | |
continue; | |
} | |
let [field, value] = split(line.value) || []; | |
if (!field) | |
continue; | |
if (field === "data") { | |
event || (event = {}); | |
event[field] = event[field] ? event[field] + "\n" + value : value; | |
} else if (field === "event") { | |
event || (event = {}); | |
event[field] = value; | |
} else if (field === "id") { | |
event || (event = {}); | |
event[field] = +value || value; | |
} else if (field === "retry") { | |
event || (event = {}); | |
event[field] = +value || void 0; | |
} | |
} | |
} | |
async function stream(input, init) { | |
let req = new Request(input, init); | |
fallback(req.headers, "Accept", "text/event-stream"); | |
fallback(req.headers, "Content-Type", "application/json"); | |
let r = await fetch(req); | |
if (!r.ok) | |
throw r; | |
return events(r, req.signal); | |
} | |
async function open_stream() { | |
let { | |
event_callbacks, | |
unclosed_events, | |
pending_stream_messages, | |
stream_status, | |
config, | |
jwt | |
} = this; | |
const that = this; | |
if (!config) { | |
throw new Error("Could not resolve app config"); | |
} | |
stream_status.open = true; | |
let stream2 = null; | |
let params = new URLSearchParams({ | |
session_hash: this.session_hash | |
}).toString(); | |
let url = new URL(`${config.root}/queue/data?${params}`); | |
if (jwt) { | |
url.searchParams.set("__sign", jwt); | |
} | |
stream2 = this.stream(url); | |
if (!stream2) { | |
console.warn("Cannot connect to SSE endpoint: " + url.toString()); | |
return; | |
} | |
stream2.onmessage = async function(event) { | |
let _data = JSON.parse(event.data); | |
if (_data.msg === "close_stream") { | |
close_stream(stream_status, that.abort_controller); | |
return; | |
} | |
const event_id = _data.event_id; | |
if (!event_id) { | |
await Promise.all( | |
Object.keys(event_callbacks).map( | |
(event_id2) => event_callbacks[event_id2](_data) | |
) | |
); | |
} else if (event_callbacks[event_id] && config) { | |
if (_data.msg === "process_completed" && ["sse", "sse_v1", "sse_v2", "sse_v2.1", "sse_v3"].includes( | |
config.protocol | |
)) { | |
unclosed_events.delete(event_id); | |
} | |
let fn2 = event_callbacks[event_id]; | |
if (typeof window !== "undefined" && typeof document !== "undefined") { | |
setTimeout(fn2, 0, _data); | |
} else { | |
fn2(_data); | |
} | |
} else { | |
if (!pending_stream_messages[event_id]) { | |
pending_stream_messages[event_id] = []; | |
} | |
pending_stream_messages[event_id].push(_data); | |
} | |
}; | |
stream2.onerror = async function() { | |
await Promise.all( | |
Object.keys(event_callbacks).map( | |
(event_id) => event_callbacks[event_id]({ | |
msg: "unexpected_error", | |
message: BROKEN_CONNECTION_MSG | |
}) | |
) | |
); | |
}; | |
} | |
function close_stream(stream_status, abort_controller) { | |
if (stream_status) { | |
stream_status.open = false; | |
abort_controller == null ? void 0 : abort_controller.abort(); | |
} | |
} | |
function apply_diff_stream(pending_diff_streams, event_id, data) { | |
let is_first_generation = !pending_diff_streams[event_id]; | |
if (is_first_generation) { | |
pending_diff_streams[event_id] = []; | |
data.data.forEach((value, i) => { | |
pending_diff_streams[event_id][i] = value; | |
}); | |
} else { | |
data.data.forEach((value, i) => { | |
let new_data = apply_diff(pending_diff_streams[event_id][i], value); | |
pending_diff_streams[event_id][i] = new_data; | |
data.data[i] = new_data; | |
}); | |
} | |
} | |
function apply_diff(obj, diff) { | |
diff.forEach(([action, path, value]) => { | |
obj = apply_edit(obj, path, action, value); | |
}); | |
return obj; | |
} | |
function apply_edit(target, path, action, value) { | |
if (path.length === 0) { | |
if (action === "replace") { | |
return value; | |
} else if (action === "append") { | |
return target + value; | |
} | |
throw new Error(`Unsupported action: ${action}`); | |
} | |
let current = target; | |
for (let i = 0; i < path.length - 1; i++) { | |
current = current[path[i]]; | |
} | |
const last_path = path[path.length - 1]; | |
switch (action) { | |
case "replace": | |
current[last_path] = value; | |
break; | |
case "append": | |
current[last_path] += value; | |
break; | |
case "add": | |
if (Array.isArray(current)) { | |
current.splice(Number(last_path), 0, value); | |
} else { | |
current[last_path] = value; | |
} | |
break; | |
case "delete": | |
if (Array.isArray(current)) { | |
current.splice(Number(last_path), 1); | |
} else { | |
delete current[last_path]; | |
} | |
break; | |
default: | |
throw new Error(`Unknown action: ${action}`); | |
} | |
return target; | |
} | |
function readable_stream(input, init = {}) { | |
const instance = { | |
close: () => { | |
throw new Error("Method not implemented."); | |
}, | |
onerror: null, | |
onmessage: null, | |
onopen: null, | |
readyState: 0, | |
url: input.toString(), | |
withCredentials: false, | |
CONNECTING: 0, | |
OPEN: 1, | |
CLOSED: 2, | |
addEventListener: () => { | |
throw new Error("Method not implemented."); | |
}, | |
dispatchEvent: () => { | |
throw new Error("Method not implemented."); | |
}, | |
removeEventListener: () => { | |
throw new Error("Method not implemented."); | |
} | |
}; | |
stream(input, init).then(async (res) => { | |
instance.readyState = instance.OPEN; | |
try { | |
for await (const chunk of res) { | |
instance.onmessage && instance.onmessage(chunk); | |
} | |
instance.readyState = instance.CLOSED; | |
} catch (e) { | |
instance.onerror && instance.onerror(e); | |
instance.readyState = instance.CLOSED; | |
} | |
}).catch((e) => { | |
console.error(e); | |
instance.onerror && instance.onerror(e); | |
instance.readyState = instance.CLOSED; | |
}); | |
return instance; | |
} | |
function submit(endpoint, data, event_data, trigger_id, all_events) { | |
var _a; | |
try { | |
let fire_event = function(event) { | |
if (all_events || events_to_publish[event.type]) { | |
push_event(event); | |
} | |
}, close = function() { | |
done = true; | |
while (resolvers.length > 0) | |
resolvers.shift()({ | |
value: void 0, | |
done: true | |
}); | |
}, push = function(data2) { | |
if (done) | |
return; | |
if (resolvers.length > 0) { | |
resolvers.shift()(data2); | |
} else { | |
values.push(data2); | |
} | |
}, push_error = function(error) { | |
push(thenable_reject(error)); | |
close(); | |
}, push_event = function(event) { | |
push({ value: event, done: false }); | |
}, next = function() { | |
if (values.length > 0) | |
return Promise.resolve(values.shift()); | |
if (done) | |
return Promise.resolve({ value: void 0, done: true }); | |
return new Promise((resolve) => resolvers.push(resolve)); | |
}; | |
const { hf_token } = this.options; | |
const { | |
fetch: fetch2, | |
app_reference, | |
config, | |
session_hash, | |
api_info, | |
api_map, | |
stream_status, | |
pending_stream_messages, | |
pending_diff_streams, | |
event_callbacks, | |
unclosed_events, | |
post_data: post_data2, | |
options | |
} = this; | |
const that = this; | |
if (!api_info) | |
throw new Error("No API found"); | |
if (!config) | |
throw new Error("Could not resolve app config"); | |
let { fn_index, endpoint_info, dependency } = get_endpoint_info( | |
api_info, | |
endpoint, | |
api_map, | |
config | |
); | |
let resolved_data = map_data_to_params(data, api_info); | |
let websocket; | |
let stream2; | |
let protocol = config.protocol ?? "ws"; | |
const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint; | |
let payload; | |
let event_id = null; | |
let complete = false; | |
let last_status = {}; | |
let url_params = typeof window !== "undefined" && typeof document !== "undefined" ? new URLSearchParams(window.location.search).toString() : ""; | |
const events_to_publish = ((_a = options == null ? void 0 : options.events) == null ? void 0 : _a.reduce( | |
(acc, event) => { | |
acc[event] = true; | |
return acc; | |
}, | |
{} | |
)) || {}; | |
async function cancel() { | |
const _status = { | |
stage: "complete", | |
queue: false, | |
time: /* @__PURE__ */ new Date() | |
}; | |
complete = _status; | |
fire_event({ | |
..._status, | |
type: "status", | |
endpoint: _endpoint, | |
fn_index | |
}); | |
let reset_request = {}; | |
let cancel_request = {}; | |
if (protocol === "ws") { | |
if (websocket && websocket.readyState === 0) { | |
websocket.addEventListener("open", () => { | |
websocket.close(); | |
}); | |
} else { | |
websocket.close(); | |
} | |
reset_request = { fn_index, session_hash }; | |
} else { | |
close_stream(stream_status, that.abort_controller); | |
close(); | |
reset_request = { event_id }; | |
cancel_request = { event_id, session_hash, fn_index }; | |
} | |
try { | |
if (!config) { | |
throw new Error("Could not resolve app config"); | |
} | |
if ("event_id" in cancel_request) { | |
await fetch2(`${config.root}/cancel`, { | |
headers: { "Content-Type": "application/json" }, | |
method: "POST", | |
body: JSON.stringify(cancel_request) | |
}); | |
} | |
await fetch2(`${config.root}/reset`, { | |
headers: { "Content-Type": "application/json" }, | |
method: "POST", | |
body: JSON.stringify(reset_request) | |
}); | |
} catch (e) { | |
console.warn( | |
"The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable." | |
); | |
} | |
} | |
const resolve_heartbeat = async (config2) => { | |
await this._resolve_hearbeat(config2); | |
}; | |
async function handle_render_config(render_config) { | |
if (!config) | |
return; | |
let render_id = render_config.render_id; | |
config.components = [ | |
...config.components.filter((c) => c.props.rendered_in !== render_id), | |
...render_config.components | |
]; | |
config.dependencies = [ | |
...config.dependencies.filter((d) => d.rendered_in !== render_id), | |
...render_config.dependencies | |
]; | |
const any_state = config.components.some((c) => c.type === "state"); | |
const any_unload = config.dependencies.some( | |
(d) => d.targets.some((t) => t[1] === "unload") | |
); | |
config.connect_heartbeat = any_state || any_unload; | |
await resolve_heartbeat(config); | |
fire_event({ | |
type: "render", | |
data: render_config, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
} | |
this.handle_blob(config.root, resolved_data, endpoint_info).then( | |
async (_payload) => { | |
var _a2; | |
let input_data = handle_payload( | |
_payload, | |
dependency, | |
config.components, | |
"input", | |
true | |
); | |
payload = { | |
data: input_data || [], | |
event_data, | |
fn_index, | |
trigger_id | |
}; | |
if (skip_queue(fn_index, config)) { | |
fire_event({ | |
type: "status", | |
endpoint: _endpoint, | |
stage: "pending", | |
queue: false, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
post_data2( | |
`${config.root}/run${_endpoint.startsWith("/") ? _endpoint : `/${_endpoint}`}${url_params ? "?" + url_params : ""}`, | |
{ | |
...payload, | |
session_hash | |
} | |
).then(([output, status_code]) => { | |
const data2 = output.data; | |
if (status_code == 200) { | |
fire_event({ | |
type: "data", | |
endpoint: _endpoint, | |
fn_index, | |
data: handle_payload( | |
data2, | |
dependency, | |
config.components, | |
"output", | |
options.with_null_state | |
), | |
time: /* @__PURE__ */ new Date(), | |
event_data, | |
trigger_id | |
}); | |
if (output.render_config) { | |
handle_render_config(output.render_config); | |
} | |
fire_event({ | |
type: "status", | |
endpoint: _endpoint, | |
fn_index, | |
stage: "complete", | |
eta: output.average_duration, | |
queue: false, | |
time: /* @__PURE__ */ new Date() | |
}); | |
} else { | |
fire_event({ | |
type: "status", | |
stage: "error", | |
endpoint: _endpoint, | |
fn_index, | |
message: output.error, | |
queue: false, | |
time: /* @__PURE__ */ new Date() | |
}); | |
} | |
}).catch((e) => { | |
fire_event({ | |
type: "status", | |
stage: "error", | |
message: e.message, | |
endpoint: _endpoint, | |
fn_index, | |
queue: false, | |
time: /* @__PURE__ */ new Date() | |
}); | |
}); | |
} else if (protocol == "ws") { | |
const { ws_protocol, host } = await process_endpoint( | |
app_reference, | |
hf_token | |
); | |
fire_event({ | |
type: "status", | |
stage: "pending", | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
let url = new URL( | |
`${ws_protocol}://${resolve_root( | |
host, | |
config.path, | |
true | |
)}/queue/join${url_params ? "?" + url_params : ""}` | |
); | |
if (this.jwt) { | |
url.searchParams.set("__sign", this.jwt); | |
} | |
websocket = new WebSocket(url); | |
websocket.onclose = (evt) => { | |
if (!evt.wasClean) { | |
fire_event({ | |
type: "status", | |
stage: "error", | |
broken: true, | |
message: BROKEN_CONNECTION_MSG, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
} | |
}; | |
websocket.onmessage = function(event) { | |
const _data = JSON.parse(event.data); | |
const { type, status, data: data2 } = handle_message( | |
_data, | |
last_status[fn_index] | |
); | |
if (type === "update" && status && !complete) { | |
fire_event({ | |
type: "status", | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date(), | |
...status | |
}); | |
if (status.stage === "error") { | |
websocket.close(); | |
} | |
} else if (type === "hash") { | |
websocket.send(JSON.stringify({ fn_index, session_hash })); | |
return; | |
} else if (type === "data") { | |
websocket.send(JSON.stringify({ ...payload, session_hash })); | |
} else if (type === "complete") { | |
complete = status; | |
} else if (type === "log") { | |
fire_event({ | |
type: "log", | |
log: data2.log, | |
level: data2.level, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
} else if (type === "generating") { | |
fire_event({ | |
type: "status", | |
time: /* @__PURE__ */ new Date(), | |
...status, | |
stage: status == null ? void 0 : status.stage, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
} | |
if (data2) { | |
fire_event({ | |
type: "data", | |
time: /* @__PURE__ */ new Date(), | |
data: handle_payload( | |
data2.data, | |
dependency, | |
config.components, | |
"output", | |
options.with_null_state | |
), | |
endpoint: _endpoint, | |
fn_index, | |
event_data, | |
trigger_id | |
}); | |
if (complete) { | |
fire_event({ | |
type: "status", | |
time: /* @__PURE__ */ new Date(), | |
...complete, | |
stage: status == null ? void 0 : status.stage, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
websocket.close(); | |
} | |
} | |
}; | |
if (semiver(config.version || "2.0.0", "3.6") < 0) { | |
addEventListener( | |
"open", | |
() => websocket.send(JSON.stringify({ hash: session_hash })) | |
); | |
} | |
} else if (protocol == "sse") { | |
fire_event({ | |
type: "status", | |
stage: "pending", | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
var params = new URLSearchParams({ | |
fn_index: fn_index.toString(), | |
session_hash | |
}).toString(); | |
let url = new URL( | |
`${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}` | |
); | |
if (this.jwt) { | |
url.searchParams.set("__sign", this.jwt); | |
} | |
stream2 = this.stream(url); | |
if (!stream2) { | |
return Promise.reject( | |
new Error("Cannot connect to SSE endpoint: " + url.toString()) | |
); | |
} | |
stream2.onmessage = async function(event) { | |
const _data = JSON.parse(event.data); | |
const { type, status, data: data2 } = handle_message( | |
_data, | |
last_status[fn_index] | |
); | |
if (type === "update" && status && !complete) { | |
fire_event({ | |
type: "status", | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date(), | |
...status | |
}); | |
if (status.stage === "error") { | |
stream2 == null ? void 0 : stream2.close(); | |
close(); | |
} | |
} else if (type === "data") { | |
event_id = _data.event_id; | |
let [_, status2] = await post_data2(`${config.root}/queue/data`, { | |
...payload, | |
session_hash, | |
event_id | |
}); | |
if (status2 !== 200) { | |
fire_event({ | |
type: "status", | |
stage: "error", | |
message: BROKEN_CONNECTION_MSG, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
stream2 == null ? void 0 : stream2.close(); | |
close(); | |
} | |
} else if (type === "complete") { | |
complete = status; | |
} else if (type === "log") { | |
fire_event({ | |
type: "log", | |
log: data2.log, | |
level: data2.level, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
} else if (type === "generating") { | |
fire_event({ | |
type: "status", | |
time: /* @__PURE__ */ new Date(), | |
...status, | |
stage: status == null ? void 0 : status.stage, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
} | |
if (data2) { | |
fire_event({ | |
type: "data", | |
time: /* @__PURE__ */ new Date(), | |
data: handle_payload( | |
data2.data, | |
dependency, | |
config.components, | |
"output", | |
options.with_null_state | |
), | |
endpoint: _endpoint, | |
fn_index, | |
event_data, | |
trigger_id | |
}); | |
if (complete) { | |
fire_event({ | |
type: "status", | |
time: /* @__PURE__ */ new Date(), | |
...complete, | |
stage: status == null ? void 0 : status.stage, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
stream2 == null ? void 0 : stream2.close(); | |
close(); | |
} | |
} | |
}; | |
} else if (protocol == "sse_v1" || protocol == "sse_v2" || protocol == "sse_v2.1" || protocol == "sse_v3") { | |
fire_event({ | |
type: "status", | |
stage: "pending", | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
let hostname = ""; | |
if (typeof window !== "undefined" && typeof document !== "undefined") { | |
hostname = (_a2 = window == null ? void 0 : window.location) == null ? void 0 : _a2.hostname; | |
} | |
let hfhubdev = "dev.spaces.huggingface.tech"; | |
const origin = hostname.includes(".dev.") ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}` : `https://huggingface.co`; | |
const is_iframe = typeof window !== "undefined" && typeof document !== "undefined" && window.parent != window; | |
const is_zerogpu_space = dependency.zerogpu && config.space_id; | |
const zerogpu_auth_promise = is_iframe && is_zerogpu_space ? post_message("zerogpu-headers", origin) : Promise.resolve(null); | |
const post_data_promise = zerogpu_auth_promise.then((headers) => { | |
return post_data2( | |
`${config.root}/queue/join?${url_params}`, | |
{ | |
...payload, | |
session_hash | |
}, | |
headers | |
); | |
}); | |
post_data_promise.then(async ([response, status]) => { | |
if (status === 503) { | |
fire_event({ | |
type: "status", | |
stage: "error", | |
message: QUEUE_FULL_MSG, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
} else if (status !== 200) { | |
fire_event({ | |
type: "status", | |
stage: "error", | |
message: BROKEN_CONNECTION_MSG, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
} else { | |
event_id = response.event_id; | |
let callback = async function(_data) { | |
try { | |
const { type, status: status2, data: data2 } = handle_message( | |
_data, | |
last_status[fn_index] | |
); | |
if (type == "heartbeat") { | |
return; | |
} | |
if (type === "update" && status2 && !complete) { | |
fire_event({ | |
type: "status", | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date(), | |
...status2 | |
}); | |
} else if (type === "complete") { | |
complete = status2; | |
} else if (type == "unexpected_error") { | |
console.error("Unexpected error", status2 == null ? void 0 : status2.message); | |
fire_event({ | |
type: "status", | |
stage: "error", | |
message: (status2 == null ? void 0 : status2.message) || "An Unexpected Error Occurred!", | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
} else if (type === "log") { | |
fire_event({ | |
type: "log", | |
log: data2.log, | |
level: data2.level, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
return; | |
} else if (type === "generating") { | |
fire_event({ | |
type: "status", | |
time: /* @__PURE__ */ new Date(), | |
...status2, | |
stage: status2 == null ? void 0 : status2.stage, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
if (data2 && ["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) { | |
apply_diff_stream(pending_diff_streams, event_id, data2); | |
} | |
} | |
if (data2) { | |
fire_event({ | |
type: "data", | |
time: /* @__PURE__ */ new Date(), | |
data: handle_payload( | |
data2.data, | |
dependency, | |
config.components, | |
"output", | |
options.with_null_state | |
), | |
endpoint: _endpoint, | |
fn_index | |
}); | |
if (data2.render_config) { | |
await handle_render_config(data2.render_config); | |
} | |
if (complete) { | |
fire_event({ | |
type: "status", | |
time: /* @__PURE__ */ new Date(), | |
...complete, | |
stage: status2 == null ? void 0 : status2.stage, | |
queue: true, | |
endpoint: _endpoint, | |
fn_index | |
}); | |
} | |
} | |
if ((status2 == null ? void 0 : status2.stage) === "complete" || (status2 == null ? void 0 : status2.stage) === "error") { | |
if (event_callbacks[event_id]) { | |
delete event_callbacks[event_id]; | |
} | |
if (event_id in pending_diff_streams) { | |
delete pending_diff_streams[event_id]; | |
} | |
} | |
} catch (e) { | |
console.error("Unexpected client exception", e); | |
fire_event({ | |
type: "status", | |
stage: "error", | |
message: "An Unexpected Error Occurred!", | |
queue: true, | |
endpoint: _endpoint, | |
fn_index, | |
time: /* @__PURE__ */ new Date() | |
}); | |
if (["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) { | |
close_stream(stream_status, that.abort_controller); | |
stream_status.open = false; | |
close(); | |
} | |
} | |
}; | |
if (event_id in pending_stream_messages) { | |
pending_stream_messages[event_id].forEach( | |
(msg) => callback(msg) | |
); | |
delete pending_stream_messages[event_id]; | |
} | |
event_callbacks[event_id] = callback; | |
unclosed_events.add(event_id); | |
if (!stream_status.open) { | |
await this.open_stream(); | |
} | |
} | |
}); | |
} | |
} | |
); | |
let done = false; | |
const values = []; | |
const resolvers = []; | |
const iterator = { | |
[Symbol.asyncIterator]: () => iterator, | |
next, | |
throw: async (value) => { | |
push_error(value); | |
return next(); | |
}, | |
return: async () => { | |
close(); | |
return next(); | |
}, | |
cancel | |
}; | |
return iterator; | |
} catch (error) { | |
console.error("Submit function encountered an error:", error); | |
throw error; | |
} | |
} | |
function thenable_reject(error) { | |
return { | |
then: (resolve, reject) => reject(error) | |
}; | |
} | |
function get_endpoint_info(api_info, endpoint, api_map, config) { | |
let fn_index; | |
let endpoint_info; | |
let dependency; | |
if (typeof endpoint === "number") { | |
fn_index = endpoint; | |
endpoint_info = api_info.unnamed_endpoints[fn_index]; | |
dependency = config.dependencies.find((dep) => dep.id == endpoint); | |
} else { | |
const trimmed_endpoint = endpoint.replace(/^\//, ""); | |
fn_index = api_map[trimmed_endpoint]; | |
endpoint_info = api_info.named_endpoints[endpoint.trim()]; | |
dependency = config.dependencies.find( | |
(dep) => dep.id == api_map[trimmed_endpoint] | |
); | |
} | |
if (typeof fn_index !== "number") { | |
throw new Error( | |
"There is no endpoint matching that name of fn_index matching that number." | |
); | |
} | |
return { fn_index, endpoint_info, dependency }; | |
} | |
class Client { | |
constructor(app_reference, options = { events: ["data"] }) { | |
__publicField(this, "app_reference"); | |
__publicField(this, "options"); | |
__publicField(this, "config"); | |
__publicField(this, "api_info"); | |
__publicField(this, "api_map", {}); | |
__publicField(this, "session_hash", Math.random().toString(36).substring(2)); | |
__publicField(this, "jwt", false); | |
__publicField(this, "last_status", {}); | |
__publicField(this, "cookies", null); | |
// streaming | |
__publicField(this, "stream_status", { open: false }); | |
__publicField(this, "pending_stream_messages", {}); | |
__publicField(this, "pending_diff_streams", {}); | |
__publicField(this, "event_callbacks", {}); | |
__publicField(this, "unclosed_events", /* @__PURE__ */ new Set()); | |
__publicField(this, "heartbeat_event", null); | |
__publicField(this, "abort_controller", null); | |
__publicField(this, "stream_instance", null); | |
__publicField(this, "view_api"); | |
__publicField(this, "upload_files"); | |
__publicField(this, "upload"); | |
__publicField(this, "handle_blob"); | |
__publicField(this, "post_data"); | |
__publicField(this, "submit"); | |
__publicField(this, "predict"); | |
__publicField(this, "open_stream"); | |
__publicField(this, "resolve_config"); | |
__publicField(this, "resolve_cookies"); | |
this.app_reference = app_reference; | |
if (!options.events) { | |
options.events = ["data"]; | |
} | |
this.options = options; | |
this.view_api = view_api.bind(this); | |
this.upload_files = upload_files.bind(this); | |
this.handle_blob = handle_blob.bind(this); | |
this.post_data = post_data.bind(this); | |
this.submit = submit.bind(this); | |
this.predict = predict.bind(this); | |
this.open_stream = open_stream.bind(this); | |
this.resolve_config = resolve_config.bind(this); | |
this.resolve_cookies = resolve_cookies.bind(this); | |
this.upload = upload.bind(this); | |
} | |
fetch(input, init) { | |
const headers = new Headers((init == null ? void 0 : init.headers) || {}); | |
if (this && this.cookies) { | |
headers.append("Cookie", this.cookies); | |
} | |
return fetch(input, { ...init, headers }); | |
} | |
stream(url) { | |
this.abort_controller = new AbortController(); | |
this.stream_instance = readable_stream(url.toString(), { | |
signal: this.abort_controller.signal | |
}); | |
return this.stream_instance; | |
} | |
async init() { | |
var _a; | |
if ((typeof window === "undefined" || !("WebSocket" in window)) && !global.WebSocket) { | |
const ws = await import("./wrapper-CviSselG.js"); | |
global.WebSocket = ws.WebSocket; | |
} | |
try { | |
if (this.options.auth) { | |
await this.resolve_cookies(); | |
} | |
await this._resolve_config().then( | |
({ config }) => this._resolve_hearbeat(config) | |
); | |
} catch (e) { | |
throw Error(e); | |
} | |
this.api_info = await this.view_api(); | |
this.api_map = map_names_to_ids(((_a = this.config) == null ? void 0 : _a.dependencies) || []); | |
} | |
async _resolve_hearbeat(_config) { | |
if (_config) { | |
this.config = _config; | |
if (this.config && this.config.connect_heartbeat) { | |
if (this.config.space_id && this.options.hf_token) { | |
this.jwt = await get_jwt( | |
this.config.space_id, | |
this.options.hf_token, | |
this.cookies | |
); | |
} | |
} | |
} | |
if (_config.space_id && this.options.hf_token) { | |
this.jwt = await get_jwt(_config.space_id, this.options.hf_token); | |
} | |
if (this.config && this.config.connect_heartbeat) { | |
const heartbeat_url = new URL( | |
`${this.config.root}/heartbeat/${this.session_hash}` | |
); | |
if (this.jwt) { | |
heartbeat_url.searchParams.set("__sign", this.jwt); | |
} | |
if (!this.heartbeat_event) { | |
this.heartbeat_event = this.stream(heartbeat_url); | |
} | |
} | |
} | |
static async connect(app_reference, options = { | |
events: ["data"] | |
}) { | |
const client2 = new this(app_reference, options); | |
await client2.init(); | |
return client2; | |
} | |
close() { | |
var _a; | |
(_a = this.heartbeat_event) == null ? void 0 : _a.close(); | |
} | |
static async duplicate(app_reference, options = { | |
events: ["data"] | |
}) { | |
return duplicate(app_reference, options); | |
} | |
async _resolve_config() { | |
const { http_protocol, host, space_id } = await process_endpoint( | |
this.app_reference, | |
this.options.hf_token | |
); | |
const { status_callback } = this.options; | |
let config; | |
try { | |
config = await this.resolve_config(`${http_protocol}//${host}`); | |
if (!config) { | |
throw new Error(CONFIG_ERROR_MSG); | |
} | |
return this.config_success(config); | |
} catch (e) { | |
if (space_id && status_callback) { | |
check_space_status( | |
space_id, | |
RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain", | |
this.handle_space_success | |
); | |
} else { | |
if (status_callback) | |
status_callback({ | |
status: "error", | |
message: "Could not load this space.", | |
load_status: "error", | |
detail: "NOT_FOUND" | |
}); | |
throw Error(e); | |
} | |
} | |
} | |
async config_success(_config) { | |
this.config = _config; | |
if (typeof window !== "undefined" && typeof document !== "undefined") { | |
if (window.location.protocol === "https:") { | |
this.config.root = this.config.root.replace("http://", "https://"); | |
} | |
} | |
if (this.config.auth_required) { | |
return this.prepare_return_obj(); | |
} | |
try { | |
this.api_info = await this.view_api(); | |
} catch (e) { | |
console.error(API_INFO_ERROR_MSG + e.message); | |
} | |
return this.prepare_return_obj(); | |
} | |
async handle_space_success(status) { | |
if (!this) { | |
throw new Error(CONFIG_ERROR_MSG); | |
} | |
const { status_callback } = this.options; | |
if (status_callback) | |
status_callback(status); | |
if (status.status === "running") { | |
try { | |
this.config = await this._resolve_config(); | |
if (!this.config) { | |
throw new Error(CONFIG_ERROR_MSG); | |
} | |
const _config = await this.config_success(this.config); | |
return _config; | |
} catch (e) { | |
if (status_callback) { | |
status_callback({ | |
status: "error", | |
message: "Could not load this space.", | |
load_status: "error", | |
detail: "NOT_FOUND" | |
}); | |
} | |
throw e; | |
} | |
} | |
} | |
async component_server(component_id, fn_name, data) { | |
var _a; | |
if (!this.config) { | |
throw new Error(CONFIG_ERROR_MSG); | |
} | |
const headers = {}; | |
const { hf_token } = this.options; | |
const { session_hash } = this; | |
if (hf_token) { | |
headers.Authorization = `Bearer ${this.options.hf_token}`; | |
} | |
let root_url; | |
let component = this.config.components.find( | |
(comp) => comp.id === component_id | |
); | |
if ((_a = component == null ? void 0 : component.props) == null ? void 0 : _a.root_url) { | |
root_url = component.props.root_url; | |
} else { | |
root_url = this.config.root; | |
} | |
let body; | |
if ("binary" in data) { | |
body = new FormData(); | |
for (const key in data.data) { | |
if (key === "binary") | |
continue; | |
body.append(key, data.data[key]); | |
} | |
body.set("component_id", component_id.toString()); | |
body.set("fn_name", fn_name); | |
body.set("session_hash", session_hash); | |
} else { | |
body = JSON.stringify({ | |
data, | |
component_id, | |
fn_name, | |
session_hash | |
}); | |
headers["Content-Type"] = "application/json"; | |
} | |
if (hf_token) { | |
headers.Authorization = `Bearer ${hf_token}`; | |
} | |
try { | |
const response = await this.fetch(`${root_url}/component_server/`, { | |
method: "POST", | |
body, | |
headers, | |
credentials: "include" | |
}); | |
if (!response.ok) { | |
throw new Error( | |
"Could not connect to component server: " + response.statusText | |
); | |
} | |
const output = await response.json(); | |
return output; | |
} catch (e) { | |
console.warn(e); | |
} | |
} | |
set_cookies(raw_cookies) { | |
this.cookies = parse_and_set_cookies(raw_cookies).join("; "); | |
} | |
prepare_return_obj() { | |
return { | |
config: this.config, | |
predict: this.predict, | |
submit: this.submit, | |
view_api: this.view_api, | |
component_server: this.component_server | |
}; | |
} | |
} | |
async function client(app_reference, options = { | |
events: ["data"] | |
}) { | |
return await Client.connect(app_reference, options); | |
} | |
async function duplicate_space(app_reference, options) { | |
return await Client.duplicate(app_reference, options); | |
} | |
export { | |
Client, | |
FileData, | |
client, | |
duplicate_space as duplicate, | |
handle_file, | |
predict, | |
prepare_files, | |
submit, | |
upload, | |
upload_files | |
}; | |