Skip to content

Commit f2a47fe

Browse files
pngwngradio-pr-bot
andauthored
fix custom components (#12397)
* fix * clean * add changeset * add changeset --------- Co-authored-by: gradio-pr-bot <gradio-pr-bot@users.noreply.github.com>
1 parent ab72f4c commit f2a47fe

File tree

10 files changed

+325
-89
lines changed

10 files changed

+325
-89
lines changed

.changeset/rotten-laws-clap.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@gradio/preview": minor
3+
"@self/app": minor
4+
"@self/build": minor
5+
"gradio": minor
6+
---
7+
8+
feat:fix custom components

gradio/routes.py

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,13 +1497,10 @@ async def sse_stream(request: fastapi.Request):
14971497
# It's possible that the event_id has already been removed
14981498
# for example, the user sent two duplicate `/cancel` requests.
14991499
# The first one would have removed the event_id from pending_event_ids_session
1500-
if (
1501-
message.event_id
1502-
in (
1503-
blocks._queue.pending_event_ids_session[
1504-
session_hash
1505-
]
1506-
)
1500+
if message.event_id in (
1501+
blocks._queue.pending_event_ids_session[
1502+
session_hash
1503+
]
15071504
):
15081505
blocks._queue.pending_event_ids_session[
15091506
session_hash
@@ -1806,8 +1803,8 @@ async def pwa_icon(size: int | None = None):
18061803

18071804
@app.get("/manifest.json")
18081805
def manifest_json():
1809-
if not blocks.pwa:
1810-
raise HTTPException(status_code=404, detail="PWA not enabled.")
1806+
# if not blocks.pwa:
1807+
# raise HTTPException(status_code=404, detail="PWA not enabled.")
18111808

18121809
favicon_path = blocks.favicon_path
18131810
if isinstance(favicon_path, Path):
@@ -2422,8 +2419,9 @@ def mount_gradio_app(
24222419
path: str,
24232420
server_name: str = "0.0.0.0",
24242421
server_port: int = 7860,
2425-
footer_links: list[Literal["api", "gradio", "settings"] | dict[str, str]]
2426-
| None = None,
2422+
footer_links: (
2423+
list[Literal["api", "gradio", "settings"] | dict[str, str]] | None
2424+
) = None,
24272425
app_kwargs: dict[str, Any] | None = None,
24282426
*,
24292427
auth: Callable | tuple[str, str] | list[tuple[str, str]] | None = None,

js/app/src/routes/+layout.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import "@gradio/theme/pollen.css";
55
import "@gradio/theme/typography.css";
66
import "@gradio/theme/gradio-style.scss";
7-
import "./svelte_init";
7+
import "virtual:load-svelte";
88
</script>
99

1010
<slot></slot>

js/app/src/routes/svelte_init.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@ if (is_browser) {
55
SvelteComponent: svelte.SvelteComponent
66
};
77
for (const key in svelte) {
8-
if (key === "SvelteComponent") continue;
9-
if (key === "SvelteComponentDev") {
10-
//@ts-ignore
11-
o[key] = o["SvelteComponent"];
12-
} else {
13-
//@ts-ignore
14-
o[key] = svelte[key];
15-
}
8+
// if (key === "SvelteComponent") continue;
9+
// if (key === "SvelteComponentDev") {
10+
// //@ts-ignore
11+
// o[key] = o["SvelteComponent"];
12+
// } else {
13+
// @ts-ignore
14+
o[key] = svelte[key];
15+
// }
1616
}
1717
window.__gradio__svelte__internal = o;
1818
window.__gradio__svelte__internal["globals"] = {};

js/app/vite.config.ts

Lines changed: 126 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { sveltekit } from "@sveltejs/kit/vite";
2-
import { defineConfig } from "vite";
2+
import { defineConfig, type Plugin } from "vite";
33

44
// @ts-ignore
55
import custom_media from "postcss-custom-media";
@@ -28,6 +28,15 @@ const version = version_raw.replace(/\./g, "-");
2828
const GRADIO_VERSION = version_raw || "asd_stub_asd";
2929
const CDN_BASE = "https://gradio.s3-us-west-2.amazonaws.com";
3030

31+
import { createRequire } from "module";
32+
33+
const require = createRequire(import.meta.url);
34+
const svelte = require("svelte/package.json");
35+
const svelte_exports = Object.keys(svelte.exports)
36+
.filter((p) => p.endsWith(".json"))
37+
.map((entry) => entry.replace(/^\./, "svelte").split("/").join("_") + ".js");
38+
console.log("Svelte exports:", svelte_exports);
39+
3140
export default defineConfig(({ mode, isSsrBuild }) => {
3241
const production = mode === "production";
3342
const development = mode === "development";
@@ -49,16 +58,12 @@ export default defineConfig(({ mode, isSsrBuild }) => {
4958
resolve: {
5059
conditions: ["gradio"]
5160
},
52-
noExternal: ["@gradio/*", "@huggingface/space-header"]
61+
noExternal: ["@gradio/*", "@huggingface/space-header"],
62+
external: mode === "development" ? [] : ["svelte", "svelte/*"]
5363
},
5464
build: {
5565
rollupOptions: {
56-
// external: [
57-
// "/svelte/svelte.js",
58-
// "/svelte/svelte-submodules.js",
59-
// "./svelte/svelte-submodules.js",
60-
// "./svelte/svelte.js"
61-
// ]
66+
external: svelte_exports
6267
},
6368
minify: true,
6469
sourcemap: false
@@ -100,34 +105,122 @@ export default defineConfig(({ mode, isSsrBuild }) => {
100105
// noExternal: ["@gradio/*", "@huggingface/space-header"]
101106
// // external: mode === "development" ? [] : ["svelte", "svelte/*"]
102107
// },
103-
// optimizeDeps: {
104-
// exclude: ["@gradio/*"]
105-
// },
108+
optimizeDeps: {
109+
exclude: ["@gradio/*"]
110+
},
106111
plugins: [
112+
inject_svelte_init_code({ mode }),
107113
sveltekit(),
108114

109-
inject_component_loader({ mode })
110-
// {
111-
// name: "resolve_svelte",
112-
// enforce: "pre",
113-
// resolveId(id, importer, options) {
114-
// if (development) {
115-
// return null;
116-
// }
117-
118-
// // if (!options?.ssr) {
119-
// // if (id === "svelte" || id === "svelte/internal") {
120-
// // return { id: "../../../svelte/svelte.js", external: true };
121-
// // }
122-
// // if (id.startsWith("svelte/")) {
123-
// // return {
124-
// // id: "../../../svelte/svelte-submodules.js",
125-
// // external: true
126-
// // };
127-
// // }
128-
// // }
129-
// }
130-
// }
115+
inject_component_loader({ mode }),
116+
resolve_svelte(mode === "production"),
117+
handle_svelte_import({ development: mode === "development" })
131118
]
132119
};
133120
});
121+
122+
function handle_svelte_import({
123+
development
124+
}: {
125+
development: boolean;
126+
}): Plugin {
127+
return {
128+
name: "handle_svelte_import",
129+
enforce: "pre",
130+
resolveId(id, importer, options) {
131+
if (development) {
132+
return null;
133+
}
134+
135+
if (!options?.ssr) {
136+
if (id === "svelte") {
137+
return {
138+
id: "../../../svelte/svelte_svelte.js",
139+
external: true
140+
};
141+
}
142+
if (id.startsWith("svelte/")) {
143+
return {
144+
id: `../../../svelte/${id.split("/").join("_")}.js`,
145+
external: true
146+
};
147+
}
148+
return null;
149+
}
150+
}
151+
};
152+
}
153+
154+
export const _svelte_exports = Object.keys(svelte.exports)
155+
156+
.filter((entry) => {
157+
const _entry = Object.keys(svelte.exports[entry]).filter(
158+
(e) => e !== "types"
159+
);
160+
return (
161+
_entry.length !== 0 &&
162+
!entry.endsWith(".json") &&
163+
entry !== "./internal" &&
164+
entry !== "./compiler" &&
165+
entry !== "./internal/disclose-version"
166+
);
167+
})
168+
.map((entry) => "svelte" + entry.replace(/^\./, ""));
169+
export const svelte_exports_transformed = Object.keys(svelte.exports).map(
170+
(entry) => entry.replace(/^\./, "svelte").split("/").join("_") + ".js"
171+
);
172+
173+
export function inject_svelte_init_code({ mode }: { mode: string }): Plugin {
174+
const v_id = "virtual:load-svelte";
175+
const resolved_v_id = "\0" + v_id;
176+
177+
return {
178+
name: "inject-component-loader",
179+
enforce: "pre",
180+
resolveId(id: string) {
181+
if (id === v_id) return resolved_v_id;
182+
},
183+
load(id: string) {
184+
if (id === resolved_v_id) {
185+
const s = make_init_code();
186+
console.log("Svelte init code:", s);
187+
return s;
188+
}
189+
}
190+
};
191+
}
192+
193+
function make_init_code(): string {
194+
const import_strings = _svelte_exports
195+
.map(
196+
(entry: string) =>
197+
`import * as ${entry
198+
.replace(/\.js$/, "")
199+
.replace(/-/g, "_")
200+
.replace(/\//g, "_")} from "${entry}";`
201+
)
202+
.join("\n");
203+
204+
const import_mappings = _svelte_exports
205+
.map((entry: string) => {
206+
const var_name = entry.replace(/\//g, "_");
207+
return `o.${var_name} = {};
208+
for (const key in ${var_name}) {
209+
//@ts-ignore
210+
o.${var_name}[key] = ${var_name}[key];
211+
}`;
212+
})
213+
.join("\n");
214+
return `${import_strings}
215+
216+
const is_browser = typeof window !== "undefined";
217+
if (is_browser) {
218+
const o = {};
219+
${import_mappings}
220+
221+
window.__gradio__svelte__ = o;
222+
window.__gradio__svelte__["globals"] = {};
223+
window.globals = window;
224+
}
225+
`;
226+
}

js/build/src/index.ts

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,72 @@ export function inject_component_loader({ mode }: { mode: string }): Plugin {
334334
};
335335
}
336336

337+
export function inject_svelte_init_code({ mode }: { mode: string }): Plugin {
338+
const v_id = "virtual:svelte-init";
339+
const resolved_v_id = "\0" + v_id;
340+
341+
342+
return {
343+
name: "inject-component-loader",
344+
enforce: "pre",
345+
resolveId(id: string) {
346+
if (id === v_id) return resolved_v_id;
347+
},
348+
load(id: string) {
349+
350+
if (id === resolved_v_id) {
351+
return load_virtual_component_loader(mode);
352+
}
353+
}
354+
}
355+
}
356+
357+
import { createRequire } from "module";
358+
const require = createRequire(import.meta.url);
359+
const svelte = require("svelte/package.json");
360+
export const svelte_exports = Object.keys(svelte.exports).map(
361+
(entry) => "svelte" + entry.replace(/^\./, "svelte")
362+
);
363+
export const svelte_exports_transformed = Object.keys(svelte.exports).map(
364+
(entry) => entry.replace(/^\./, "svelte").split("/").join("_") + ".js"
365+
);
366+
367+
368+
369+
function make_init_code(): string {
370+
const import_strings = svelte_exports
371+
.map(
372+
(entry: string) =>
373+
`import * as ${entry
374+
.replace(/\.js$/, "")
375+
.replace(/-/g, "_")
376+
.replace(/\//g, "_")} from "svelte/${entry}";`
377+
)
378+
.join("\n");
379+
return `${import_strings}
380+
381+
const is_browser = typeof window !== "undefined";
382+
if (is_browser) {
383+
const o = {
384+
SvelteComponent: svelte.SvelteComponent
385+
};
386+
for (const key in svelte) {
387+
// if (key === "SvelteComponent") continue;
388+
// if (key === "SvelteComponentDev") {
389+
// //@ts-ignore
390+
// o[key] = o["SvelteComponent"];
391+
// } else {
392+
// @ts-ignore
393+
o[key] = svelte[key];
394+
// }
395+
}
396+
window.__gradio__svelte__internal = o;
397+
window.__gradio__svelte__internal["globals"] = {};
398+
window.globals = window;
399+
}
400+
`;
401+
}
402+
337403
export function resolve_svelte(enable: boolean): Plugin {
338404
return {
339405
enforce: "pre",

js/preview/package.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@
1717
"@rollup/plugin-json": "^6.1.0",
1818
"@rollup/plugin-node-resolve": "^16.0.2",
1919
"@rollup/plugin-typescript": "^12.1.4",
20-
"rollup": "^4.52.4"
20+
"rollup": "^4.52.4",
21+
"svelte": "^5.43.4"
2122
},
2223
"dependencies": {
2324
"@originjs/vite-plugin-commonjs": "^1.0.3",
@@ -38,9 +39,6 @@
3839
"which": "5.0.0",
3940
"yootils": "^0.3.1"
4041
},
41-
"optionalDependencies": {
42-
"svelte": "^5.43.4"
43-
},
4442
"exports": {
4543
".": {
4644
"default": "./dist/index.js",

0 commit comments

Comments
 (0)