@gradio/core 0.22.0 → 0.23.1

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/dist/src/init.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { writable, get } from "svelte/store";
2
+ import { dequal } from "dequal";
2
3
  import { load_component } from "virtual:component-loader";
3
4
  import { create_loading_status_store } from "./stores";
4
5
  import { _ } from "svelte-i18n";
@@ -11,8 +12,9 @@ const raf = is_browser
11
12
  * Create a store with the layout and a map of targets
12
13
  * @returns A store with the layout and a map of targets
13
14
  */
14
- let has_run = new Set();
15
- export function create_components(initial_layout) {
15
+ export function create_components({ initial_layout = undefined } = {
16
+ initial_layout: undefined
17
+ }) {
16
18
  let _component_map;
17
19
  let target_map = writable({});
18
20
  let _target_map = {};
@@ -26,6 +28,10 @@ export function create_components(initial_layout) {
26
28
  let app;
27
29
  let keys_per_render_id = {};
28
30
  let _rootNode;
31
+ let value_change_cb = null;
32
+ function value_change(cb) {
33
+ value_change_cb = cb;
34
+ }
29
35
  // Store current layout and root for dynamic visibility recalculation
30
36
  let current_layout;
31
37
  let current_root;
@@ -48,8 +54,12 @@ export function create_components(initial_layout) {
48
54
  if (instance_map) {
49
55
  // re-render in reload mode
50
56
  components.forEach((c) => {
51
- if (c.props.value == null && c.id in instance_map) {
52
- c.props.value = instance_map[c.id].props.value;
57
+ if (c.props.value == null && c.key) {
58
+ // If the component has a key, we preserve its value by finding a matching instance with the same key
59
+ const matching_instance = Object.values(instance_map).find((instance) => instance.key === c.key);
60
+ if (matching_instance) {
61
+ c.props.value = matching_instance.props.value;
62
+ }
53
63
  }
54
64
  });
55
65
  }
@@ -178,17 +188,11 @@ export function create_components(initial_layout) {
178
188
  if (!instance.component) {
179
189
  const constructor_key = instance.component_class_id || instance.type;
180
190
  let component_constructor = constructor_map.get(constructor_key);
181
- // Only load component if it was preloaded (i.e., it's visible)
182
191
  if (component_constructor) {
183
192
  instance.component = (await component_constructor)?.default;
184
193
  }
185
- // If component wasn't preloaded, leave it unloaded for now
186
- // It will be loaded later when/if it becomes visible
187
194
  }
188
195
  instance.parent = parent;
189
- // if (instance.type === "timer") {
190
- // console.log("timer", instance, constructor_map);
191
- // }
192
196
  if (instance.type === "dataset") {
193
197
  instance.props.component_map = get_component(instance.type, instance.component_class_id, root, components, instance.props.components).example_components;
194
198
  }
@@ -300,6 +304,7 @@ export function create_components(initial_layout) {
300
304
  if (!instance)
301
305
  continue;
302
306
  let new_value;
307
+ const old_value = instance.props[update.prop];
303
308
  if (update.value instanceof Map)
304
309
  new_value = new Map(update.value);
305
310
  else if (update.value instanceof Set)
@@ -313,6 +318,11 @@ export function create_components(initial_layout) {
313
318
  else
314
319
  new_value = update.value;
315
320
  instance.props[update.prop] = new_value;
321
+ if (update.prop === "value" &&
322
+ !is_visible(instance) &&
323
+ !dequal(old_value, new_value)) {
324
+ value_change_cb?.(update.id, new_value);
325
+ }
316
326
  }
317
327
  }
318
328
  return layout;
@@ -407,7 +417,8 @@ export function create_components(initial_layout) {
407
417
  loading_status,
408
418
  scheduled_updates: update_scheduled_store,
409
419
  create_layout: create_layout,
410
- rerender_layout
420
+ rerender_layout,
421
+ value_change
411
422
  };
412
423
  }
413
424
  /** An async version of 'new Function' */
@@ -721,3 +732,13 @@ export function preload_all_components(components, root) {
721
732
  });
722
733
  return constructor_map;
723
734
  }
735
+ function is_visible(component) {
736
+ if (typeof component.props.visible === "boolean" &&
737
+ component.props.visible === false) {
738
+ return false;
739
+ }
740
+ else if (component.parent) {
741
+ return is_visible(component.parent);
742
+ }
743
+ return true;
744
+ }
package/package.json CHANGED
@@ -1,67 +1,67 @@
1
1
  {
2
2
  "name": "@gradio/core",
3
- "version": "0.22.0",
3
+ "version": "0.23.1",
4
4
  "type": "module",
5
5
  "devDependencies": {
6
- "@gradio/accordion": "^0.5.19",
6
+ "@gradio/accordion": "^0.5.20",
7
+ "@gradio/annotatedimage": "^0.9.25",
7
8
  "@gradio/atoms": "^0.16.3",
8
- "@gradio/audio": "^0.17.20",
9
+ "@gradio/audio": "^0.17.21",
9
10
  "@gradio/box": "^0.2.21",
10
- "@gradio/annotatedimage": "^0.9.24",
11
- "@gradio/button": "^0.5.6",
12
- "@gradio/chatbot": "^0.26.17",
13
- "@gradio/checkboxgroup": "^0.6.24",
14
- "@gradio/checkbox": "^0.4.25",
15
- "@gradio/code": "^0.14.10",
16
- "@gradio/client": "^1.15.5",
17
- "@gradio/colorpicker": "^0.4.24",
11
+ "@gradio/browserstate": "^0.3.2",
12
+ "@gradio/button": "^0.5.7",
13
+ "@gradio/chatbot": "^0.26.18",
14
+ "@gradio/checkbox": "^0.4.26",
15
+ "@gradio/client": "^1.15.6",
16
+ "@gradio/code": "^0.14.11",
17
+ "@gradio/colorpicker": "^0.4.25",
18
18
  "@gradio/column": "^0.2.1",
19
- "@gradio/dataframe": "^0.18.2",
20
- "@gradio/dataset": "^0.4.26",
21
- "@gradio/datetime": "^0.3.17",
22
- "@gradio/downloadbutton": "^0.4.6",
23
- "@gradio/dropdown": "^0.9.24",
24
- "@gradio/fallback": "^0.4.24",
25
- "@gradio/fileexplorer": "^0.5.34",
19
+ "@gradio/dataframe": "^0.18.3",
20
+ "@gradio/checkboxgroup": "^0.6.25",
21
+ "@gradio/dataset": "^0.4.27",
22
+ "@gradio/downloadbutton": "^0.4.7",
23
+ "@gradio/datetime": "^0.3.18",
24
+ "@gradio/dropdown": "^0.9.25",
25
+ "@gradio/fallback": "^0.4.25",
26
+ "@gradio/file": "^0.12.24",
26
27
  "@gradio/form": "^0.2.21",
27
- "@gradio/gallery": "^0.15.26",
28
- "@gradio/file": "^0.12.23",
28
+ "@gradio/fileexplorer": "^0.5.35",
29
+ "@gradio/gallery": "^0.15.27",
29
30
  "@gradio/group": "^0.2.0",
30
- "@gradio/highlightedtext": "^0.9.7",
31
+ "@gradio/highlightedtext": "^0.9.8",
31
32
  "@gradio/icons": "^0.12.0",
32
- "@gradio/image": "^0.22.12",
33
- "@gradio/html": "^0.6.16",
34
- "@gradio/imageeditor": "^0.16.0",
35
- "@gradio/imageslider": "^0.2.8",
36
- "@gradio/label": "^0.5.16",
37
- "@gradio/browserstate": "^0.3.2",
38
- "@gradio/json": "^0.5.26",
39
- "@gradio/markdown": "^0.13.17",
40
- "@gradio/model3d": "^0.14.19",
41
- "@gradio/nativeplot": "^0.7.1",
42
- "@gradio/multimodaltextbox": "^0.10.12",
43
- "@gradio/number": "^0.6.1",
44
- "@gradio/paramviewer": "^0.7.12",
45
- "@gradio/plot": "^0.9.19",
46
- "@gradio/radio": "^0.7.7",
33
+ "@gradio/html": "^0.6.17",
34
+ "@gradio/image": "^0.22.13",
35
+ "@gradio/imageeditor": "^0.16.1",
36
+ "@gradio/imageslider": "^0.2.9",
37
+ "@gradio/label": "^0.5.17",
38
+ "@gradio/json": "^0.5.27",
39
+ "@gradio/markdown": "^0.13.18",
40
+ "@gradio/model3d": "^0.14.21",
41
+ "@gradio/multimodaltextbox": "^0.10.13",
42
+ "@gradio/nativeplot": "^0.7.2",
43
+ "@gradio/paramviewer": "^0.7.13",
44
+ "@gradio/number": "^0.6.2",
45
+ "@gradio/plot": "^0.9.20",
46
+ "@gradio/radio": "^0.7.8",
47
+ "@gradio/sidebar": "^0.1.18",
48
+ "@gradio/simpledropdown": "^0.3.25",
49
+ "@gradio/simpleimage": "^0.8.35",
50
+ "@gradio/simpletextbox": "^0.3.26",
47
51
  "@gradio/row": "^0.2.1",
48
- "@gradio/sidebar": "^0.1.17",
49
- "@gradio/simpledropdown": "^0.3.24",
50
- "@gradio/simpleimage": "^0.8.34",
51
- "@gradio/simpletextbox": "^0.3.25",
52
- "@gradio/sketchbox": "^0.6.12",
52
+ "@gradio/sketchbox": "^0.6.13",
53
+ "@gradio/slider": "^0.6.14",
54
+ "@gradio/statustracker": "^0.10.15",
53
55
  "@gradio/state": "^0.1.2",
54
- "@gradio/slider": "^0.6.13",
55
- "@gradio/statustracker": "^0.10.14",
56
56
  "@gradio/tabitem": "^0.5.0",
57
57
  "@gradio/tabs": "^0.4.5",
58
- "@gradio/textbox": "^0.10.16",
58
+ "@gradio/textbox": "^0.10.17",
59
59
  "@gradio/theme": "^0.4.0",
60
60
  "@gradio/timer": "^0.4.5",
61
- "@gradio/upload": "^0.16.10",
62
- "@gradio/uploadbutton": "^0.9.6",
61
+ "@gradio/upload": "^0.16.11",
63
62
  "@gradio/utils": "^0.10.2",
64
- "@gradio/video": "^0.14.20",
63
+ "@gradio/video": "^0.14.21",
64
+ "@gradio/uploadbutton": "^0.9.7",
65
65
  "@gradio/wasm": "^0.18.1"
66
66
  },
67
67
  "msw": {
@@ -94,5 +94,8 @@
94
94
  "type": "git",
95
95
  "url": "git+https://github.com/gradio-app/gradio.git",
96
96
  "directory": "js/core"
97
+ },
98
+ "dependencies": {
99
+ "dequal": "^2.0.2"
97
100
  }
98
101
  }
package/src/Blocks.svelte CHANGED
@@ -56,6 +56,7 @@
56
56
  export let max_file_size: number | undefined = undefined;
57
57
  export let initial_layout: ComponentMeta | undefined = undefined;
58
58
  export let css: string | null | undefined = null;
59
+ let broken_connection = false;
59
60
 
60
61
  let {
61
62
  layout: _layout,
@@ -68,8 +69,11 @@
68
69
  loading_status,
69
70
  scheduled_updates,
70
71
  create_layout,
71
- rerender_layout
72
- } = create_components(initial_layout);
72
+ rerender_layout,
73
+ value_change
74
+ } = create_components({
75
+ initial_layout
76
+ });
73
77
 
74
78
  $: components, layout, dependencies, root, app, fill_height, target, run();
75
79
 
@@ -275,13 +279,17 @@
275
279
 
276
280
  let _error_id = -1;
277
281
 
278
- let user_left_page = false;
279
-
280
282
  const MESSAGE_QUOTE_RE = /^'([^]+)'$/;
281
283
 
282
284
  const DUPLICATE_MESSAGE = $_("blocks.long_requests_queue");
283
285
  const MOBILE_QUEUE_WARNING = $_("blocks.connection_can_break");
284
- const MOBILE_RECONNECT_MESSAGE = $_("blocks.lost_connection");
286
+ const LOST_CONNECTION_MESSAGE =
287
+ "Connection to the server was lost. Attempting reconnection...";
288
+ const CHANGED_CONNECTION_MESSAGE =
289
+ "Reconnected to server, but the server has changed. You may need to <a href=''>refresh the page</a>.";
290
+ const RECONNECTION_MESSAGE = "Connection re-established.";
291
+ const SESSION_NOT_FOUND_MESSAGE =
292
+ "Session not found - this is likely because the machine you were connected to has changed. <a href=''>Refresh the page</a> to continue.";
285
293
  const WAITING_FOR_INPUTS_MESSAGE = $_("blocks.waiting_for_inputs");
286
294
  const SHOW_DUPLICATE_MESSAGE_ON_ETA = 15;
287
295
  const SHOW_MOBILE_QUEUE_WARNING_ON_ETA = 10;
@@ -424,6 +432,43 @@
424
432
  }
425
433
  }
