,
endpoint: string | number,
diff --git a/client/js/vite.config.js b/client/js/vite.config.js
index 61fb69fb579e3..efc4eda54e41e 100644
--- a/client/js/vite.config.js
+++ b/client/js/vite.config.js
@@ -3,30 +3,37 @@ import { svelte } from "@sveltejs/vite-plugin-svelte";
const TEST_MODE = process.env.TEST_MODE || "happy-dom";
-export default defineConfig({
- build: {
- lib: {
- entry: "src/index.ts",
- formats: ["es"],
- fileName: (format) => `index.${format}.js`
- },
- rollupOptions: {
- input: "src/index.ts",
- output: {
- dir: "dist"
+export default defineConfig(({ mode }) => {
+ if (mode === "preview") {
+ return {
+ entry: "index.html"
+ };
+ }
+ return {
+ build: {
+ lib: {
+ entry: "src/index.ts",
+ formats: ["es"],
+ fileName: (format) => `index.${format}.js`
+ },
+ rollupOptions: {
+ input: "src/index.ts",
+ output: {
+ dir: "dist"
+ }
}
- }
- },
- plugins: [svelte()],
+ },
+ plugins: [svelte()],
- mode: process.env.MODE || "development",
- test: {
- include: ["./src/test/*.test.*"],
- environment: TEST_MODE
- },
- ssr: {
- target: "node",
- format: "esm",
- noExternal: ["ws", "semiver", "bufferutil", "@gradio/upload"]
- }
+ mode: process.env.MODE || "development",
+ test: {
+ include: ["./src/test/*.test.*"],
+ environment: TEST_MODE
+ },
+ ssr: {
+ target: "node",
+ format: "esm",
+ noExternal: ["ws", "semiver", "bufferutil", "@gradio/upload"]
+ }
+ };
});
diff --git a/demo/cancel_events/run.ipynb b/demo/cancel_events/run.ipynb
index d2b61c048a4b0..c45edc3da683e 100644
--- a/demo/cancel_events/run.ipynb
+++ b/demo/cancel_events/run.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: cancel_events"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import time\n", "import gradio as gr\n", "import atexit\n", "import pathlib\n", "\n", "log_file = (pathlib.Path(__file__).parent / \"cancel_events_output_log.txt\").resolve()\n", "\n", "def fake_diffusion(steps):\n", " log_file.write_text(\"\")\n", " for i in range(steps):\n", " print(f\"Current step: {i}\")\n", " with log_file.open(\"a\") as f:\n", " f.write(f\"Current step: {i}\\n\")\n", " time.sleep(0.2)\n", " yield str(i)\n", "\n", "\n", "def long_prediction(*args, **kwargs):\n", " time.sleep(10)\n", " return 42\n", "\n", "\n", "with gr.Blocks() as demo:\n", " with gr.Row():\n", " with gr.Column():\n", " n = gr.Slider(1, 10, value=9, step=1, label=\"Number Steps\")\n", " run = gr.Button(value=\"Start Iterating\")\n", " output = gr.Textbox(label=\"Iterative Output\")\n", " stop = gr.Button(value=\"Stop Iterating\")\n", " with gr.Column():\n", " textbox = gr.Textbox(label=\"Prompt\")\n", " prediction = gr.Number(label=\"Expensive Calculation\")\n", " run_pred = gr.Button(value=\"Run Expensive Calculation\")\n", " with gr.Column():\n", " cancel_on_change = gr.Textbox(label=\"Cancel Iteration and Expensive Calculation on Change\")\n", " cancel_on_submit = gr.Textbox(label=\"Cancel Iteration and Expensive Calculation on Submit\")\n", " echo = gr.Textbox(label=\"Echo\")\n", " with gr.Row():\n", " with gr.Column():\n", " image = gr.Image(sources=[\"webcam\"], label=\"Cancel on clear\", interactive=True)\n", " with gr.Column():\n", " video = gr.Video(sources=[\"webcam\"], label=\"Cancel on start recording\", interactive=True)\n", "\n", " click_event = run.click(fake_diffusion, n, output)\n", " stop.click(fn=None, inputs=None, outputs=None, cancels=[click_event])\n", " pred_event = run_pred.click(fn=long_prediction, inputs=[textbox], outputs=prediction)\n", "\n", " cancel_on_change.change(None, None, None, cancels=[click_event, pred_event])\n", " cancel_on_submit.submit(lambda s: s, cancel_on_submit, echo, cancels=[click_event, pred_event])\n", " image.clear(None, None, None, cancels=[click_event, pred_event])\n", " video.start_recording(None, None, None, cancels=[click_event, pred_event])\n", "\n", " demo.queue(max_size=20)\n", " atexit.register(lambda: log_file.unlink())\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: cancel_events"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import time\n", "import gradio as gr\n", "import atexit\n", "import pathlib\n", "\n", "log_file = pathlib.Path(__file__).parent / \"cancel_events_output_log.txt\"\n", "\n", "\n", "def fake_diffusion(steps):\n", " log_file.write_text(\"\")\n", " for i in range(steps):\n", " print(f\"Current step: {i}\")\n", " with log_file.open(\"a\") as f:\n", " f.write(f\"Current step: {i}\\n\")\n", " time.sleep(0.2)\n", " yield str(i)\n", "\n", "\n", "def long_prediction(*args, **kwargs):\n", " time.sleep(10)\n", " return 42\n", "\n", "\n", "with gr.Blocks() as demo:\n", " with gr.Row():\n", " with gr.Column():\n", " n = gr.Slider(1, 10, value=9, step=1, label=\"Number Steps\")\n", " run = gr.Button(value=\"Start Iterating\")\n", " output = gr.Textbox(label=\"Iterative Output\")\n", " stop = gr.Button(value=\"Stop Iterating\")\n", " with gr.Column():\n", " textbox = gr.Textbox(label=\"Prompt\")\n", " prediction = gr.Number(label=\"Expensive Calculation\")\n", " run_pred = gr.Button(value=\"Run Expensive Calculation\")\n", " with gr.Column():\n", " cancel_on_change = gr.Textbox(\n", " label=\"Cancel Iteration and Expensive Calculation on Change\"\n", " )\n", " cancel_on_submit = gr.Textbox(\n", " label=\"Cancel Iteration and Expensive Calculation on Submit\"\n", " )\n", " echo = gr.Textbox(label=\"Echo\")\n", " with gr.Row():\n", " with gr.Column():\n", " image = gr.Image(\n", " sources=[\"webcam\"], label=\"Cancel on clear\", interactive=True\n", " )\n", " with gr.Column():\n", " video = gr.Video(\n", " sources=[\"webcam\"], label=\"Cancel on start recording\", interactive=True\n", " )\n", "\n", " click_event = run.click(fake_diffusion, n, output)\n", " stop.click(fn=None, inputs=None, outputs=None, cancels=[click_event])\n", " pred_event = run_pred.click(\n", " fn=long_prediction, inputs=[textbox], outputs=prediction\n", " )\n", "\n", " cancel_on_change.change(None, None, None, cancels=[click_event, pred_event])\n", " cancel_on_submit.submit(\n", " lambda s: s, cancel_on_submit, echo, cancels=[click_event, pred_event]\n", " )\n", " image.clear(None, None, None, cancels=[click_event, pred_event])\n", " video.start_recording(None, None, None, cancels=[click_event, pred_event])\n", "\n", " demo.queue(max_size=20)\n", " atexit.register(lambda: log_file.unlink())\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
\ No newline at end of file
diff --git a/demo/cancel_events/run.py b/demo/cancel_events/run.py
index 409858c5748a3..7c2d3b73c2a05 100644
--- a/demo/cancel_events/run.py
+++ b/demo/cancel_events/run.py
@@ -3,7 +3,8 @@
import atexit
import pathlib
-log_file = (pathlib.Path(__file__).parent / "cancel_events_output_log.txt").resolve()
+log_file = pathlib.Path(__file__).parent / "cancel_events_output_log.txt"
+
def fake_diffusion(steps):
log_file.write_text("")
@@ -32,21 +33,33 @@ def long_prediction(*args, **kwargs):
prediction = gr.Number(label="Expensive Calculation")
run_pred = gr.Button(value="Run Expensive Calculation")
with gr.Column():
- cancel_on_change = gr.Textbox(label="Cancel Iteration and Expensive Calculation on Change")
- cancel_on_submit = gr.Textbox(label="Cancel Iteration and Expensive Calculation on Submit")
+ cancel_on_change = gr.Textbox(
+ label="Cancel Iteration and Expensive Calculation on Change"
+ )
+ cancel_on_submit = gr.Textbox(
+ label="Cancel Iteration and Expensive Calculation on Submit"
+ )
echo = gr.Textbox(label="Echo")
with gr.Row():
with gr.Column():
- image = gr.Image(sources=["webcam"], label="Cancel on clear", interactive=True)
+ image = gr.Image(
+ sources=["webcam"], label="Cancel on clear", interactive=True
+ )
with gr.Column():
- video = gr.Video(sources=["webcam"], label="Cancel on start recording", interactive=True)
+ video = gr.Video(
+ sources=["webcam"], label="Cancel on start recording", interactive=True
+ )
click_event = run.click(fake_diffusion, n, output)
stop.click(fn=None, inputs=None, outputs=None, cancels=[click_event])
- pred_event = run_pred.click(fn=long_prediction, inputs=[textbox], outputs=prediction)
+ pred_event = run_pred.click(
+ fn=long_prediction, inputs=[textbox], outputs=prediction
+ )
cancel_on_change.change(None, None, None, cancels=[click_event, pred_event])
- cancel_on_submit.submit(lambda s: s, cancel_on_submit, echo, cancels=[click_event, pred_event])
+ cancel_on_submit.submit(
+ lambda s: s, cancel_on_submit, echo, cancels=[click_event, pred_event]
+ )
image.clear(None, None, None, cancels=[click_event, pred_event])
video.start_recording(None, None, None, cancels=[click_event, pred_event])
diff --git a/demo/dataframe_colorful/run.ipynb b/demo/dataframe_colorful/run.ipynb
index 83a30371f132d..e9181aab72819 100644
--- a/demo/dataframe_colorful/run.ipynb
+++ b/demo/dataframe_colorful/run.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: dataframe_colorful"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import pandas as pd \n", "import gradio as gr\n", "\n", "df = pd.DataFrame({\"A\" : [14, 4, 5, 4, 1], \n", "\t\t\t\t\"B\" : [5, 2, 54, 3, 2], \n", "\t\t\t\t\"C\" : [20, 20, 7, 3, 8], \n", "\t\t\t\t\"D\" : [14, 3, 6, 2, 6], \n", "\t\t\t\t\"E\" : [23, 45, 64, 32, 23]}) \n", "\n", "t = df.style.highlight_max(color = 'lightgreen', axis = 0)\n", "\n", "with gr.Blocks() as demo:\n", " gr.Dataframe(t)\n", " \n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: dataframe_colorful"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import pandas as pd\n", "import gradio as gr\n", "\n", "df = pd.DataFrame(\n", " {\n", " \"A\": [14, 4, 5, 4, 1],\n", " \"B\": [5, 2, 54, 3, 2],\n", " \"C\": [20, 20, 7, 3, 8],\n", " \"D\": [14, 3, 6, 2, 6],\n", " \"E\": [23, 45, 64, 32, 23],\n", " }\n", ")\n", "\n", "t = df.style.highlight_max(color=\"lightgreen\", axis=0)\n", "\n", "with gr.Blocks() as demo:\n", " gr.Dataframe(t)\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
\ No newline at end of file
diff --git a/demo/dataframe_colorful/run.py b/demo/dataframe_colorful/run.py
index eb97120438de5..38f146c356cd8 100644
--- a/demo/dataframe_colorful/run.py
+++ b/demo/dataframe_colorful/run.py
@@ -1,16 +1,20 @@
-import pandas as pd
+import pandas as pd
import gradio as gr
-df = pd.DataFrame({"A" : [14, 4, 5, 4, 1],
- "B" : [5, 2, 54, 3, 2],
- "C" : [20, 20, 7, 3, 8],
- "D" : [14, 3, 6, 2, 6],
- "E" : [23, 45, 64, 32, 23]})
+df = pd.DataFrame(
+ {
+ "A": [14, 4, 5, 4, 1],
+ "B": [5, 2, 54, 3, 2],
+ "C": [20, 20, 7, 3, 8],
+ "D": [14, 3, 6, 2, 6],
+ "E": [23, 45, 64, 32, 23],
+ }
+)
-t = df.style.highlight_max(color = 'lightgreen', axis = 0)
+t = df.style.highlight_max(color="lightgreen", axis=0)
with gr.Blocks() as demo:
gr.Dataframe(t)
-
+
if __name__ == "__main__":
- demo.launch()
\ No newline at end of file
+ demo.launch()
diff --git a/demo/state_change/run.ipynb b/demo/state_change/run.ipynb
index d3d0891213f2e..8b4d611579adb 100644
--- a/demo/state_change/run.ipynb
+++ b/demo/state_change/run.ipynb
@@ -1 +1 @@
-{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: state_change"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", "\n", " with gr.Row():\n", " state_a = gr.State(0)\n", " btn_a = gr.Button(\"Increment A\")\n", " value_a = gr.Number(label=\"A\")\n", " btn_a.click(lambda x: x+1, state_a, state_a)\n", " state_a.change(lambda x: x, state_a, value_a)\n", " with gr.Row():\n", " state_b = gr.State(0)\n", " btn_b = gr.Button(\"Increment B\")\n", " value_b = gr.Number(label=\"num\")\n", " btn_b.click(lambda x: x+1, state_b, state_b)\n", "\n", " @gr.on(inputs=state_b, outputs=value_b)\n", " def identity(x):\n", " return x\n", "\n", " @gr.render(inputs=[state_a, state_b])\n", " def render(a, b):\n", " for x in range(a):\n", " with gr.Row():\n", " for y in range(b):\n", " gr.Button(f\"Button {x}, {y}\")\n", "\n", " list_state = gr.State([])\n", " dict_state = gr.State(dict())\n", " nested_list_state = gr.State([])\n", " set_state = gr.State(set())\n", "\n", " def transform_list(x):\n", " return {n: n for n in x}, [x[:] for _ in range(len(x))], set(x)\n", " \n", " list_state.change(\n", " transform_list,\n", " inputs=list_state,\n", " outputs=[dict_state, nested_list_state, set_state],\n", " )\n", "\n", " all_textbox = gr.Textbox(label=\"Output\")\n", " click_count = gr.Number(label=\"Clicks\")\n", " change_count = gr.Number(label=\"Changes\")\n", " gr.on(\n", " inputs=[change_count, dict_state, nested_list_state, set_state],\n", " triggers=[dict_state.change, nested_list_state.change, set_state.change],\n", " fn=lambda x, *args: (x+1, \"\\n\".join(str(arg) for arg in args)),\n", " outputs=[change_count, all_textbox],\n", " )\n", "\n", " count_to_3_btn = gr.Button(\"Count to 3\")\n", " count_to_3_btn.click(lambda: [1, 2, 3], outputs=list_state)\n", " zero_all_btn = gr.Button(\"Zero All\")\n", " zero_all_btn.click(\n", " lambda x: [0] * len(x), inputs=list_state, outputs=list_state\n", " )\n", "\n", " gr.on([count_to_3_btn.click, zero_all_btn.click], lambda x: x + 1, click_count, click_count)\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
\ No newline at end of file
+{"cells": [{"cell_type": "markdown", "id": "302934307671667531413257853548643485645", "metadata": {}, "source": ["# Gradio Demo: state_change"]}, {"cell_type": "code", "execution_count": null, "id": "272996653310673477252411125948039410165", "metadata": {}, "outputs": [], "source": ["!pip install -q gradio "]}, {"cell_type": "code", "execution_count": null, "id": "288918539441861185822528903084949547379", "metadata": {}, "outputs": [], "source": ["import gradio as gr\n", "\n", "with gr.Blocks() as demo:\n", "\n", " with gr.Row():\n", " state_a = gr.State(0)\n", " btn_a = gr.Button(\"Increment A\")\n", " value_a = gr.Number(label=\"Number A\")\n", " btn_a.click(lambda x: x + 1, state_a, state_a)\n", " state_a.change(lambda x: x, state_a, value_a)\n", " with gr.Row():\n", " state_b = gr.State(0)\n", " btn_b = gr.Button(\"Increment B\")\n", " value_b = gr.Number(label=\"Number B\")\n", " btn_b.click(lambda x: x + 1, state_b, state_b)\n", "\n", " @gr.on(inputs=state_b, outputs=value_b)\n", " def identity(x):\n", " return x\n", "\n", " @gr.render(inputs=[state_a, state_b])\n", " def render(a, b):\n", " for x in range(a):\n", " with gr.Row():\n", " for y in range(b):\n", " gr.Button(f\"Button {x}, {y}\")\n", "\n", " list_state = gr.State([])\n", " dict_state = gr.State(dict())\n", " nested_list_state = gr.State([])\n", " set_state = gr.State(set())\n", "\n", " def transform_list(x):\n", " return {n: n for n in x}, [x[:] for _ in range(len(x))], set(x)\n", "\n", " list_state.change(\n", " transform_list,\n", " inputs=list_state,\n", " outputs=[dict_state, nested_list_state, set_state],\n", " )\n", "\n", " all_textbox = gr.Textbox(label=\"Output\")\n", " click_count = gr.Number(label=\"Clicks\")\n", " change_count = gr.Number(label=\"Changes\")\n", " gr.on(\n", " inputs=[change_count, dict_state, nested_list_state, set_state],\n", " triggers=[dict_state.change, nested_list_state.change, set_state.change],\n", " fn=lambda x, *args: (x + 1, \"\\n\".join(str(arg) for arg in args)),\n", " outputs=[change_count, all_textbox],\n", " )\n", "\n", " count_to_3_btn = gr.Button(\"Count to 3\")\n", " count_to_3_btn.click(lambda: [1, 2, 3], outputs=list_state)\n", " zero_all_btn = gr.Button(\"Zero All\")\n", " zero_all_btn.click(lambda x: [0] * len(x), inputs=list_state, outputs=list_state)\n", "\n", " gr.on(\n", " [count_to_3_btn.click, zero_all_btn.click],\n", " lambda x: x + 1,\n", " click_count,\n", " click_count,\n", " )\n", "\n", "if __name__ == \"__main__\":\n", " demo.launch()\n"]}], "metadata": {}, "nbformat": 4, "nbformat_minor": 5}
\ No newline at end of file
diff --git a/demo/state_change/run.py b/demo/state_change/run.py
index c23f00ff47cd8..2846a38ce51c6 100644
--- a/demo/state_change/run.py
+++ b/demo/state_change/run.py
@@ -5,14 +5,14 @@
with gr.Row():
state_a = gr.State(0)
btn_a = gr.Button("Increment A")
- value_a = gr.Number(label="A")
- btn_a.click(lambda x: x+1, state_a, state_a)
+ value_a = gr.Number(label="Number A")
+ btn_a.click(lambda x: x + 1, state_a, state_a)
state_a.change(lambda x: x, state_a, value_a)
with gr.Row():
state_b = gr.State(0)
btn_b = gr.Button("Increment B")
- value_b = gr.Number(label="num")
- btn_b.click(lambda x: x+1, state_b, state_b)
+ value_b = gr.Number(label="Number B")
+ btn_b.click(lambda x: x + 1, state_b, state_b)
@gr.on(inputs=state_b, outputs=value_b)
def identity(x):
@@ -32,7 +32,7 @@ def render(a, b):
def transform_list(x):
return {n: n for n in x}, [x[:] for _ in range(len(x))], set(x)
-
+
list_state.change(
transform_list,
inputs=list_state,
@@ -45,18 +45,21 @@ def transform_list(x):
gr.on(
inputs=[change_count, dict_state, nested_list_state, set_state],
triggers=[dict_state.change, nested_list_state.change, set_state.change],
- fn=lambda x, *args: (x+1, "\n".join(str(arg) for arg in args)),
+ fn=lambda x, *args: (x + 1, "\n".join(str(arg) for arg in args)),
outputs=[change_count, all_textbox],
)
count_to_3_btn = gr.Button("Count to 3")
count_to_3_btn.click(lambda: [1, 2, 3], outputs=list_state)
zero_all_btn = gr.Button("Zero All")
- zero_all_btn.click(
- lambda x: [0] * len(x), inputs=list_state, outputs=list_state
- )
+ zero_all_btn.click(lambda x: [0] * len(x), inputs=list_state, outputs=list_state)
- gr.on([count_to_3_btn.click, zero_all_btn.click], lambda x: x + 1, click_count, click_count)
+ gr.on(
+ [count_to_3_btn.click, zero_all_btn.click],
+ lambda x: x + 1,
+ click_count,
+ click_count,
+ )
if __name__ == "__main__":
- demo.launch()
\ No newline at end of file
+ demo.launch()
diff --git a/js/_spaces-test/src/routes/client-browser/+page.svelte b/js/_spaces-test/src/routes/client-browser/+page.svelte
index 762aae5d4f76e..d9c9010c46ab3 100644
--- a/js/_spaces-test/src/routes/client-browser/+page.svelte
+++ b/js/_spaces-test/src/routes/client-browser/+page.svelte
@@ -83,14 +83,13 @@
async function submit() {
response_data = { data: [], fn_index: 0, endpoint: "" };
- job = app
- .submit(active_endpoint, request_data)
- .on("data", (data) => {
- response_data = data;
- })
- .on("status", (_status) => {
- status = _status.stage;
- });
+ job = app.submit(active_endpoint, request_data);
+ // .on("data", (data) => {
+ // response_data = data;
+ // })
+ // .on("status", (_status) => {
+ // status = _status.stage;
+ // });
}
function cancel() {
@@ -194,12 +193,7 @@
{#if app_info.type.generator || app_info.type.continuous}
-
+
{/if}
diff --git a/js/app/src/Blocks.svelte b/js/app/src/Blocks.svelte
index 83bc2ae686e6a..740c629b308f9 100644
--- a/js/app/src/Blocks.svelte
+++ b/js/app/src/Blocks.svelte
@@ -18,6 +18,11 @@
import logo from "./images/logo.svg";
import api_logo from "./api_docs/img/api-logo.svg";
import { create_components, AsyncFunction } from "./init";
+ import type {
+ LogMessage,
+ RenderMessage,
+ StatusMessage
+ } from "@gradio/client";
setupi18n();
@@ -284,132 +289,145 @@
return;
}
- submission
- .on("data", ({ data, fn_index }) => {
- if (dep.pending_request && dep.final_event) {
- dep.pending_request = false;
- make_prediction(dep.final_event);
- }
+ submit_map.set(dep_index, submission);
+
+ for await (const message of submission) {
+ if (message.type === "data") {
+ handle_data(message);
+ } else if (message.type === "render") {
+ handle_render(message);
+ } else if (message.type === "status") {
+ handle_status_update(message);
+ } else if (message.type === "log") {
+ handle_log(message);
+ }
+ }
+
+ function handle_data(message: Payload): void {
+ const { data, fn_index } = message;
+ if (dep.pending_request && dep.final_event) {
dep.pending_request = false;
- handle_update(data, fn_index);
- set_status($loading_status);
- })
- .on("render", ({ data }) => {
- let _components: ComponentMeta[] = data.components;
- let render_layout: LayoutNode = data.layout;
- let _dependencies: Dependency[] = data.dependencies;
- let render_id = data.render_id;
-
- let deps_to_remove: number[] = [];
- dependencies.forEach((dep, i) => {
- if (dep.rendered_in === render_id) {
- deps_to_remove.push(i);
- }
- });
- deps_to_remove.reverse().forEach((i) => {
- dependencies.splice(i, 1);
- });
- _dependencies.forEach((dep) => {
- dependencies.push(dep);
- });
+ make_prediction(dep.final_event);
+ }
+ dep.pending_request = false;
+ handle_update(data, fn_index);
+ set_status($loading_status);
+ }
+
+ function handle_render(message: RenderMessage): void {
+ const { data } = message;
+ let _components: ComponentMeta[] = data.components;
+ let render_layout: LayoutNode = data.layout;
+ let _dependencies: Dependency[] = data.dependencies;
+ let render_id = data.render_id;
+
+ let deps_to_remove: number[] = [];
+ dependencies.forEach((dep, i) => {
+ if (dep.rendered_in === render_id) {
+ deps_to_remove.push(i);
+ }
+ });
+ deps_to_remove.reverse().forEach((i) => {
+ dependencies.splice(i, 1);
+ });
+ _dependencies.forEach((dep) => {
+ dependencies.push(dep);
+ });
+
+ rerender_layout({
+ components: _components,
+ layout: render_layout,
+ root: root,
+ dependencies: dependencies,
+ render_id: render_id
+ });
+ }
+
+ function handle_log(msg: LogMessage): void {
+ const { log, fn_index, level } = msg;
+ messages = [new_message(log, fn_index, level), ...messages];
+ }
+
+ function handle_status_update(message: StatusMessage): void {
+ const { fn_index, ...status } = message;
+ //@ts-ignore
+ loading_status.update({
+ ...status,
+ status: status.stage,
+ progress: status.progress_data,
+ fn_index
+ });
+ set_status($loading_status);
+ if (
+ !showed_duplicate_message &&
+ space_id !== null &&
+ status.position !== undefined &&
+ status.position >= 2 &&
+ status.eta !== undefined &&
+ status.eta > SHOW_DUPLICATE_MESSAGE_ON_ETA
+ ) {
+ showed_duplicate_message = true;
+ messages = [
+ new_message(DUPLICATE_MESSAGE, fn_index, "warning"),
+ ...messages
+ ];
+ }
+ if (
+ !showed_mobile_warning &&
+ is_mobile_device &&
+ status.eta !== undefined &&
+ status.eta > SHOW_MOBILE_QUEUE_WARNING_ON_ETA
+ ) {
+ showed_mobile_warning = true;
+ messages = [
+ new_message(MOBILE_QUEUE_WARNING, fn_index, "warning"),
+ ...messages
+ ];
+ }
- rerender_layout({
- components: _components,
- layout: render_layout,
- root: root,
- dependencies: dependencies,
- render_id: render_id
+ if (status.stage === "complete") {
+ status.changed_state_ids?.forEach((id) => {
+ dependencies
+ .filter((dep) => dep.targets.some(([_id, _]) => _id === id))
+ .forEach((dep) => {
+ wait_then_trigger_api_call(dep.id, payload.trigger_id);
+ });
});
- })
- .on("status", ({ fn_index, ...status }) => {
- //@ts-ignore
- loading_status.update({
- ...status,
- status: status.stage,
- progress: status.progress_data,
- fn_index
+ dependencies.forEach(async (dep) => {
+ if (dep.trigger_after === fn_index) {
+ wait_then_trigger_api_call(dep.id, payload.trigger_id);
+ }
});
- set_status($loading_status);
- if (
- !showed_duplicate_message &&
- space_id !== null &&
- status.position !== undefined &&
- status.position >= 2 &&
- status.eta !== undefined &&
- status.eta > SHOW_DUPLICATE_MESSAGE_ON_ETA
- ) {
- showed_duplicate_message = true;
- messages = [
- new_message(DUPLICATE_MESSAGE, fn_index, "warning"),
- ...messages
- ];
- }
- if (
- !showed_mobile_warning &&
- is_mobile_device &&
- status.eta !== undefined &&
- status.eta > SHOW_MOBILE_QUEUE_WARNING_ON_ETA
- ) {
- showed_mobile_warning = true;
+
+ // submission.destroy();
+ }
+ if (status.broken && is_mobile_device && user_left_page) {
+ window.setTimeout(() => {
messages = [
- new_message(MOBILE_QUEUE_WARNING, fn_index, "warning"),
+ new_message(MOBILE_RECONNECT_MESSAGE, fn_index, "error"),
...messages
];
+ }, 0);
+ wait_then_trigger_api_call(dep.id, payload.trigger_id, event_data);
+ user_left_page = false;
+ } else if (status.stage === "error") {
+ if (status.message) {
+ const _message = status.message.replace(
+ MESSAGE_QUOTE_RE,
+ (_, b) => b
+ );
+ messages = [new_message(_message, fn_index, "error"), ...messages];
}
-
- if (status.stage === "complete") {
- status.changed_state_ids?.forEach((id) => {
- dependencies
- .filter((dep) => dep.targets.some(([_id, _]) => _id === id))
- .forEach((dep) => {
- wait_then_trigger_api_call(dep.id, payload.trigger_id);
- });
- });
- dependencies.forEach(async (dep) => {
- if (dep.trigger_after === fn_index) {
- wait_then_trigger_api_call(dep.id, payload.trigger_id);
- }
- });
-
- submission.destroy();
- }
- if (status.broken && is_mobile_device && user_left_page) {
- window.setTimeout(() => {
- messages = [
- new_message(MOBILE_RECONNECT_MESSAGE, fn_index, "error"),
- ...messages
- ];
- }, 0);
- wait_then_trigger_api_call(dep.id, payload.trigger_id, event_data);
- user_left_page = false;
- } else if (status.stage === "error") {
- if (status.message) {
- const _message = status.message.replace(
- MESSAGE_QUOTE_RE,
- (_, b) => b
- );
- messages = [
- new_message(_message, fn_index, "error"),
- ...messages
- ];
+ dependencies.map(async (dep) => {
+ if (
+ dep.trigger_after === fn_index &&
+ !dep.trigger_only_on_success
+ ) {
+ wait_then_trigger_api_call(dep.id, payload.trigger_id);
}
- dependencies.map(async (dep) => {
- if (
- dep.trigger_after === fn_index &&
- !dep.trigger_only_on_success
- ) {
- wait_then_trigger_api_call(dep.id, payload.trigger_id);
- }
- });
-
- submission.destroy();
- }
- })
- .on("log", ({ log, fn_index, level }) => {
- messages = [new_message(log, fn_index, level), ...messages];
- });
-
- submit_map.set(dep_index, submission);
+ });
+ }
+ }
}
}
diff --git a/js/app/src/Index.svelte b/js/app/src/Index.svelte
index eb806a18010f4..3d9dee5360eb8 100644
--- a/js/app/src/Index.svelte
+++ b/js/app/src/Index.svelte
@@ -275,7 +275,8 @@
app = await Client.connect(api_url, {
status_callback: handle_status,
- with_null_state: true
+ with_null_state: true,
+ events: ["data", "log", "status", "render"]
});
if (!app.config) {
@@ -312,7 +313,8 @@
stream.addEventListener("reload", async (event) => {
app.close();
app = await Client.connect(api_url, {
- status_callback: handle_status
+ status_callback: handle_status,
+ events: ["data", "log", "status", "render"]
});
if (!app.config) {
diff --git a/js/app/src/lite/index.ts b/js/app/src/lite/index.ts
index de972f041d805..02221447545d3 100644
--- a/js/app/src/lite/index.ts
+++ b/js/app/src/lite/index.ts
@@ -109,7 +109,7 @@ export function create(options: Options): GradioAppController {
return wasm_proxied_fetch(worker_proxy, input, init);
}
- async stream(url: URL): Promise {
+ stream(url: URL): EventSource {
return wasm_proxied_stream_factory(worker_proxy, url);
}
}
diff --git a/js/app/test/state_change.spec.ts b/js/app/test/state_change.spec.ts
index 41c45fe7f3591..d10e184799f2b 100644
--- a/js/app/test/state_change.spec.ts
+++ b/js/app/test/state_change.spec.ts
@@ -5,14 +5,22 @@ test("test 2d state-based render", async ({ page }) => {
await expect(
page.locator("button").filter({ hasText: "Button" })
).toHaveCount(0);
+
+ await expect(page.getByLabel("Number A")).toHaveValue("1");
await page.getByRole("button", { name: "Increment B" }).click();
await page.getByRole("button", { name: "Increment A" }).click();
+ await expect(page.getByLabel("Number B")).toHaveValue("1");
await expect(
page.locator("button").filter({ hasText: "Button" })
).toHaveCount(2);
await page.getByRole("button", { name: "Increment A" }).click();
+ await expect(page.getByLabel("Number A")).toHaveValue("2");
+
await page.getByRole("button", { name: "Increment B" }).click();
+ await expect(page.getByLabel("Number B")).toHaveValue("2");
+
await page.getByRole("button", { name: "Increment A" }).click();
+ await expect(page.getByLabel("Number A").first()).toHaveValue("4");
await expect(
page.locator("button").filter({ hasText: "Button" })
).toHaveCount(8);
diff --git a/js/file/shared/FilePreview.svelte b/js/file/shared/FilePreview.svelte
index fbc9c0bcb41de..2b024ff23c0b6 100644
--- a/js/file/shared/FilePreview.svelte
+++ b/js/file/shared/FilePreview.svelte
@@ -39,7 +39,9 @@
const tr = event.currentTarget;
const should_select =
event.target === tr || // Only select if the click is on the row itself
- event.composedPath().includes(tr.firstElementChild); // Or if the click is on the name column
+ (tr &&
+ tr.firstElementChild &&
+ event.composedPath().includes(tr.firstElementChild)); // Or if the click is on the name column
if (should_select) {
dispatch("select", { value: normalized_files[index].orig_name, index });
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index c061d6732552c..4d318e564347a 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -231,12 +231,18 @@ importers:
eventsource:
specifier: ^2.0.2
version: 2.0.2
+ fetch-event-stream:
+ specifier: ^0.1.5
+ version: 0.1.5
msw:
specifier: ^2.2.1
version: 2.2.8(typescript@5.4.3)
semiver:
specifier: ^1.1.0
version: 1.1.0
+ textlinestream:
+ specifier: ^1.1.1
+ version: 1.1.1
typescript:
specifier: ^5.0.0
version: 5.4.3
@@ -5851,6 +5857,9 @@ packages:
fastq@1.15.0:
resolution: {integrity: sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==}
+ fetch-event-stream@0.1.5:
+ resolution: {integrity: sha512-V1PWovkspxQfssq/NnxoEyQo1DV+MRK/laPuPblIZmSjMN8P5u46OhlFQznSr9p/t0Sp8Uc6SbM3yCMfr0KU8g==}
+
fetch-retry@5.0.6:
resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==}
@@ -8460,6 +8469,9 @@ packages:
text-table@0.2.0:
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
+ textlinestream@1.1.1:
+ resolution: {integrity: sha512-iBHbi7BQxrFmwZUQJsT0SjNzlLLsXhvW/kg7EyOMVMBIrlnj/qYofwo1LVLZi+3GbUEo96Iu2eqToI2+lZoAEQ==}
+
thenify-all@1.6.0:
resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
engines: {node: '>=0.8'}
@@ -14170,6 +14182,8 @@ snapshots:
dependencies:
reusify: 1.0.4
+ fetch-event-stream@0.1.5: {}
+
fetch-retry@5.0.6: {}
figures@3.2.0:
@@ -16998,6 +17012,8 @@ snapshots:
text-table@0.2.0: {}
+ textlinestream@1.1.1: {}
+
thenify-all@1.6.0:
dependencies:
thenify: 3.3.1