|
<script lang="ts">
|
|
import "@gradio/theme/reset.css";
|
|
import "@gradio/theme/global.css";
|
|
import "@gradio/theme/pollen.css";
|
|
import "@gradio/theme/typography.css";
|
|
|
|
import { onDestroy, SvelteComponent } from "svelte";
|
|
import Index from "@self/spa";
|
|
import Playground from "./Playground.svelte";
|
|
import ErrorDisplay from "./ErrorDisplay.svelte";
|
|
import type { ThemeMode } from "@gradio/core";
|
|
import { WorkerProxy, type WorkerProxyOptions } from "@gradio/wasm";
|
|
import { FAKE_LITE_HOST } from "@gradio/wasm/network";
|
|
import { Client } from "@gradio/client";
|
|
import { wasm_proxied_fetch } from "./fetch";
|
|
import { wasm_proxied_stream_factory } from "./sse";
|
|
import { wasm_proxied_mount_css, mount_prebuilt_css } from "./css";
|
|
import type { mount_css } from "@gradio/core";
|
|
|
|
|
|
import gradioWheel from "gradio.whl";
|
|
import gradioClientWheel from "gradio_client.whl";
|
|
|
|
export let info: boolean;
|
|
export let container: boolean;
|
|
export let is_embed: boolean;
|
|
export let initial_height: string;
|
|
export let eager: boolean;
|
|
export let version: string;
|
|
export let theme_mode: ThemeMode | null;
|
|
export let autoscroll: boolean;
|
|
export let control_page_title: boolean;
|
|
export let app_mode: boolean;
|
|
|
|
|
|
export let files: WorkerProxyOptions["files"] | undefined;
|
|
export let requirements: WorkerProxyOptions["requirements"] | undefined;
|
|
export let code: string | undefined;
|
|
export let entrypoint: string | undefined;
|
|
export let sharedWorkerMode: boolean | undefined;
|
|
|
|
|
|
export let playground = false;
|
|
export let layout: string | null;
|
|
|
|
const worker_proxy = new WorkerProxy({
|
|
gradioWheelUrl: new URL(gradioWheel, import.meta.url).href,
|
|
gradioClientWheelUrl: new URL(gradioClientWheel, import.meta.url).href,
|
|
files: files ?? {},
|
|
requirements: requirements ?? [],
|
|
sharedWorkerMode: sharedWorkerMode ?? false
|
|
});
|
|
onDestroy(() => {
|
|
worker_proxy.terminate();
|
|
});
|
|
|
|
let error: Error | null = null;
|
|
|
|
const wrapFunctionWithAppLogic = <TArgs extends any[], TRet extends any>(
|
|
func: (...args: TArgs) => Promise<TRet>
|
|
): ((...args: TArgs) => Promise<TRet>) => {
|
|
return async (...args: TArgs) => {
|
|
try {
|
|
error = null;
|
|
const retval = await func(...args);
|
|
refresh_index_component();
|
|
return retval;
|
|
} catch (err) {
|
|
error = err as Error;
|
|
throw err;
|
|
}
|
|
};
|
|
};
|
|
worker_proxy.runPythonCode = wrapFunctionWithAppLogic(
|
|
worker_proxy.runPythonCode.bind(worker_proxy)
|
|
);
|
|
worker_proxy.runPythonFile = wrapFunctionWithAppLogic(
|
|
worker_proxy.runPythonFile.bind(worker_proxy)
|
|
);
|
|
worker_proxy.writeFile = wrapFunctionWithAppLogic(
|
|
worker_proxy.writeFile.bind(worker_proxy)
|
|
);
|
|
worker_proxy.renameFile = wrapFunctionWithAppLogic(
|
|
worker_proxy.renameFile.bind(worker_proxy)
|
|
);
|
|
worker_proxy.unlink = wrapFunctionWithAppLogic(
|
|
worker_proxy.unlink.bind(worker_proxy)
|
|
);
|
|
worker_proxy.install = wrapFunctionWithAppLogic(
|
|
worker_proxy.install.bind(worker_proxy)
|
|
);
|
|
|
|
worker_proxy.addEventListener("initialization-error", (event) => {
|
|
error = (event as CustomEvent).detail;
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
if (code != null) {
|
|
worker_proxy.runPythonCode(code);
|
|
} else if (entrypoint != null) {
|
|
worker_proxy.runPythonFile(entrypoint);
|
|
} else {
|
|
throw new Error("Either code or entrypoint must be provided.");
|
|
}
|
|
|
|
mount_prebuilt_css(document.head);
|
|
|
|
class LiteClient extends Client {
|
|
fetch(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
|
|
return wasm_proxied_fetch(worker_proxy, input, init);
|
|
}
|
|
|
|
stream(url: URL): EventSource {
|
|
return wasm_proxied_stream_factory(worker_proxy, url);
|
|
}
|
|
}
|
|
|
|
const overridden_mount_css: typeof mount_css = async (url, target) => {
|
|
return wasm_proxied_mount_css(worker_proxy, url, target);
|
|
};
|
|
|
|
let index_component_key = 0;
|
|
function refresh_index_component(): void {
|
|
index_component_key += 1;
|
|
}
|
|
|
|
let playground_component: SvelteComponent | null = null;
|
|
$: playground_component?.$on("code", (event) => {
|
|
const { code } = event.detail;
|
|
worker_proxy.runPythonCode(code);
|
|
});
|
|
|
|
export const run_code = worker_proxy.runPythonCode;
|
|
export const run_file = worker_proxy.runPythonFile;
|
|
export const write = worker_proxy.writeFile;
|
|
export const rename = worker_proxy.renameFile;
|
|
export const unlink = worker_proxy.unlink;
|
|
export const install = worker_proxy.install;
|
|
</script>
|
|
|
|
{#if playground}
|
|
<Playground
|
|
bind:this={playground_component}
|
|
{worker_proxy}
|
|
{layout}
|
|
{code}
|
|
{is_embed}
|
|
>
|
|
{#key index_component_key}
|
|
{#if error}
|
|
<ErrorDisplay {error} is_embed />
|
|
{:else}
|
|
<Index
|
|
space={null}
|
|
src={null}
|
|
host={null}
|
|
{info}
|
|
{container}
|
|
{is_embed}
|
|
{initial_height}
|
|
{eager}
|
|
{version}
|
|
{theme_mode}
|
|
{autoscroll}
|
|
{control_page_title}
|
|
{app_mode}
|
|
{worker_proxy}
|
|
Client={LiteClient}
|
|
mount_css={overridden_mount_css}
|
|
/>
|
|
{/if}
|
|
{/key}
|
|
</Playground>
|
|
{:else}
|
|
{#key index_component_key}
|
|
{#if error}
|
|
<ErrorDisplay {error} {is_embed} />
|
|
{:else}
|
|
<Index
|
|
space={null}
|
|
src={null}
|
|
host={FAKE_LITE_HOST}
|
|
{info}
|
|
{container}
|
|
{is_embed}
|
|
{initial_height}
|
|
{eager}
|
|
{version}
|
|
{theme_mode}
|
|
{autoscroll}
|
|
{control_page_title}
|
|
{app_mode}
|
|
{worker_proxy}
|
|
Client={LiteClient}
|
|
mount_css={overridden_mount_css}
|
|
/>
|
|
{/if}
|
|
{/key}
|
|
{/if}
|
|
|