@gradio/core 1.2.0 → 1.4.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/dist/src/Blocks.svelte +39 -18
  3. package/dist/src/MountComponents.svelte +11 -2
  4. package/dist/src/MountComponents.svelte.d.ts +1 -1
  5. package/dist/src/MountCustomComponent.svelte +38 -0
  6. package/dist/src/MountCustomComponent.svelte.d.ts +6 -0
  7. package/dist/src/api_docs/ApiBanner.svelte +6 -2
  8. package/dist/src/api_docs/ApiBanner.svelte.d.ts +1 -1
  9. package/dist/src/api_docs/ApiDocs.svelte +41 -25
  10. package/dist/src/api_docs/CodeSnippet.svelte +67 -170
  11. package/dist/src/api_docs/CodeSnippet.svelte.d.ts +2 -6
  12. package/dist/src/api_docs/CopyMarkdown.svelte +7 -2
  13. package/dist/src/api_docs/CopyMarkdown.svelte.d.ts +1 -1
  14. package/dist/src/api_docs/InstallSnippet.svelte +6 -1
  15. package/dist/src/api_docs/InstallSnippet.svelte.d.ts +1 -1
  16. package/dist/src/api_docs/ParametersSnippet.svelte +6 -1
  17. package/dist/src/api_docs/ParametersSnippet.svelte.d.ts +1 -1
  18. package/dist/src/api_docs/RecordingSnippet.svelte +6 -1
  19. package/dist/src/api_docs/RecordingSnippet.svelte.d.ts +1 -1
  20. package/dist/src/api_docs/ResponseSnippet.svelte +6 -1
  21. package/dist/src/api_docs/ResponseSnippet.svelte.d.ts +1 -1
  22. package/dist/src/api_docs/SkillSnippet.svelte +125 -0
  23. package/dist/src/api_docs/SkillSnippet.svelte.d.ts +20 -0
  24. package/dist/src/api_docs/img/skill.svg +10 -0
  25. package/dist/src/api_docs/utils.d.ts +0 -1
  26. package/dist/src/api_docs/utils.js +0 -22
  27. package/dist/src/dependency.d.ts +3 -1
  28. package/dist/src/dependency.js +19 -1
  29. package/dist/src/init.svelte.d.ts +1 -1
  30. package/dist/src/init.svelte.js +108 -34
  31. package/dist/src/init_utils.d.ts +4 -1
  32. package/dist/src/init_utils.js +1 -1
  33. package/dist/src/types.d.ts +2 -0
  34. package/dist/src/vite-env-override.d.ts +1 -0
  35. package/package.json +55 -55
  36. package/src/Blocks.svelte +39 -18
  37. package/src/MountComponents.svelte +11 -2
  38. package/src/MountCustomComponent.svelte +38 -0
  39. package/src/api_docs/ApiBanner.svelte +6 -2
  40. package/src/api_docs/ApiDocs.svelte +41 -25
  41. package/src/api_docs/CodeSnippet.svelte +67 -170
  42. package/src/api_docs/CopyMarkdown.svelte +7 -2
  43. package/src/api_docs/InstallSnippet.svelte +6 -1
  44. package/src/api_docs/ParametersSnippet.svelte +6 -1
  45. package/src/api_docs/RecordingSnippet.svelte +6 -1
  46. package/src/api_docs/ResponseSnippet.svelte +6 -1
  47. package/src/api_docs/SkillSnippet.svelte +125 -0
  48. package/src/api_docs/img/skill.svg +10 -0
  49. package/src/api_docs/utils.ts +0 -25
  50. package/src/dependency.ts +19 -1
  51. package/src/init.svelte.ts +139 -43
  52. package/src/init.test.ts +1 -1
  53. package/src/init_utils.ts +2 -2
  54. package/src/types.ts +2 -1
  55. package/src/vite-env-override.d.ts +1 -0
