|
import { |
|
type ApiData, |
|
type BlobRef, |
|
type Config, |
|
type EndpointInfo, |
|
type JsApiData, |
|
type DataType, |
|
Command, |
|
type Dependency, |
|
type ComponentMeta |
|
} from "../types"; |
|
import { FileData } from "../upload"; |
|
|
|
const is_node = |
|
typeof process !== "undefined" && process.versions && process.versions.node; |
|
|
|
export function update_object( |
|
object: { [x: string]: any }, |
|
newValue: any, |
|
stack: (string | number)[] |
|
): void { |
|
while (stack.length > 1) { |
|
const key = stack.shift(); |
|
if (typeof key === "string" || typeof key === "number") { |
|
object = object[key]; |
|
} else { |
|
throw new Error("Invalid key type"); |
|
} |
|
} |
|
|
|
const key = stack.shift(); |
|
if (typeof key === "string" || typeof key === "number") { |
|
object[key] = newValue; |
|
} else { |
|
throw new Error("Invalid key type"); |
|
} |
|
} |
|
|
|
export async function walk_and_store_blobs( |
|
data: DataType, |
|
type: string | undefined = undefined, |
|
path: string[] = [], |
|
root = false, |
|
endpoint_info: EndpointInfo<ApiData | JsApiData> | undefined = undefined |
|
): Promise<BlobRef[]> { |
|
if (Array.isArray(data)) { |
|
let blob_refs: BlobRef[] = []; |
|
|
|
await Promise.all( |
|
data.map(async (_, index) => { |
|
let new_path = path.slice(); |
|
new_path.push(String(index)); |
|
|
|
const array_refs = await walk_and_store_blobs( |
|
data[index], |
|
root |
|
? endpoint_info?.parameters[index]?.component || undefined |
|
: type, |
|
new_path, |
|
false, |
|
endpoint_info |
|
); |
|
|
|
blob_refs = blob_refs.concat(array_refs); |
|
}) |
|
); |
|
|
|
return blob_refs; |
|
} else if ( |
|
(globalThis.Buffer && data instanceof globalThis.Buffer) || |
|
data instanceof Blob |
|
) { |
|
return [ |
|
{ |
|
path: path, |
|
blob: new Blob([data]), |
|
type |
|
} |
|
]; |
|
} else if (typeof data === "object" && data !== null) { |
|
let blob_refs: BlobRef[] = []; |
|
for (const key of Object.keys(data) as (keyof typeof data)[]) { |
|
const new_path = [...path, key]; |
|
const value = data[key]; |
|
|
|
blob_refs = blob_refs.concat( |
|
await walk_and_store_blobs( |
|
value, |
|
undefined, |
|
new_path, |
|
false, |
|
endpoint_info |
|
) |
|
); |
|
} |
|
|
|
return blob_refs; |
|
} |
|
|
|
return []; |
|
} |
|
|
|
export function skip_queue(id: number, config: Config): boolean { |
|
let fn_queue = config?.dependencies?.find((dep) => dep.id == id)?.queue; |
|
if (fn_queue != null) { |
|
return !fn_queue; |
|
} |
|
return !config.enable_queue; |
|
} |
|
|
|
|
|
|
|
export function post_message<Res = any>( |
|
message: any, |
|
origin: string |
|
): Promise<Res> { |
|
return new Promise((res, _rej) => { |
|
const channel = new MessageChannel(); |
|
channel.port1.onmessage = (({ data }) => { |
|
channel.port1.close(); |
|
res(data); |
|
}) as (ev: MessageEvent<Res>) => void; |
|
window.parent.postMessage(message, origin, [channel.port2]); |
|
}); |
|
} |
|
|
|
export function handle_file( |
|
file_or_url: File | string | Blob | Buffer |
|
): FileData | Blob | Command { |
|
if (typeof file_or_url === "string") { |
|
if ( |
|
file_or_url.startsWith("http://") || |
|
file_or_url.startsWith("https://") |
|
) { |
|
return { |
|
path: file_or_url, |
|
url: file_or_url, |
|
orig_name: file_or_url.split("/").pop() ?? "unknown", |
|
meta: { _type: "gradio.FileData" } |
|
}; |
|
} |
|
|
|
if (is_node) { |
|
|
|
return new Command("upload_file", { |
|
path: file_or_url, |
|
name: file_or_url, |
|
orig_path: file_or_url |
|
}); |
|
} |
|
} else if (typeof File !== "undefined" && file_or_url instanceof File) { |
|
return new Blob([file_or_url]); |
|
} 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." |
|
); |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export function handle_payload( |
|
resolved_payload: unknown[], |
|
dependency: Dependency, |
|
components: ComponentMeta[], |
|
type: "input" | "output", |
|
with_null_state = false |
|
): unknown[] { |
|
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: unknown[] = []; |
|
let payload_index = 0; |
|
const deps = type === "input" ? dependency.inputs : dependency.outputs; |
|
for (let i = 0; i < deps.length; i++) { |
|
const input_id = deps[i]; |
|
const component = components.find((c) => c.id === input_id); |
|
|
|
if (component?.type === "state") { |
|
|
|
if (with_null_state) { |
|
if (resolved_payload.length === deps.length) { |
|
const value = resolved_payload[payload_index]; |
|
updated_payload.push(value); |
|
payload_index++; |
|
} else { |
|
updated_payload.push(null); |
|
} |
|
} else { |
|
|
|
|
|
payload_index++; |
|
continue; |
|
} |
|
|
|
continue; |
|
} else { |
|
const value = resolved_payload[payload_index]; |
|
updated_payload.push(value); |
|
payload_index++; |
|
} |
|
} |
|
|
|
return updated_payload; |
|
} |
|
|