@gradio/core 0.19.3 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # @gradio/core
2
2
 
3
+ ## 0.21.0
4
+
5
+ ### Features
6
+
7
+ - [#11427](https://github.com/gradio-app/gradio/pull/11427) [`6b2bcd0`](https://github.com/gradio-app/gradio/commit/6b2bcd097ae5ef999a7fb273ecf7c7e4c0eab305) - Improve load times of the Gradio front-end. Thanks @pngwn!
8
+ - [#11511](https://github.com/gradio-app/gradio/pull/11511) [`1a99336`](https://github.com/gradio-app/gradio/commit/1a99336043076e7b0a4c4b07f97082f0361882f4) - Fix SSR. Thanks @pngwn!
9
+
10
+ ### Dependency updates
11
+
12
+ - @gradio/atoms@0.16.3
13
+ - @gradio/statustracker@0.10.14
14
+ - @gradio/column@0.2.1
15
+ - @gradio/tabs@0.4.5
16
+ - @gradio/upload@0.16.10
17
+ - @gradio/video@0.14.20
18
+ - @gradio/tabitem@0.5.0
19
+ - @gradio/code@0.14.10
20
+ - @gradio/paramviewer@0.7.12
21
+ - @gradio/client@1.15.5
22
+ - @gradio/image@0.22.12
23
+ - @gradio/button@0.5.6
24
+ - @gradio/checkbox@0.4.25
25
+ - @gradio/gallery@0.15.26
26
+ - @gradio/plot@0.9.19
27
+ - @gradio/textbox@0.10.16
28
+ - @gradio/file@0.12.23
29
+
30
+ ## 0.20.0
31
+
32
+ ### Features
33
+
34
+ - [#11392](https://github.com/gradio-app/gradio/pull/11392) [`dc760a6`](https://github.com/gradio-app/gradio/commit/dc760a6dd7d3375f99913059803a826cdf0f7102) - Add column-specific filtering to `gr.Dataframe`. Thanks @tiago-gsantos!
35
+
36
+ ### Fixes
37
+
38
+ - [#11421](https://github.com/gradio-app/gradio/pull/11421) [`c2acf6e`](https://github.com/gradio-app/gradio/commit/c2acf6e33025fe7bbfe0660c182006651cc95090) - Preserve value in reload mode. Thanks @aliabid94!
39
+
40
+ ### Dependency updates
41
+
42
+ - @gradio/tabitem@0.4.6
43
+ - @gradio/code@0.14.9
44
+ - @gradio/upload@0.16.9
45
+ - @gradio/video@0.14.19
46
+ - @gradio/client@1.15.4
47
+ - @gradio/button@0.5.5
48
+ - @gradio/column@0.2.1
49
+ - @gradio/image@0.22.11
50
+ - @gradio/gallery@0.15.25
51
+ - @gradio/file@0.12.22
52
+
3
53
  ## 0.19.3
4
54
 
5
55
  ### Fixes
@@ -3,7 +3,6 @@ import { _ } from "svelte-i18n";
3
3
  import { Client } from "@gradio/client";
4
4
  import { writable } from "svelte/store";
5
5
  import { setupi18n } from "./i18n";
6
- import { ApiDocs, ApiRecorder, Settings } from "./api_docs/";
7
6
  import { Toast } from "@gradio/statustracker";
8
7
  import MountComponents from "./MountComponents.svelte";
9
8
  import { prefix_css } from "./css";
@@ -80,8 +79,36 @@ let settings_visible = search_params.get("view") === "settings";
80
79
  let api_recorder_visible = search_params.get("view") === "api-recorder" && show_api;
81
80
  let allow_zoom = true;
82
81
  let allow_video_trim = true;
83
- function set_api_docs_visible(visible) {
82
+ let ApiDocs = null;
83
+ let ApiRecorder = null;
84
+ let Settings = null;
85
+ async function loadApiDocs() {
86
+ if (!ApiDocs || !ApiRecorder) {
87
+ const api_docs_module = await import("./api_docs/ApiDocs.svelte");
88
+ const api_recorder_module = await import("./api_docs/ApiRecorder.svelte");
89
+ if (!ApiDocs)
90
+ ApiDocs = api_docs_module.default;
91
+ if (!ApiRecorder)
92
+ ApiRecorder = api_recorder_module.default;
93
+ }
94
+ }
95
+ async function loadApiRecorder() {
96
+ if (!ApiRecorder) {
97
+ const api_recorder_module = await import("./api_docs/ApiRecorder.svelte");
98
+ ApiRecorder = api_recorder_module.default;
99
+ }
100
+ }
101
+ async function loadSettings() {
102
+ if (!Settings) {
103
+ const settings_module = await import("./api_docs/Settings.svelte");
104
+ Settings = settings_module.default;
105
+ }
106
+ }
107
+ async function set_api_docs_visible(visible) {
84
108
  api_recorder_visible = false;
109
+ if (visible) {
110
+ await loadApiDocs();
111
+ }
85
112
  api_docs_visible = visible;
86
113
  let params = new URLSearchParams(window.location.search);
87
114
  if (visible) {
@@ -91,7 +118,10 @@ function set_api_docs_visible(visible) {
91
118
  }
92
119
  history.replaceState(null, "", "?" + params.toString());
93
120
  }
94
- function set_settings_visible(visible) {
121
+ async function set_settings_visible(visible) {
122
+ if (visible) {
123
+ await loadSettings();
124
+ }
95
125
  let params = new URLSearchParams(window.location.search);
96
126
  if (visible) {
97
127
  params.set("view", "settings");
@@ -658,6 +688,15 @@ onMount(() => {
658
688
  $is_screen_recording = isRecording;
659
689
  }
660
690
  );
691
+ if (api_docs_visible) {
692
+ loadApiDocs();
693
+ }
694
+ if (api_recorder_visible) {
695
+ loadApiRecorder();
696
+ }
697
+ if (settings_visible) {
698
+ loadSettings();
699
+ }
661
700
  });
662
701
  function screen_recording() {
663
702
  if ($is_screen_recording) {
@@ -666,10 +705,6 @@ function screen_recording() {
666
705
  screen_recorder.startRecording();
667
706
  }
668
707
  }
669
- let i18n_ready = false;
670
- setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
671
- i18n_ready = true;
672
- });
673
708
  </script>
674
709
 
675
710
  <svelte:head>
@@ -683,7 +718,7 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
683
718
 
684
719
  <div class="wrap" style:min-height={app_mode ? "100%" : "auto"}>
685
720
  <div class="contain" style:flex-grow={app_mode ? "1" : "auto"}>
686
- {#if $_layout && app.config && i18n_ready}
721
+ {#if $_layout && app.config}
687
722
  <MountComponents
688
723
  rootNode={$_layout}
689
724
  {root}
@@ -705,6 +740,10 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
705
740
  on:click={() => {
706
741
  set_api_docs_visible(!api_docs_visible);
707
742
  }}
743
+ on:mouseenter={() => {
744
+ loadApiDocs();
745
+ loadApiRecorder();
746
+ }}
708
747
  class="show-api"
709
748
  >
710
749
  {#if app.config?.mcp_server}
@@ -741,6 +780,9 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
741
780
  on:click={() => {
742
781
  set_settings_visible(!settings_visible);
743
782
  }}
783
+ on:mouseenter={() => {
784
+ loadSettings();
785
+ }}
744
786
  class="settings"
745
787
  >
746
788
  {$_("common.settings")}
@@ -750,7 +792,7 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
750
792
  {/if}
751
793
  </div>
752
794
 
753
- {#if api_recorder_visible}
795
+ {#if api_recorder_visible && ApiRecorder}
754
796
  <!-- TODO: fix -->
755
797
  <!-- svelte-ignore a11y-click-events-have-key-events-->
756
798
  <!-- svelte-ignore a11y-no-static-element-interactions-->
@@ -761,11 +803,11 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
761
803
  api_recorder_visible = false;
762
804
  }}
763
805
  >
764
- <ApiRecorder {api_calls} {dependencies} />
806
+ <svelte:component this={ApiRecorder} {api_calls} {dependencies} />
765
807
  </div>
766
808
  {/if}
767
809
 
768
- {#if api_docs_visible && $_layout}
810
+ {#if api_docs_visible && $_layout && ApiDocs}
769
811
  <div class="api-docs">
770
812
  <!-- TODO: fix -->
771
813
  <!-- svelte-ignore a11y-click-events-have-key-events-->
@@ -777,12 +819,14 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
777
819
  }}
778
820
  />
779
821
  <div class="api-docs-wrap">
780
- <ApiDocs
822
+ <svelte:component
823
+ this={ApiDocs}
781
824
  root_node={$_layout}
782
825
  on:close={(event) => {
783
826
  set_api_docs_visible(false);
784
827
  api_calls = [];
785
- api_recorder_visible = event.detail?.api_recorder_visible;
828
+ api_recorder_visible = api_recorder_visible =
829
+ event.detail?.api_recorder_visible;
786
830
  }}
787
831
  {dependencies}
788
832
  {root}
@@ -795,7 +839,7 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
795
839
  </div>
796
840
  {/if}
797
841
 
798
- {#if settings_visible && $_layout && app.config}
842
+ {#if settings_visible && $_layout && app.config && Settings}
799
843
  <div class="api-docs">
800
844
  <!-- TODO: fix -->
801
845
  <!-- svelte-ignore a11y-click-events-have-key-events-->
@@ -807,13 +851,14 @@ setupi18n(app.config?.i18n_translations ?? void 0).then(() => {
807
851
  }}
808
852
  />
809
853
  <div class="api-docs-wrap">
810
- <Settings
854
+ <svelte:component
855
+ this={Settings}
811
856
  bind:allow_zoom
812
857
  bind:allow_video_trim
813
- on:close={(event) => {
858
+ on:close={() => {
814
859
  set_settings_visible(false);
815
860
  }}
816
- on:start_recording={(event) => {
861
+ on:start_recording={() => {
817
862
  screen_recording();
818
863
  }}
819
864
  pwa_enabled={app.config.pwa}
@@ -39,7 +39,9 @@ $: {
39
39
  setContext("BLOCK_KEY", parent);
40
40
  $: {
41
41
  if (node && node.type === "form") {
42
- if (node.children?.every((c) => !c.props.visible)) {
42
+ if (node.children?.every(
43
+ (c) => typeof c.props.visible === "boolean" && !c.props.visible
44
+ )) {
43
45
  node.props.visible = false;
44
46
  } else {
45
47
  node.props.visible = true;
@@ -61,34 +63,39 @@ $:
61
63
  );
62
64
  </script>
63
65
 
64
- <RenderComponent
65
- _id={node?.id}
66
- component={node.component}
67
- bind:instance={node.instance}
68
- bind:value={node.props.value}
69
- elem_id={("elem_id" in node.props && node.props.elem_id) ||
70
- `component-${node.id}`}
71
- elem_classes={("elem_classes" in node.props && node.props.elem_classes) || []}
72
- {target}
73
- {...node.props}
74
- {theme_mode}
75
- {root}
76
- visible={typeof node.props.visible === "boolean" ? node.props.visible : true}
77
- >
78
- {#if node.children && node.children.length}
79
- {#each node.children as _node (_node.id)}
80
- <svelte:self
81
- node={_node}
82
- component={_node.component}
83
- {target}
84
- id={_node.id}
85
- {root}
86
- {theme_mode}
87
- on:destroy
88
- on:mount
89
- {max_file_size}
90
- {client}
91
- />
92
- {/each}
93
- {/if}
94
- </RenderComponent>
66
+ {#if node.component}
67
+ <RenderComponent
68
+ _id={node?.id}
69
+ component={node.component}
70
+ bind:instance={node.instance}
71
+ bind:value={node.props.value}
72
+ elem_id={("elem_id" in node.props && node.props.elem_id) ||
73
+ `component-${node.id}`}
74
+ elem_classes={("elem_classes" in node.props && node.props.elem_classes) ||
75
+ []}
76
+ {target}
77
+ {...node.props}
78
+ {theme_mode}
79
+ {root}
80
+ visible={typeof node.props.visible === "boolean"
81
+ ? node.props.visible
82
+ : true}
83
+ >
84
+ {#if node.children && node.children.length}
85
+ {#each node.children as _node (_node.id)}
86
+ <svelte:self
87
+ node={_node}
88
+ component={_node.component}
89
+ {target}
90
+ id={_node.id}
91
+ {root}
92
+ {theme_mode}
93
+ on:destroy
94
+ on:mount
95
+ {max_file_size}
96
+ {client}
97
+ />
98
+ {/each}
99
+ {/if}
100
+ </RenderComponent>
101
+ {/if}
@@ -34,7 +34,7 @@ function wrap(component2) {
34
34
  });
35
35
  return ProxiedMyClass;
36
36
  }
37
- const _component = wrap(component);
37
+ let _component = wrap(component);
38
38
  const supported_props = [
39
39
  "description",
40
40
  "info",
@@ -56,20 +56,19 @@ $:
56
56
  value = translate_if_needed(value);
57
57
  </script>
58
58
 
59
- <!-- {#if visible} -->
60
- <svelte:component
61
- this={_component}
62
- bind:this={instance}
63
- bind:value
64
- on:prop_change
65
- {elem_id}
66
- {elem_classes}
67
- {target}
68
- {visible}
69
- {...$$restProps}
70
- {theme_mode}
71
- {root}
72
- >
73
- <slot />
74
- </svelte:component>
75
- <!-- {/if} -->
59
+ {#if visible}
60
+ <svelte:component
61
+ this={_component}
62
+ bind:this={instance}
63
+ bind:value
64
+ on:prop_change
65
+ {elem_id}
66
+ {elem_classes}
67
+ {target}
68
+ {...$$restProps}
69
+ {theme_mode}
70
+ {root}
71
+ >
72
+ <slot />
73
+ </svelte:component>
74
+ {/if}
@@ -2,8 +2,17 @@ export interface I18nData {
2
2
  __type__: "translation_metadata";
3
3
  key: string;
4
4
  }
5
+ export type Lang = {
6
+ [key: string]: Record<string, string> | string;
7
+ };
5
8
  export interface LangsRecord {
6
- [lang: string]: any;
9
+ [lang: string]: {
10
+ type: "lazy";
11
+ data: () => Promise<Lang>;
12
+ } | {
13
+ type: "static";
14
+ data: Lang;
15
+ };
7
16
  }
8
17
  export declare function is_translation_metadata(obj: any): obj is I18nData;
9
18
  export declare function translate_if_needed(value: any): string;
@@ -13,4 +22,7 @@ export declare let all_common_keys: Set<string>;
13
22
  export declare function setupi18n(custom_translations?: Record<string, Record<string, string>>): Promise<void>;
14
23
  export declare function changeLocale(new_locale: string): void;
15
24
  export declare function get_initial_locale(browser_locale: string | null, available_locales: string[], fallback_locale?: string): string;
16
- export declare function load_translations(translations: LangsRecord | null | undefined): void;
25
+ export declare function load_translations(translations: {
26
+ processed_langs: LangsRecord;
27
+ custom_translations: Record<string, Record<string, string>>;
28
+ }): void;
package/dist/src/i18n.js CHANGED
@@ -1,10 +1,41 @@
1
- import { addMessages, init, getLocaleFromNavigator, locale } from "svelte-i18n";
1
+ import { addMessages, init, getLocaleFromNavigator, locale, register, waitLocale } from "svelte-i18n";
2
2
  import { formatter } from "./gradio_helper";
3
- const langs = import.meta.glob("./lang/*.json", {
4
- eager: true
5
- });
3
+ const lang_map = {
4
+ ar: "العربية",
5
+ ca: "Català",
6
+ ckb: "کوردی",
7
+ de: "Deutsch",
8
+ en: "English",
9
+ es: "Español",
10
+ eu: "Euskara",
11
+ fa: "فارسی",
12
+ fi: "Suomi",
13
+ fr: "Français",
14
+ he: "עברית",
15
+ hi: "हिंदी",
16
+ ja: "日本語",
17
+ ko: "한국어",
18
+ lt: "Lietuvių",
19
+ nb: "Norsk bokmål",
20
+ nl: "Nederlands",
21
+ pl: "Polski",
22
+ "pt-BR": "Português do Brasil",
23
+ pt: "Português",
24
+ ro: "Română",
25
+ ru: "Русский",
26
+ sv: "Svenska",
27
+ ta: "தமிழ்",
28
+ th: "ภาษาไทย",
29
+ tr: "Türkçe",
30
+ uk: "Українська",
31
+ ur: "اردو",
32
+ uz: "O'zbek",
33
+ "zh-CN": "简体中文",
34
+ "zh-TW": "繁體中文"
35
+ };
36
+ const langs = import.meta.glob("./lang/*.json");
37
+ import en from "./lang/en.json";
6
38
  export function is_translation_metadata(obj) {
7
- console.log(obj);
8
39
  const result = obj &&
9
40
  typeof obj === "object" &&
10
41
  obj.__type__ === "translation_metadata" &&
@@ -61,14 +92,18 @@ export function translate_if_needed(value) {
61
92
  }
62
93
  }
63
94
  export function process_langs() {
64
- return Object.fromEntries(Object.entries(langs).map(([path, module]) => [
95
+ const lazy_langs = Object.fromEntries(Object.entries(langs).map(([path, mod]) => [
65
96
  path.split("/").pop().split(".")[0],
66
- module.default
97
+ { type: "lazy", data: mod }
67
98
  ]));
99
+ return {
100
+ ...lazy_langs,
101
+ en: { type: "static", data: en }
102
+ };
68
103
  }
69
104
  const processed_langs = process_langs();
70
105
  const available_locales = Object.keys(processed_langs);
71
- export const language_choices = Object.entries(processed_langs).map(([code, data]) => [data._name || code, code]);
106
+ export const language_choices = Object.entries(processed_langs).map(([code]) => [lang_map[code] || code, code]);
72
107
  export let all_common_keys = new Set();
73
108
  let i18n_initialized = false;
74
109
  let previous_translations;
@@ -79,8 +114,8 @@ export async function setupi18n(custom_translations) {
79
114
  }
80
115
  previous_translations = custom_translations;
81
116
  load_translations({
82
- ...processed_langs,
83
- ...(custom_translations ?? {})
117
+ processed_langs,
118
+ custom_translations: custom_translations ?? {}
84
119
  });
85
120
  const browser_locale = getLocaleFromNavigator();
86
121
  let initial_locale = browser_locale && available_locales.includes(browser_locale)
@@ -97,17 +132,6 @@ export async function setupi18n(custom_translations) {
97
132
  fallbackLocale: "en",
98
133
  initialLocale: initial_locale
99
134
  });
100
- for (const lang_code in processed_langs) {
101
- if (processed_langs[lang_code] &&
102
- typeof processed_langs[lang_code] === "object" &&
103
- processed_langs[lang_code].common &&
104
- typeof processed_langs[lang_code].common === "object") {
105
- const common_ns = processed_langs[lang_code].common;
106
- for (const key in common_ns) {
107
- all_common_keys.add(`common.${key}`);
108
- }
109
- }
110
- }
111
135
  i18n_initialized = true;
112
136
  }
113
137
  export function changeLocale(new_locale) {
@@ -126,8 +150,17 @@ export function load_translations(translations) {
126
150
  return;
127
151
  }
128
152
  try {
129
- for (const lang in translations) {
130
- addMessages(lang, translations[lang]);
153
+ for (const lang in translations.custom_translations) {
154
+ addMessages(lang, translations.custom_translations[lang]);
155
+ }
156
+ for (const lang in translations.processed_langs) {
157
+ if (lang === "en" &&
158
+ translations.processed_langs[lang].type === "static") {
159
+ addMessages(lang, en);
160
+ }
161
+ else if (translations.processed_langs[lang].type === "lazy") {
162
+ register(lang, translations.processed_langs[lang].data);
163
+ }
131
164
  }
132
165
  }
133
166
  catch (e) {
@@ -97,7 +97,15 @@ export declare function get_component(type: string, class_id: string, root: stri
97
97
  example_components?: Map<ComponentMeta["type"], LoadingComponent>;
98
98
  };
99
99
  /**
100
- * Preload all components
100
+ * Preload only visible components
101
+ * @param components A list of component metadata
102
+ * @param layout The layout tree to determine visibility
103
+ * @param root The root url of the app
104
+ * @returns A map of component ids to their constructors
105
+ */
106
+ export declare function preload_visible_components(components: ComponentMeta[], layout: LayoutNode, root: string): Map<ComponentMeta["type"], LoadingComponent>;
107
+ /**
108
+ * Preload all components (legacy function, kept for backwards compatibility)
101
109
  * @param components A list of component metadata
102
110
  * @param root The root url of the app
103
111
  * @returns A map of component ids to their constructors