@@ -118,13 +118,16 @@ export class DependencyManager {
118
118
  get_state_cb;
119
119
  rerender_cb;
120
120
  log_cb;
121
+ on_connection_lost_cb;
121
122
  loading_stati = new LoadingStatus();
122
- constructor(dependencies, client, update_state_cb, get_state_cb, rerender_cb, log_cb, add_to_api_calls) {
123
+ connection_lost = false;
124
+ constructor(dependencies, client, update_state_cb, get_state_cb, rerender_cb, log_cb, add_to_api_calls, on_connection_lost_cb) {
123
125
  this.add_to_api_calls = add_to_api_calls;
124
126
  this.log_cb = log_cb;
125
127
  this.update_state_cb = update_state_cb;
126
128
  this.get_state_cb = get_state_cb;
127
129
  this.rerender_cb = rerender_cb;
130
+ this.on_connection_lost_cb = on_connection_lost_cb;
128
131
  this.client = client;
129
132
  this.reload(dependencies, update_state_cb, get_state_cb, rerender_cb, client);
130
133
  }
@@ -180,6 +183,8 @@ export class DependencyManager {
180
183
  * @returns a value if there is no backend fn, a 'submission' if there is a backend fn, or null if there is no dependency
181
184
  */
182
185
  async dispatch(event_meta) {
186
+ if (this.connection_lost)
187
+ return;
183
188
  let deps;
184
189
  if (event_meta.type === "fn") {
185
190
  const dep = this.dependencies_by_fn.get(event_meta.fn_index);
@@ -314,6 +319,19 @@ export class DependencyManager {
314
319
  this.update_loading_stati_state();
315
320
  }
316
321
  else if (result.stage === "error") {
322
+ if (result.broken || result.session_not_found) {
323
+ if (!this.connection_lost) {
324
+ this.connection_lost = true;
325
+ this.on_connection_lost_cb();
326
+ }
327
+ this.loading_stati.update({
328
+ status: "complete",
329
+ fn_index: dep.id,
330
+ stream_state: null
331
+ });
332
+ this.update_loading_stati_state();
333
+ break submit_loop;
334
+ }
317
335
  if (Array.isArray(result?.message)) {
318
336
  result.message.forEach((m, i) => {
319
337
  this.update_state_cb(dep.inputs[i], {
@@ -61,8 +61,8 @@ export declare class AppTree {
61
61
  */
62
62
  create_node(opts: LayoutNode, component_map: Map<number, ComponentMeta>, root?: boolean, reactive_formatter?: (str: string) => string): ProcessedComponentMeta;
63
63
  rerender(components: ComponentMeta[], layout: LayoutNode): void;
64
- update_visibility(node: ProcessedComponentMeta, new_state: any): Promise<void>;
65
64
  update_state(id: number, new_state: Partial<SharedProps> & Record<string, unknown>, check_visibility?: boolean): Promise<void>;
65
+ update_visibility(node: ProcessedComponentMeta, new_state: any): Promise<void>;
66
66
  /**
67
67
  * Gets the current state of a component by its ID
68
68
  * @param id the ID of the component to get the state of
@@ -31,6 +31,7 @@ export class AppTree {
31
31
  #pending_components = [];
32
32
  #get_callbacks = new Map();
33
33
  #set_callbacks = new Map();
34
+ #pending_updates = new Map();
34
35
  #event_dispatcher;
35
36
  component_ids;
36
37
  initial_tabs = {};
@@ -51,6 +52,7 @@ export class AppTree {
51
52
  this.#component_payload = components;
52
53
  this.#layout_payload = layout;
53
54
  this.#dependency_payload = dependencies;
55
+ this.#event_dispatcher = event_dispatcher;
54
56
  this.root = this.create_node({ id: layout.id, children: [] }, new Map(), true);
55
57
  for (const comp of components) {
56
58
  if (comp.props.visible != false)
@@ -70,7 +72,6 @@ export class AppTree {
70
72
  this.initial_tabs = {};
71
73
  gather_initial_tabs(this.root, this.initial_tabs);
72
74
  this.postprocess(this.root);
73
- this.#event_dispatcher = event_dispatcher;
74
75
  this.root_untracked = this.root;
75
76
  }
76
77
  reload(components, layout, dependencies, config) {
@@ -110,6 +111,20 @@ export class AppTree {
110
111
  this.#set_callbacks.set(id, _set_data);
111
112
  this.#get_callbacks.set(id, _get_data);
112
113
  this.components_to_register.delete(id);
114
+ // Apply any pending updates that were stored while the component
115
+ // was not yet mounted (e.g. hidden in an inactive tab).
116
+ // We must apply AFTER tick() so that the Gradio class's $effect
117
+ // (which syncs from node props) has already run. Otherwise the
118
+ // $effect would overwrite the values we set here.
119
+ const pending = this.#pending_updates.get(id);
120
+ if (pending) {
121
+ this.#pending_updates.delete(id);
122
+ tick().then(() => {
123
+ const _set = this.#set_callbacks.get(id);
124
+ if (_set)
125
+ _set(pending);
126
+ });
127
+ }
113
128
  if (this.components_to_register.size === 0 && !this.resolved) {
114
129
  this.resolved = true;
115
130
  this.ready_resolve();
@@ -190,7 +205,8 @@ export class AppTree {
190
205
  props: {
191
206
  visible: true,
192
207
  root: "",
193
- theme_mode: "light"
208
+ theme_mode: "light",
209
+ scale: this.#config.fill_height ? 1 : null
194
210
  },
195
211
  component_class_id: "column",
196
212
  key: null
@@ -202,8 +218,15 @@ export class AppTree {
202
218
  if (reactive_formatter) {
203
219
  component.props.i18n = reactive_formatter;
204
220
  }
205
- const processed_props = gather_props(opts.id, component.props, [this.#input_ids, this.#output_ids], this.client, this.#config.api_url, { ...this.#config });
221
+ const processed_props = gather_props(opts.id, component.props, [this.#input_ids, this.#output_ids], this.client, this.#config.api_url, {
222
+ ...this.#config,
223
+ register_component: this.register_component.bind(this),
224
+ dispatcher: this.#event_dispatcher.bind(this)
225
+ });
206
226
  const type = type_map[component.type] || component.type;
227
+ const loading_component = processed_props.shared_props.visible !== false
228
+ ? get_component(component.type, component.component_class_id, this.#config.api_url || "")
229
+ : null;
207
230
  const node = {
208
231
  id: opts.id,
209
232
  type: type,
@@ -212,8 +235,9 @@ export class AppTree {
212
235
  show_progress_on: null,
213
236
  component_class_id: component.component_class_id || component.type,
214
237
  component: processed_props.shared_props.visible !== false
215
- ? get_component(component.type, component.component_class_id, this.#config.api_url || "")
238
+ ? loading_component?.component || null
216
239
  : null,
240
+ runtime: loading_component?.runtime || false,
217
241
  key: component.key,
218
242
  rendered_in: component.rendered_in,
219
243
  documentation: component.documentation,
@@ -238,15 +262,6 @@ export class AppTree {
238
262
  }
239
263
  n.children = subtree.children;
240
264
  }
241
- async update_visibility(node, new_state) {
242
- node.children.forEach((child) => {
243
- const _set_data = this.#set_callbacks.get(child.id);
244
- if (_set_data) {
245
- _set_data(new_state);
246
- }
247
- this.update_visibility(child, new_state);
248
- });
249
- }
250
265
  /*
251
266
  * Updates the state of a component by its ID
252
267
  * @param id the ID of the component to update
@@ -276,11 +291,22 @@ export class AppTree {
276
291
  const old_value = node?.props.props.value;
277
292
  // @ts-ignore
278
293
  const new_props = create_props_shared_props(new_state);
279
- node.props.shared_props = {
280
- ...node?.props.shared_props,
281
- ...new_props.shared_props
282
- };
283
- node.props.props = { ...node?.props.props, ...new_props.props };
294
+ // Modify props in-place instead of replacing the entire object.
295
+ // Replacing with a new object via spread can cause Svelte 5's
296
+ // deep $state proxy to lose track of the values during async
297
+ // component mounting/revival.
298
+ for (const key in new_props.shared_props) {
299
+ // @ts-ignore
300
+ node.props.shared_props[key] = new_props.shared_props[key];
301
+ }
302
+ for (const key in new_props.props) {
303
+ // @ts-ignore
304
+ node.props.props[key] = new_props.props[key];
305
+ }
306
+ // Also store as pending so the value can be applied via _set_data
307
+ // when the component eventually mounts and registers
308
+ const existing = this.#pending_updates.get(id) || {};
309
+ this.#pending_updates.set(id, { ...existing, ...new_state });
284
310
  if ("value" in new_state && !dequal(old_value, new_state.value)) {
285
311
  this.#event_dispatcher(id, "change", null);
286
312
  }
@@ -299,6 +325,15 @@ export class AppTree {
299
325
  // @ts-ignore
300
326
  await this.update_visibility(node, new_state);
301
327
  }
328
+ async update_visibility(node, new_state) {
329
+ node.children.forEach((child) => {
330
+ const _set_data = this.#set_callbacks.get(child.id);
331
+ if (_set_data) {
332
+ _set_data(new_state);
333
+ }
334
+ this.update_visibility(child, new_state);
335
+ });
336
+ }
302
337
  /**
303
338
  * Gets the current state of a component by its ID
304
339
  * @param id the ID of the component to get the state of
@@ -316,24 +351,58 @@ export class AppTree {
316
351
  return null;
317
352
  }
318
353
  async render_previously_invisible_children(id) {
319
- this.root = this.traverse(this.root, [
320
- (node) => {
321
- if (node.id === id) {
322
- make_visible_if_not_rendered(node, this.#hidden_on_startup);
323
- }
324
- return node;
325
- },
326
- (node) => handle_visibility(node, this.#config.api_url)
327
- ]);
354
+ const node = find_node_by_id(this.root, id);
355
+ if (!node)
356
+ return;
357
+ // Check if this node or any of its descendants need to be made visible.
358
+ // If not, skip entirely to avoid unnecessary reactive updates
359
+ // from mutating the tree through the $state proxy.
360
+ if (!this.#hidden_on_startup.has(node.id) &&
361
+ !has_hidden_descendants(node, this.#hidden_on_startup)) {
362
+ return;
363
+ }
364
+ make_visible_if_not_rendered(node, this.#hidden_on_startup, true);
365
+ load_components(node, this.#config.api_url);
328
366
  }
329
367
  }
330
- function make_visible_if_not_rendered(node, hidden_on_startup) {
368
+ function make_visible_if_not_rendered(node, hidden_on_startup, is_target_node = false) {
331
369
  node.props.shared_props.visible = hidden_on_startup.has(node.id)
332
370
  ? true
333
371
  : node.props.shared_props.visible;
334
- node.children.forEach((child) => {
335
- make_visible_if_not_rendered(child, hidden_on_startup);
336
- });
372
+ if (node.type === "tabs") {
373
+ const selectedId = node.props.props.selected ?? node.props.props.initial_tabs?.[0]?.id;
374
+ node.children.forEach((child) => {
375
+ if (child.type === "tabitem" &&
376
+ (child.props.props.id === selectedId || child.id === selectedId)) {
377
+ make_visible_if_not_rendered(child, hidden_on_startup, false);
378
+ }
379
+ });
380
+ }
381
+ else if (node.type === "accordion" &&
382
+ node.props.props.open === false &&
383
+ !is_target_node) {
384
+ // Don't recurse into closed accordion content
385
+ }
386
+ else {
387
+ node.children.forEach((child) => {
388
+ make_visible_if_not_rendered(child, hidden_on_startup, false);
389
+ });
390
+ }
391
+ }
392
+ function has_hidden_descendants(node, hidden_on_startup) {
393
+ for (const child of node.children) {
394
+ if (hidden_on_startup.has(child.id))
395
+ return true;
396
+ if (has_hidden_descendants(child, hidden_on_startup))
397
+ return true;
398
+ }
399
+ return false;
400
+ }
401
+ function load_components(node, api_url) {
402
+ if (node.props.shared_props.visible && !node.component) {
403
+ node.component = get_component(node.type, node.component_class_id, api_url);
404
+ }
405
+ node.children.forEach((child) => load_components(child, api_url));
337
406
  }
338
407
  /**
339
408
  * Process the server function names and return a dictionary of functions
@@ -390,6 +459,7 @@ function gather_props(id, props, dependencies, client, api_url, additional = {})
390
459
  for (const key in additional) {
391
460
  if (allowed_shared_props.includes(key)) {
392
461
  const _key = key;
462
+ //@ts-ignore
393
463
  _shared_props[_key] = additional[key];
394
464
  }
395
465
  else {
@@ -399,7 +469,7 @@ function gather_props(id, props, dependencies, client, api_url, additional = {})
399
469
  _shared_props.client = client;
400
470
  _shared_props.id = id;
401
471
  _shared_props.interactive = determine_interactivity(id, _shared_props.interactive, _props.value, dependencies);
402
- _shared_props.load_component = (name, variant) => get_component(name, "", api_url, variant);
472
+ _shared_props.load_component = (name, variant) => get_component(name, "", api_url, variant).component;
403
473
  _shared_props.visible =
404
474
  _shared_props.visible === undefined ? true : _shared_props.visible;
405
475
  _shared_props.loading_status = {};
@@ -408,9 +478,10 @@ function gather_props(id, props, dependencies, client, api_url, additional = {})
408
478
  function handle_visibility(node, api_url) {
409
479
  // Check if the node is visible
410
480
  if (node.props.shared_props.visible && !node.component) {
481
+ const loading_component = get_component(node.type, node.component_class_id, api_url);
411
482
  const result = {
412
483
  ...node,
413
- component: get_component(node.type, node.component_class_id, api_url),
484
+ component: loading_component.component,
414
485
  children: []
415
486
  };
416
487
  if (node.children) {
@@ -466,6 +537,7 @@ function untrack_children_of_closed_accordions_or_inactive_tabs(node, components
466
537
  node.children.forEach((child) => {
467
538
  if (child.type === "tabitem" &&
468
539
  child.props.props.id !==
540
+ //@ts-ignore
469
541
  (node.props.props.selected || node.props.props.initial_tabs[0].id)) {
470
542
  _untrack(child, components_to_register);
471
543
  mark_component_invisible_if_visible(child, hidden_on_startup);
@@ -492,8 +564,10 @@ function _gather_initial_tabs(node, initial_tabs, parent_tab_id, order) {
492
564
  if (!("id" in node.props.props)) {
493
565
  node.props.props.id = node.id;
494
566
  }
567
+ const i18n = node.props.props.i18n;
568
+ const raw_label = node.props.shared_props.label;
495
569
  initial_tabs[parent_tab_id].push({
496
- label: node.props.shared_props.label,
570
+ label: i18n ? i18n(raw_label) : raw_label,
497
571
  id: node.props.props.id,
498
572
  elem_id: node.props.shared_props.elem_id,
499
573
  visible: node.props.shared_props.visible,
@@ -6,7 +6,10 @@ import type { Dependency, LoadingComponent } from "./types";
6
6
  * @param root
7
7
  * @returns the loading component
8
8
  */
9
- export declare function get_component(type: string, class_id: string, root: string, variant?: "component" | "example" | "base"): LoadingComponent;
9
+ export declare function get_component(type: string, class_id: string, root: string, variant?: "component" | "example" | "base"): {
10
+ component: LoadingComponent;
11
+ runtime: false | typeof import("svelte");
12
+ };
10
13
  /**
11
14
  * Get all component ids that are an input dependency and all that are an output dependency
12
15
  * @param dep the dependency
@@ -14,7 +14,7 @@ export function get_component(type, class_id, root, variant = "component") {
14
14
  name: type,
15
15
  id: class_id,
16
16
  variant
17
- }).component;
17
+ });
18
18
  }
19
19
  /**
20
20
  * Get all component ids that are an input dependency and all that are an output dependency
@@ -23,6 +23,7 @@ export interface ProcessedComponentMeta {
23
23
  props: Record<string, unknown>;
24
24
  };
25
25
  component: Component | LoadingComponent | null;
26
+ runtime: false | typeof import("svelte");
26
27
  documentation?: Documentation;
27
28
  children: ProcessedComponentMeta[];
28
29
  component_class_id: string;
@@ -109,5 +110,6 @@ export interface AppConfig {
109
110
  autoscroll: boolean;
110
111
  api_prefix: string;
111
112
  api_url: string;
113
+ fill_height?: boolean;
112
114
  }
113
115
  export {};
@@ -16,5 +16,6 @@ declare module "virtual:component-loader" {
16
16
  export function load_component(args: Args): {
17
17
  name: ComponentMeta["type"];
18
18
  component: LoadedComponent;
19
+ runtime: false | typeof import("svelte");
19
20
  };
20
21
  }
package/package.json CHANGED
@@ -1,67 +1,67 @@
1
1
  {
2
2
  "name": "@gradio/core",
3
- "version": "1.2.0",
3
+ "version": "1.4.0",
4
4
  "type": "module",
5
5
  "devDependencies": {
6
- "@gradio/accordion": "^0.5.31",
7
- "@gradio/audio": "^0.22.3",
8
- "@gradio/atoms": "^0.22.0",
6
+ "@gradio/accordion": "^0.5.32",
7
+ "@gradio/annotatedimage": "^0.11.4",
8
+ "@gradio/audio": "^0.22.4",
9
+ "@gradio/atoms": "^0.22.2",
9
10
  "@gradio/box": "^0.2.30",
10
- "@gradio/annotatedimage": "^0.11.3",
11
- "@gradio/browserstate": "^0.3.6",
12
- "@gradio/button": "^0.6.3",
13
- "@gradio/checkbox": "^0.6.3",
14
- "@gradio/checkboxgroup": "^0.9.3",
15
- "@gradio/client": "^2.0.4",
16
- "@gradio/code": "^0.17.3",
17
- "@gradio/colorpicker": "^0.5.6",
18
- "@gradio/dataframe": "^0.21.5",
19
- "@gradio/dataset": "^0.5.4",
20
- "@gradio/chatbot": "^0.29.4",
11
+ "@gradio/button": "^0.6.5",
12
+ "@gradio/browserstate": "^0.3.7",
13
+ "@gradio/chatbot": "^0.29.5",
14
+ "@gradio/checkbox": "^0.6.4",
15
+ "@gradio/checkboxgroup": "^0.9.4",
16
+ "@gradio/client": "^2.1.0",
17
+ "@gradio/code": "^0.17.4",
18
+ "@gradio/colorpicker": "^0.5.7",
21
19
  "@gradio/column": "^0.3.2",
22
- "@gradio/datetime": "^0.4.3",
23
- "@gradio/dropdown": "^0.11.4",
24
- "@gradio/fallback": "^0.4.34",
25
- "@gradio/file": "^0.14.3",
26
- "@gradio/form": "^0.3.0",
27
- "@gradio/downloadbutton": "^0.4.17",
28
- "@gradio/gallery": "^0.17.1",
29
- "@gradio/fileexplorer": "^0.6.3",
30
- "@gradio/group": "^0.3.2",
31
- "@gradio/highlightedtext": "^0.11.2",
32
- "@gradio/html": "^0.9.3",
20
+ "@gradio/datetime": "^0.4.4",
21
+ "@gradio/dataframe": "^0.21.7",
22
+ "@gradio/downloadbutton": "^0.4.18",
23
+ "@gradio/dataset": "^0.5.5",
24
+ "@gradio/dropdown": "^0.11.5",
25
+ "@gradio/file": "^0.14.4",
26
+ "@gradio/fallback": "^0.4.35",
27
+ "@gradio/fileexplorer": "^0.6.4",
28
+ "@gradio/gallery": "^0.17.3",
29
+ "@gradio/form": "^0.3.1",
30
+ "@gradio/group": "^0.3.3",
31
+ "@gradio/html": "^0.11.1",
32
+ "@gradio/highlightedtext": "^0.11.3",
33
33
  "@gradio/icons": "^0.15.1",
34
- "@gradio/imageeditor": "^0.18.6",
35
- "@gradio/image": "^0.25.3",
36
- "@gradio/label": "^0.6.3",
37
- "@gradio/json": "^0.7.2",
38
- "@gradio/imageslider": "^0.4.3",
39
- "@gradio/markdown": "^0.13.28",
40
- "@gradio/model3d": "^0.16.4",
41
- "@gradio/multimodaltextbox": "^0.11.6",
42
- "@gradio/paramviewer": "^0.9.4",
43
- "@gradio/nativeplot": "^0.10.2",
44
- "@gradio/number": "^0.8.3",
45
- "@gradio/plot": "^0.10.4",
46
- "@gradio/radio": "^0.9.3",
34
+ "@gradio/image": "^0.25.4",
35
+ "@gradio/imageeditor": "^0.18.7",
36
+ "@gradio/imageslider": "^0.4.4",
37
+ "@gradio/json": "^0.7.3",
38
+ "@gradio/label": "^0.6.4",
39
+ "@gradio/markdown": "^0.13.29",
40
+ "@gradio/multimodaltextbox": "^0.11.7",
41
+ "@gradio/number": "^0.8.4",
42
+ "@gradio/nativeplot": "^0.10.3",
43
+ "@gradio/paramviewer": "^0.9.5",
44
+ "@gradio/model3d": "^0.16.5",
45
+ "@gradio/plot": "^0.10.5",
46
+ "@gradio/sidebar": "^0.2.4",
47
+ "@gradio/radio": "^0.9.4",
48
+ "@gradio/simpledropdown": "^0.3.35",
49
+ "@gradio/simpleimage": "^0.9.6",
50
+ "@gradio/simpletextbox": "^0.3.37",
47
51
  "@gradio/row": "^0.3.1",
48
- "@gradio/simpletextbox": "^0.3.36",
49
- "@gradio/simpledropdown": "^0.3.34",
50
- "@gradio/sidebar": "^0.2.3",
51
- "@gradio/simpleimage": "^0.9.5",
52
- "@gradio/slider": "^0.7.6",
53
- "@gradio/state": "^0.2.2",
54
- "@gradio/tabitem": "^0.6.5",
55
- "@gradio/statustracker": "^0.12.4",
56
- "@gradio/tabs": "^0.5.6",
52
+ "@gradio/state": "^0.2.3",
53
+ "@gradio/slider": "^0.7.7",
54
+ "@gradio/tabitem": "^0.6.6",
55
+ "@gradio/statustracker": "^0.12.5",
56
+ "@gradio/textbox": "^0.13.5",
57
+ "@gradio/tabs": "^0.5.8",
57
58
  "@gradio/theme": "^0.6.1",
58
- "@gradio/textbox": "^0.13.4",
59
- "@gradio/upload": "^0.17.6",
60
- "@gradio/timer": "^0.4.8",
61
- "@gradio/uploadbutton": "^0.9.17",
62
- "@gradio/utils": "^0.11.3",
63
- "@gradio/video": "^0.20.3",
64
- "@gradio/vibeeditor": "^0.3.5"
59
+ "@gradio/timer": "^0.4.9",
60
+ "@gradio/upload": "^0.17.7",
61
+ "@gradio/utils": "^0.12.0",
62
+ "@gradio/uploadbutton": "^0.9.18",
63
+ "@gradio/video": "^0.20.4",
64
+ "@gradio/vibeeditor": "^0.3.6"
65
65
  },
66
66
  "msw": {
67
67
  "workerDirectory": "public"
package/src/Blocks.svelte CHANGED
@@ -4,18 +4,15 @@
4
4
  import { Client } from "@gradio/client";
5
5
  import { writable } from "svelte/store";
6
6
 
7
- // import type { LoadingStatus, LoadingStatusCollection } from "./stores";
8
-
9
7
  import type {
10
8
  ComponentMeta,
11
9
  Dependency as IDependency,
12
10
  LayoutNode
13
11
  } from "./types";
14
- // import type { UpdateTransaction } from "./_init";
15
12
  import type { ThemeMode, Payload } from "./types";
16
13
  import { Toast } from "@gradio/statustracker";
17
14
  import type { ToastMessage } from "@gradio/statustracker";
18
- import { type ShareData, type ValueData, GRADIO_ROOT } from "@gradio/utils";
15
+ import { type ShareData, GRADIO_ROOT } from "@gradio/utils";
19
16
 
20
17
  import MountComponents from "./MountComponents.svelte";
21
18
  import { prefix_css } from "./css";
@@ -24,18 +21,13 @@
24
21
  import type ApiDocsInterface from "./api_docs/ApiDocs.svelte";
25
22
  import type ApiRecorderInterface from "./api_docs/ApiRecorder.svelte";
26
23
  import type SettingsInterface from "./api_docs/Settings.svelte";
27
- // import type { ComponentType } from "svelte";
28
24
 
29
25
  import logo from "./images/logo.svg";
30
26
  import api_logo from "./api_docs/img/api-logo.svg";
31
27
  import settings_logo from "./api_docs/img/settings-logo.svg";
32
28
  import record_stop from "./api_docs/img/record-stop.svg";
33
29
  import { AppTree } from "./init.svelte";
34
- // import type {
35
- // LogMessage,
36
- // RenderMessage,
37
- // StatusMessage,
38
- // } from "@gradio/client";
30
+
39
31
  import * as screen_recorder from "./screen_recorder";
40
32
 
41
33
  import { DependencyManager } from "./dependency";
@@ -104,6 +96,7 @@
104
96
  });
105
97
 
106
98
  let messages: (ToastMessage & { fn_index: number })[] = $state([]);
99
+ let reconnect_interval: ReturnType<typeof setInterval> | null = null;
107
100
 
108
101
  function gradio_event_dispatcher(
109
102
  id: number,
@@ -170,7 +163,8 @@
170
163
  version,
171
164
  api_prefix,
172
165
  max_file_size,
173
- autoscroll
166
+ autoscroll,
167
+ fill_height
174
168
  },
175
169
  app,
176
170
  $reactive_formatter,
@@ -190,11 +184,6 @@
190
184
  });
191
185
  }
192
186
 
193
- setContext(GRADIO_ROOT, {
194
- register: app_tree.register_component.bind(app_tree),
195
- dispatcher: gradio_event_dispatcher
196
- });
197
-
198
187
  let api_calls: Payload[] = $state([]);
199
188
  let last_api_call: Payload | null = $state(null);
200
189
  // We need a callback to add to api_calls from the DependencyManager
@@ -206,6 +195,35 @@
206
195
  api_calls = [...api_calls, last_api_call];
207
196
  };
208
197
 
198
+ function handle_connection_lost(): void {
199
+ messages = messages.filter((m) => m.type !== "error");
200
+
201
+ ++_error_id;
202
+ messages.push({
203
+ title: "Connection Lost",
204
+ message: LOST_CONNECTION_MESSAGE,
205
+ fn_index: -1,
206
+ type: "error",
207
+ id: _error_id,
208
+ duration: null,
209
+ visible: true
210
+ });
211
+
212
+ reconnect_interval = setInterval(async () => {
213
+ try {
214
+ const status = await app.reconnect();
215
+ if (status === "connected" || status === "changed") {
216
+ clearInterval(reconnect_interval!);
217
+ reconnect_interval = null;
218
+ window.location.reload();
219
+ }
220
+ } catch (e) {
221
+ // server still unreachable
222
+ console.debug(e);
223
+ }
224
+ }, 2000);
225
+ }
226
+
209
227
  let dep_manager = new DependencyManager(
210
228
  dependencies,
211
229
  app,
@@ -213,7 +231,8 @@
213
231
  app_tree.get_state.bind(app_tree),
214
232
  app_tree.rerender.bind(app_tree),
215
233
  new_message,
216
- add_to_api_calls
234
+ add_to_api_calls,
235
+ handle_connection_lost
217
236
  );
218
237
 
219
238
  $effect(() => {
@@ -225,7 +244,8 @@
225
244
  version,
226
245
  api_prefix,
227
246
  max_file_size,
228
- autoscroll
247
+ autoscroll,
248
+ fill_height
229
249
  });
230
250
  dep_manager.reload(
231
251
  dependencies,
@@ -426,6 +446,7 @@
426
446
  return () => {
427
447
  mut.disconnect();
428
448
  res.disconnect();
449
+ if (reconnect_interval) clearInterval(reconnect_interval);
429
450
  };
430
451
  });
431
452
 
@@ -1,12 +1,13 @@
1
1
  <script lang="ts">
2
2
  import Self from "./MountComponents.svelte";
3
- let { node } = $props();
3
+ import MountCustomComponent from "./MountCustomComponent.svelte";
4
+ let { node, ...rest } = $props();
4
5
 
5
6
  let component = $derived(await node.component);
6
7
  </script>
7
8
 
8
9
  {#if node && component}
9
- {#if node.props.shared_props.visible}
10
+ {#if node.props.shared_props.visible && !node.runtime}
10
11
  <svelte:component
11
12
  this={component.default}
12
13
  shared_props={node.props.shared_props}
@@ -18,5 +19,13 @@
18
19
  {/each}
19
20
  {/if}
20
21
  </svelte:component>
22
+ {:else if node.props.shared_props.visible && node.runtime}
23
+ <MountCustomComponent {...rest} {node}>
24
+ {#if node.children && node.children.length}
25
+ {#each node.children as _node}
26
+ <Self node={_node} />
27
+ {/each}
28
+ {/if}
29
+ </MountCustomComponent>
21
30
  {/if}
22
31
  {/if}