diff --git "a/node_modules/@gradio/client/dist/index.js" "b/node_modules/@gradio/client/dist/index.js" --- "a/node_modules/@gradio/client/dist/index.js" +++ "b/node_modules/@gradio/client/dist/index.js" @@ -1,18 +1,167 @@ +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 } = new URL(endpoint); + const { protocol, host, pathname } = new URL(endpoint); if (host.endsWith("hf.space")) { return { ws_protocol: "wss", @@ -23,7 +172,7 @@ function determine_protocol(endpoint) { return { ws_protocol: protocol === "https:" ? "wss" : "ws", http_protocol: protocol, - host + host: host + (pathname !== "/" ? pathname : "") }; } else if (endpoint.startsWith("file:")) { return { @@ -39,29 +188,38 @@ function determine_protocol(endpoint) { host: endpoint }; } -const RE_SPACE_NAME = /^[^\/]*\/[^\/]*$/; +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, token) { +async function process_endpoint(app_reference, hf_token) { const headers = {}; - if (token) { - headers.Authorization = `Bearer ${token}`; + if (hf_token) { + headers.Authorization = `Bearer ${hf_token}`; } - const _app_reference = app_reference.trim(); + 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`, + `https://huggingface.co/api/spaces/${_app_reference}/${HOST_URL}`, { headers } ); - if (res.status !== 200) - throw new Error("Space metadata could not be loaded."); const _host = (await res.json()).host; return { space_id: app_reference, ...determine_protocol(_host) }; } catch (e) { - throw new Error("Space metadata could not be loaded." + e.message); + throw new Error(SPACE_METADATA_ERROR_MSG); } } if (RE_SPACE_DOMAIN.test(_app_reference)) { @@ -78,161 +236,371 @@ async function process_endpoint(app_reference, token) { ...determine_protocol(_app_reference) }; } -function map_names_to_ids(fns) { - let apis = {}; - fns.forEach(({ api_name }, i) => { - if (api_name) - apis[api_name] = i; - }); - return apis; -} -const RE_DISABLED_DISCUSSION = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/; -async function discussions_enabled(space_id) { +const join_urls = (...urls) => { try { - const r = await fetch( - `https://huggingface.co/api/spaces/${space_id}/discussions`, - { - method: "HEAD" - } - ); - const error = r.headers.get("x-error-message"); - if (error && RE_DISABLED_DISCUSSION.test(error)) - return false; - return true; + return urls.reduce((base_url, part) => { + base_url = base_url.replace(/\/+$/, ""); + part = part.replace(/^\/+/, ""); + return new URL(part, base_url + "/").toString(); + }); } catch (e) { - return false; + 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; } -async function get_space_hardware(space_id, token) { - const headers = {}; - if (token) { - headers.Authorization = `Bearer ${token}`; +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"; } - try { - const res = await fetch( - `https://huggingface.co/api/spaces/${space_id}/runtime`, - { headers } - ); - if (res.status !== 200) - throw new Error("Space hardware could not be obtained."); - const { hardware } = await res.json(); - return hardware; - } catch (e) { - throw new Error(e.message); + 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))][]`; } } -async function set_space_hardware(space_id, new_hardware, token) { - const headers = {}; - if (token) { - headers.Authorization = `Bearer ${token}`; +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"; } - try { - const res = await fetch( - `https://huggingface.co/api/spaces/${space_id}/hardware`, - { headers, body: JSON.stringify(new_hardware) } - ); - if (res.status !== 200) - throw new Error( - "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in." - ); - const { hardware } = await res.json(); - return hardware; - } catch (e) { - throw new Error(e.message); + 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 } }; } -async function set_space_timeout(space_id, timeout, token) { - const headers = {}; - if (token) { - headers.Authorization = `Bearer ${token}`; +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; } - try { - const res = await fetch( - `https://huggingface.co/api/spaces/${space_id}/hardware`, - { headers, body: JSON.stringify({ seconds: timeout }) } - ); - if (res.status !== 200) + 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( - "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in." + `No value provided for required parameter: ${param.parameter_name}` ); - const { hardware } = await res.json(); - return hardware; - } catch (e) { - throw new Error(e.message); - } -} -const hardware_types = [ - "cpu-basic", - "cpu-upgrade", - "t4-small", - "t4-medium", - "a10g-small", - "a10g-large", - "a100-large" -]; -function normalise_file(file, server_url, proxy_url) { - if (file == null) { - return null; - } - if (Array.isArray(file)) { - const normalized_file = []; - for (const x of file) { - if (x == null) { - normalized_file.push(null); - } else { - normalized_file.push(normalise_file(x, server_url, proxy_url)); - } } - return normalized_file; - } - if (file.is_stream) { - if (proxy_url == null) { - return new FileData({ - ...file, - url: server_url + "/stream/" + file.path - }); + }); + 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.` + ); } - return new FileData({ - ...file, - url: "/proxy=" + proxy_url + "stream/" + file.path - }); - } - return new FileData({ - ...file, - url: get_fetchable_url_or_file(file.path, server_url, proxy_url) }); -} -function is_url(str) { + 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 { - const url = new URL(str); - return url.protocol === "http:" || url.protocol === "https:"; - } catch { - return false; + 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; } } -function get_fetchable_url_or_file(path, server_url, proxy_url) { - if (path == null) { - return proxy_url ? `/proxy=${proxy_url}file=` : `${server_url}/file=`; +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}`; } - if (is_url(path)) { - return path; + 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 proxy_url ? `/proxy=${proxy_url}file=${path}` : `${server_url}/file=${path}`; + return { files: uploadResponses }; } -async function upload(file_data, root, upload_id, upload_fn = upload_files) { +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 upload_fn(root, files, void 0, upload_id).then( + 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 }); - return normalise_file(file, root, null); + const file = new FileData({ + ...file_data[i], + path: f, + url: root_url + "/file=" + f + }); + return file; }); } return []; @@ -243,7 +611,7 @@ async function upload(file_data, root, upload_id, upload_fn = upload_files) { } async function prepare_files(files, is_stream) { return files.map( - (f, i) => new FileData({ + (f) => new FileData({ path: f.name, orig_name: f.name, blob: f, @@ -264,6 +632,15 @@ class FileData { 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; @@ -274,1319 +651,1831 @@ class FileData { this.alt_text = alt_text; } } -const QUEUE_FULL_MSG = "This application is too busy. Keep trying!"; -const BROKEN_CONNECTION_MSG = "Connection errored out."; -let NodeBlob; -async function duplicate(app_reference, options) { - const { hf_token, private: _private, hardware, timeout } = options; - if (hardware && !hardware_types.includes(hardware)) { - throw new Error( - `Invalid hardware type provided. Valid types are: ${hardware_types.map((v) => `"${v}"`).join(",")}.` - ); +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 headers = { - Authorization: `Bearer ${hf_token}` - }; - 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; +} +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"); + } } - try { - const response = await fetch( - `https://huggingface.co/api/spaces/${app_reference}/duplicate`, + 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 [ { - method: "POST", - headers: { "Content-Type": "application/json", ...headers }, - body: JSON.stringify(body) + path, + blob: new Blob([data]), + type } - ); - if (response.status === 409) { - return client(`${user}/${space_name}`, options); - } - const duplicated_space = await response.json(); - let original_hardware; - if (!hardware) { - original_hardware = await get_space_hardware(app_reference, hf_token); + ]; + } 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 + ) + ); } - const requested_hardware = hardware || original_hardware || "cpu-basic"; - await set_space_hardware( - `${user}/${space_name}`, - requested_hardware, - hf_token - ); - await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token); - return client(duplicated_space.url, options); - } catch (e) { - throw new Error(e); + 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 api_factory(fetch_implementation, EventSource_factory) { - return { post_data: post_data2, upload_files: upload_files2, client: client2, handle_blob: handle_blob2 }; - async function post_data2(url, body, token) { - const headers = { "Content-Type": "application/json" }; - if (token) { - headers.Authorization = `Bearer ${token}`; +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" } + }; } - try { - var response = await fetch_implementation(url, { - method: "POST", - body: JSON.stringify(body), - headers + if (is_node) { + return new Command("upload_file", { + path: file_or_url, + name: file_or_url, + orig_path: file_or_url }); - } 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; + } 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 [output, status]; } - async function upload_files2(root, files, token, upload_id) { - const headers = {}; - if (token) { - headers.Authorization = `Bearer ${token}`; + 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]); } - const chunkSize = 1e3; - const uploadResponses = []; - 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); + } +} +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 || "" }); - try { - const upload_url = upload_id ? `${root}/upload?upload_id=${upload_id}` : `${root}/upload`; - var response = await fetch_implementation(upload_url, { - method: "POST", - body: formData, - headers - }); - } catch (e) { - return { error: BROKEN_CONNECTION_MSG }; - } - const output = await response.json(); - uploadResponses.push(...output); + data[key] = fileData; } - return { files: uploadResponses }; - } - async function client2(app_reference, options = { normalise_files: true }) { - return new Promise(async (res) => { - const { status_callback, hf_token, normalise_files } = options; - const return_obj = { - predict, - submit, - view_api, - component_server - }; - const transform_files = normalise_files ?? true; - if ((typeof window === "undefined" || !("WebSocket" in window)) && !global.Websocket) { - const ws = await import("./wrapper-6f348d45.js"); - NodeBlob = (await import("node:buffer")).Blob; - global.WebSocket = ws.WebSocket; - } - const { ws_protocol, http_protocol, host, space_id } = await process_endpoint(app_reference, hf_token); - const session_hash = Math.random().toString(36).substring(2); - const last_status = {}; - let stream_open = false; - let pending_stream_messages = {}; - let event_stream = null; - const event_callbacks = {}; - const unclosed_events = /* @__PURE__ */ new Set(); - let config; - let api_map = {}; - let jwt = false; - if (hf_token && space_id) { - jwt = await get_jwt(space_id, hf_token); - } - async function config_success(_config) { - config = _config; - api_map = map_names_to_ids((_config == null ? void 0 : _config.dependencies) || []); - if (config.auth_required) { - return { - config, - ...return_obj - }; - } - try { - api = await view_api(config); - } catch (e) { - console.error(`Could not get api details: ${e.message}`); + } 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); } - return { - config, - ...return_obj - }; + data_returned = true; + result = message; } - let api; - async function handle_space_sucess(status) { - if (status_callback) - status_callback(status); - if (status.status === "running") - try { - config = await resolve_config( - fetch_implementation, - `${http_protocol}//${host}`, - hf_token - ); - const _config = await config_success(config); - res(_config); - } catch (e) { - console.error(e); - if (status_callback) { - status_callback({ - status: "error", - message: "Could not load this space.", - load_status: "error", - detail: "NOT_FOUND" - }); - } + if (message.type === "status") { + if (message.stage === "error") + reject(message); + if (message.stage === "complete") { + status_complete = true; + if (data_returned) { + resolve(result); } - } - try { - config = await resolve_config( - fetch_implementation, - `${http_protocol}//${host}`, - hf_token - ); - const _config = await config_success(config); - res(_config); - } catch (e) { - console.error(e); - if (space_id) { - check_space_status( - space_id, - RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain", - handle_space_sucess - ); - } else { - if (status_callback) - status_callback({ - status: "error", - message: "Could not load this space.", - load_status: "error", - detail: "NOT_FOUND" - }); - } - } - function predict(endpoint, data, event_data) { - let data_returned = false; - let status_complete = false; - let dependency; - if (typeof endpoint === "number") { - dependency = config.dependencies[endpoint]; - } else { - const trimmed_endpoint = endpoint.replace(/^\//, ""); - dependency = config.dependencies[api_map[trimmed_endpoint]]; - } - if (dependency.types.continuous) { - throw new Error( - "Cannot call predict on this function as it may run forever. Use submit instead" - ); } - return new Promise((res2, rej) => { - const app = submit(endpoint, data, event_data); - let result; - app.on("data", (d) => { - if (status_complete) { - app.destroy(); - res2(d); - } - data_returned = true; - result = d; - }).on("status", (status) => { - if (status.stage === "error") - rej(status); - if (status.stage === "complete") { - status_complete = true; - if (data_returned) { - app.destroy(); - res2(result); - } - } - }); - }); } - function submit(endpoint, data, event_data, trigger_id = null) { - let fn_index; - let api_info; - if (typeof endpoint === "number") { - fn_index = endpoint; - api_info = api.unnamed_endpoints[fn_index]; - } else { - const trimmed_endpoint = endpoint.replace(/^\//, ""); - fn_index = api_map[trimmed_endpoint]; - api_info = api.named_endpoints[endpoint.trim()]; - } - if (typeof fn_index !== "number") { - throw new Error( - "There is no endpoint matching that name of fn_index matching that number." - ); - } - let websocket; - let eventSource; - let protocol = config.protocol ?? "ws"; - const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint; - let payload; - let event_id = null; - let complete = false; - const listener_map = {}; - let url_params = ""; - if (typeof window !== "undefined") { - url_params = new URLSearchParams(window.location.search).toString(); - } - handle_blob2(`${config.root}`, data, api_info, hf_token).then( - (_payload) => { - payload = { - data: _payload || [], - 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 - }, - hf_token - ).then(([output, status_code]) => { - const data2 = transform_files ? transform_output( - output.data, - api_info, - config.root, - config.root_url - ) : output.data; - if (status_code == 200) { - fire_event({ - type: "data", - endpoint: _endpoint, - fn_index, - data: data2, - time: /* @__PURE__ */ new Date() - }); - 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") { - 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 (jwt) { - url.searchParams.set("__sign", jwt); + } + }); +} +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); } - 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: transform_files ? transform_output( - data2.data, - api_info, - config.root, - config.root_url - ) : data2.data, - endpoint: _endpoint, - fn_index - }); - 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 })) - ); + 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 (protocol == "sse") { + } 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", - stage: "pending", + 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, - time: /* @__PURE__ */ new Date() + event_data, + trigger_id }); - var params = new URLSearchParams({ - fn_index: fn_index.toString(), + 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 - }).toString(); - let url = new URL( - `${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}` - ); - eventSource = EventSource_factory(url); - eventSource.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") { - eventSource.close(); - } - } else if (type === "data") { - event_id = _data.event_id; - let [_, status2] = await post_data2( - `${config.root}/queue/data`, - { - ...payload, - session_hash, - event_id - }, - hf_token + }, + 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 (status2 !== 200) { + 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: BROKEN_CONNECTION_MSG, + message: (status2 == null ? void 0 : status2.message) || "An Unexpected Error Occurred!", queue: true, endpoint: _endpoint, fn_index, time: /* @__PURE__ */ new Date() }); - eventSource.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: transform_files ? transform_output( - data2.data, - api_info, - config.root, - config.root_url - ) : data2.data, - endpoint: _endpoint, - fn_index - }); - if (complete) { + } 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(), - ...complete, - stage: status == null ? void 0 : status.stage, + ...status2, + stage: status2 == null ? void 0 : status2.stage, queue: true, endpoint: _endpoint, fn_index }); - eventSource.close(); + if (data2 && ["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) { + apply_diff_stream(pending_diff_streams, event_id, data2); + } } - } - }; - } else if (protocol == "sse_v1") { - fire_event({ - type: "status", - stage: "pending", - queue: true, - endpoint: _endpoint, - fn_index, - time: /* @__PURE__ */ new Date() - }); - post_data2( - `${config.root}/queue/join?${url_params}`, - { - ...payload, - session_hash - }, - hf_token - ).then(([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) { + 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: BROKEN_CONNECTION_MSG, + message: "An Unexpected Error Occurred!", 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) { - fire_event({ - type: "data", - time: /* @__PURE__ */ new Date(), - data: transform_files ? transform_output( - data2.data, - api_info, - config.root, - config.root_url - ) : data2.data, - endpoint: _endpoint, - fn_index - }); - 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]; - } - } - } 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() - }); - close_stream(); - } - }; - 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_open) { - open_stream(); + if (["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) { + close_stream(stream_status, that.abort_controller); + stream_status.open = false; + close(); } } - }); - } - } - ); - function fire_event(event) { - const narrowed_listener_map = listener_map; - const listeners = narrowed_listener_map[event.type] || []; - listeners == null ? void 0 : listeners.forEach((l) => l(event)); - } - function on(eventType, listener) { - const narrowed_listener_map = listener_map; - const listeners = narrowed_listener_map[eventType] || []; - narrowed_listener_map[eventType] = listeners; - listeners == null ? void 0 : listeners.push(listener); - return { on, off, cancel, destroy }; - } - function off(eventType, listener) { - const narrowed_listener_map = listener_map; - let listeners = narrowed_listener_map[eventType] || []; - listeners = listeners == null ? void 0 : listeners.filter((l) => l !== listener); - narrowed_listener_map[eventType] = listeners; - return { on, off, cancel, destroy }; - } - 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 cancel_request = {}; - if (protocol === "ws") { - if (websocket && websocket.readyState === 0) { - websocket.addEventListener("open", () => { - websocket.close(); - }); - } else { - websocket.close(); - } - cancel_request = { fn_index, session_hash }; - } else { - eventSource.close(); - cancel_request = { event_id }; - } - try { - await fetch_implementation(`${config.root}/reset`, { - headers: { "Content-Type": "application/json" }, - method: "POST", - body: JSON.stringify(cancel_request) - }); - } catch (e) { - console.warn( - "The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable." - ); - } - } - function destroy() { - for (const event_type in listener_map) { - listener_map[event_type].forEach((fn2) => { - off(event_type, fn2); - }); - } - } - return { - on, - off, - cancel, - destroy - }; - } - function open_stream() { - stream_open = true; - let params = new URLSearchParams({ - session_hash - }).toString(); - let url = new URL(`${config.root}/queue/data?${params}`); - event_stream = EventSource_factory(url); - event_stream.onmessage = async function(event) { - let _data = JSON.parse(event.data); - 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]) { - if (_data.msg === "process_completed") { - unclosed_events.delete(event_id); - if (unclosed_events.size === 0) { - close_stream(); + }; + 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 fn2 = event_callbacks[event_id]; - window.setTimeout(fn2, 0, _data); - } else { - if (!pending_stream_messages[event_id]) { - pending_stream_messages[event_id] = []; - } - pending_stream_messages[event_id].push(_data); - } - }; - event_stream.onerror = async function(event) { - await Promise.all( - Object.keys(event_callbacks).map( - (event_id) => event_callbacks[event_id]({ - msg: "unexpected_error", - message: BROKEN_CONNECTION_MSG - }) - ) - ); - close_stream(); - }; - } - function close_stream() { - stream_open = false; - event_stream == null ? void 0 : event_stream.close(); - } - async function component_server(component_id, fn_name, data) { - var _a; - const headers = { "Content-Type": "application/json" }; - if (hf_token) { - headers.Authorization = `Bearer ${hf_token}`; - } - let root_url; - let component = 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 = config.root; - } - const response = await fetch_implementation( - `${root_url}/component_server/`, - { - method: "POST", - body: JSON.stringify({ - data, - component_id, - fn_name, - session_hash - }), - headers - } - ); - if (!response.ok) { - throw new Error( - "Could not connect to component server: " + response.statusText - ); - } - const output = await response.json(); - return output; - } - async function view_api(config2) { - if (api) - return api; - const headers = { "Content-Type": "application/json" }; - if (hf_token) { - headers.Authorization = `Bearer ${hf_token}`; - } - let response; - if (semiver(config2.version || "2.0.0", "3.30") < 0) { - response = await fetch_implementation( - "https://gradio-space-api-fetcher-v2.hf.space/api", - { - method: "POST", - body: JSON.stringify({ - serialize: false, - config: JSON.stringify(config2) - }), - headers - } - ); - } else { - response = await fetch_implementation(`${config2.root}/info`, { - headers }); } - 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"]; - } - const x = transform_api_info(api_info, config2, api_map); - return x; } - }); + ); + 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; } - async function handle_blob2(endpoint, data, api_info, token) { - const blob_refs = await walk_and_store_blobs( - data, - void 0, - [], - true, - api_info +} +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 Promise.all( - blob_refs.map(async ({ path, blob, type }) => { - if (blob) { - const file_url = (await upload_files2(endpoint, [blob], token)).files[0]; - return { path, file_url, type, name: blob == null ? void 0 : blob.name }; - } - return { path, type }; - }) - ).then((r) => { - r.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; - }); } + return { fn_index, endpoint_info, dependency }; } -const { post_data, upload_files, client, handle_blob } = api_factory( - fetch, - (...args) => new EventSource(...args) -); -function transform_output(data, api_info, root_url, remote_url) { - return data.map((d, i) => { - var _a, _b, _c, _d; - if (((_b = (_a = api_info == null ? void 0 : api_info.returns) == null ? void 0 : _a[i]) == null ? void 0 : _b.component) === "File") { - return normalise_file(d, root_url, remote_url); - } else if (((_d = (_c = api_info == null ? void 0 : api_info.returns) == null ? void 0 : _c[i]) == null ? void 0 : _d.component) === "Gallery") { - return d.map((img) => { - return Array.isArray(img) ? [normalise_file(img[0], root_url, remote_url), img[1]] : [normalise_file(img, root_url, remote_url), null]; - }); - } else if (typeof d === "object" && d.path) { - return normalise_file(d, root_url, remote_url); +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"]; } - return d; - }); -} -function get_type(type, component, serializer, signature_type) { - switch (type.type) { - case "string": - return "string"; - case "boolean": - return "boolean"; - case "number": - return "number"; + 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); } - 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}[]`; + fetch(input, init) { + const headers = new Headers((init == null ? void 0 : init.headers) || {}); + if (this && this.cookies) { + headers.append("Cookie", this.cookies); } - 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))][]`; + return fetch(input, { ...init, headers }); } -} -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"; + stream(url) { + this.abort_controller = new AbortController(); + this.stream_instance = readable_stream(url.toString(), { + signal: this.abort_controller.signal + }); + return this.stream_instance; } - return type.description; -} -function transform_api_info(api_info, config, api_map) { - const new_data = { - named_endpoints: {}, - unnamed_endpoints: {} - }; - for (const key in api_info) { - const cat = api_info[key]; - for (const endpoint in cat) { - const dep_index = config.dependencies[endpoint] ? endpoint : api_map[endpoint.replace("/", "")]; - const info = cat[endpoint]; - new_data[key][endpoint] = {}; - new_data[key][endpoint].parameters = {}; - new_data[key][endpoint].returns = {}; - new_data[key][endpoint].type = config.dependencies[dep_index].types; - new_data[key][endpoint].parameters = info.parameters.map( - ({ label, component, type, serializer }) => ({ - label, - component, - type: get_type(type, component, serializer, "parameter"), - description: get_description(type, serializer) - }) - ); - new_data[key][endpoint].returns = info.returns.map( - ({ label, component, type, serializer }) => ({ - label, - component, - type: get_type(type, component, serializer, "return"), - description: get_description(type, serializer) - }) + 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) || []); } - return new_data; -} -async function get_jwt(space, token) { - try { - const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, { - headers: { - Authorization: `Bearer ${token}` + 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 + ); + } } - }); - const jwt = (await r.json()).token; - return jwt || false; - } catch (e) { - console.error(e); - return false; + } + 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); + } + } } -} -function update_object(object, newValue, stack) { - while (stack.length > 1) { - object = object[stack.shift()]; + 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(); } - object[stack.shift()] = newValue; -} -async function walk_and_store_blobs(param, type = void 0, path = [], root = false, api_info = void 0) { - if (Array.isArray(param)) { - let blob_refs = []; - await Promise.all( - param.map(async (v, i) => { - var _a; - let new_path = path.slice(); - new_path.push(i); - const array_refs = await walk_and_store_blobs( - param[i], - root ? ((_a = api_info == null ? void 0 : api_info.parameters[i]) == null ? void 0 : _a.component) || void 0 : type, - new_path, - false, - api_info - ); - blob_refs = blob_refs.concat(array_refs); - }) + 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 ); - return blob_refs; - } else if (globalThis.Buffer && param instanceof globalThis.Buffer) { - const is_image = type === "Image"; - return [ - { - path, - blob: is_image ? false : new NodeBlob([param]), - type + const { status_callback } = this.options; + let config; + try { + config = await this.resolve_config(`${http_protocol}//${host}`); + if (!config) { + throw new Error(CONFIG_ERROR_MSG); } - ]; - } else if (typeof param === "object") { - let blob_refs = []; - for (let key in param) { - if (param.hasOwnProperty(key)) { - let new_path = path.slice(); - new_path.push(key); - blob_refs = blob_refs.concat( - await walk_and_store_blobs( - param[key], - void 0, - new_path, - false, - api_info - ) + 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); } } - return blob_refs; - } - return []; -} -function skip_queue(id, config) { - var _a, _b, _c, _d; - return !(((_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a[id]) == null ? void 0 : _b.queue) === null ? config.enable_queue : (_d = (_c = config == null ? void 0 : config.dependencies) == null ? void 0 : _c[id]) == null ? void 0 : _d.queue) || false; -} -async function resolve_config(fetch_implementation, endpoint, token) { - const headers = {}; - if (token) { - headers.Authorization = `Bearer ${token}`; } - 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; - config.root = resolve_root(endpoint, config.root, false); - return { ...config, path }; - } else if (endpoint) { - let response = await fetch_implementation(`${endpoint}/config`, { - headers - }); - if (response.status === 200) { - const config = await response.json(); - config.path = config.path ?? ""; - config.root = endpoint; - return config; + 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(); } - throw new Error("Could not get config."); + try { + this.api_info = await this.view_api(); + } catch (e) { + console.error(API_INFO_ERROR_MSG + e.message); + } + return this.prepare_return_obj(); } - throw new Error("No config or app endpoint found"); -} -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(); + 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; + } } - response = await response.json(); - } catch (e) { - status_callback({ - status: "error", - load_status: "error", - message: "Could not get space status", - 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 + 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 }); - 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) + 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" }); - break; - } -} -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 - } - }; + if (!response.ok) { + throw new Error( + "Could not connect to component server: " + response.statusText + ); } - 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 - }, - 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 - } - }; + const output = await response.json(); + return output; + } catch (e) { + console.warn(e); + } } - return { type: "none", status: { stage: "error", queue } }; + 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, - api_factory, client, - duplicate, - get_fetchable_url_or_file, - normalise_file, - post_data, + duplicate_space as duplicate, + handle_file, + predict, prepare_files, + submit, upload, upload_files };