426
434
 
435
+ async function reconnect(): Promise<void> {
436
+ const connection_status = await app.reconnect();
437
+ if (connection_status === "broken") {
438
+ setTimeout(reconnect, 1000);
439
+ } else if (connection_status === "changed") {
440
+ broken_connection = false;
441
+ messages = [
442
+ new_message(
443
+ "Changed Connection",
444
+ CHANGED_CONNECTION_MESSAGE,
445
+ -1,
446
+ "info",
447
+ 3,
448
+ true
449
+ ),
450
+ ...messages.map((m) =>
451
+ m.message === LOST_CONNECTION_MESSAGE ? { ...m, visible: false } : m
452
+ )
453
+ ];
454
+ } else if (connection_status === "connected") {
455
+ broken_connection = false;
456
+ messages = [
457
+ new_message(
458
+ "Reconnected",
459
+ RECONNECTION_MESSAGE,
460
+ -1,
461
+ "success",
462
+ null,
463
+ true
464
+ ),
465
+ ...messages.map((m) =>
466
+ m.message === LOST_CONNECTION_MESSAGE ? { ...m, visible: false } : m
467
+ )
468
+ ];
469
+ }
470
+ }
471
+
427
472
  async function make_prediction(
428
473
  payload: Payload,
429
474
  streaming = false
@@ -567,6 +612,35 @@
567
612
 
568
613
  /* eslint-disable complexity */
569
614
  function handle_status_update(message: StatusMessage): void {
615
+ if (message.broken && !broken_connection) {
616
+ messages = [
617
+ new_message(
618
+ "Broken Connection",
619
+ LOST_CONNECTION_MESSAGE,
620
+ -1,
621
+ "error",
622
+ null,
623
+ true
624
+ ),
625
+ ...messages
626
+ ];
627
+
628
+ broken_connection = true;
629
+ setTimeout(reconnect, 1000);
630
+ }
631
+ if (message.session_not_found) {
632
+ messages = [
633
+ new_message(
634
+ "Session Not Found",
635
+ SESSION_NOT_FOUND_MESSAGE,
636
+ -1,
637
+ "error",
638
+ null,
639
+ true
640
+ ),
641
+ ...messages
642
+ ];
643
+ }
570
644
  const { fn_index, ...status } = message;
571
645
  if (status.stage === "streaming" && status.time_limit) {
572
646
  dep.inputs.forEach((id) => {
@@ -636,16 +710,11 @@
636
710
  });
637
711
  submit_map.delete(dep_index);
638
712
  }
639
- if (status.broken && is_mobile_device && user_left_page) {
640
- window.setTimeout(() => {
641
- messages = [
642
- new_message("Error", MOBILE_RECONNECT_MESSAGE, fn_index, "error"),
643
- ...messages
644
- ];
645
- }, 0);
646
- wait_then_trigger_api_call(dep.id, payload.trigger_id, event_data);
647
- user_left_page = false;
648
- } else if (status.stage === "error") {
713
+ if (
714
+ status.stage === "error" &&
715
+ !broken_connection &&
716
+ !message.session_not_found
717
+ ) {
649
718
  if (status.message) {
650
719
  const _message = status.message.replace(
651
720
  MESSAGE_QUOTE_RE,
@@ -779,6 +848,16 @@
779
848
  render_complete = true;
780
849
  }
781
850
 
851
+ value_change((id, value) => {
852
+ const deps = $targets[id]?.["change"];
853
+
854
+ deps?.forEach((dep_id) => {
855
+ requestAnimationFrame(() => {
856
+ wait_then_trigger_api_call(dep_id, id, value);
857
+ });
858
+ });
859
+ });
860
+
782
861
  const handle_load_triggers = (): void => {
783
862
  dependencies.forEach((dep) => {
784
863
  if (dep.targets.some((dep) => dep[1] === "load")) {
@@ -851,12 +930,6 @@
851
930
  let is_screen_recording = writable(false);
852
931
 
853
932
  onMount(() => {
854
- document.addEventListener("visibilitychange", function () {
855
- if (document.visibilityState === "hidden") {
856
- user_left_page = true;
857
- }
858
- });
859
-
860
933
  is_mobile_device =
861
934
  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
862
935
  navigator.userAgent
@@ -81,6 +81,7 @@
81
81
  {elem_id}
82
82
  {elem_classes}
83
83
  {target}
84
+ {visible}
84
85
  {...$$restProps}
85
86
  {theme_mode}
86
87
  {root}