@gradio/core 1.2.0 → 1.3.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 +21 -0
- package/dist/src/Blocks.svelte +33 -1
- package/dist/src/api_docs/ApiBanner.svelte +6 -2
- package/dist/src/api_docs/ApiBanner.svelte.d.ts +1 -1
- package/dist/src/api_docs/ApiDocs.svelte +41 -25
- package/dist/src/api_docs/CodeSnippet.svelte +67 -170
- package/dist/src/api_docs/CodeSnippet.svelte.d.ts +2 -6
- package/dist/src/api_docs/CopyMarkdown.svelte +7 -2
- package/dist/src/api_docs/CopyMarkdown.svelte.d.ts +1 -1
- package/dist/src/api_docs/InstallSnippet.svelte +6 -1
- package/dist/src/api_docs/InstallSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/ParametersSnippet.svelte +6 -1
- package/dist/src/api_docs/ParametersSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/RecordingSnippet.svelte +6 -1
- package/dist/src/api_docs/RecordingSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/ResponseSnippet.svelte +6 -1
- package/dist/src/api_docs/ResponseSnippet.svelte.d.ts +1 -1
- package/dist/src/api_docs/SkillSnippet.svelte +125 -0
- package/dist/src/api_docs/SkillSnippet.svelte.d.ts +20 -0
- package/dist/src/api_docs/img/skill.svg +10 -0
- package/dist/src/api_docs/utils.d.ts +0 -1
- package/dist/src/api_docs/utils.js +0 -22
- package/dist/src/dependency.d.ts +3 -1
- package/dist/src/dependency.js +19 -1
- package/dist/src/init.svelte.js +81 -19
- package/package.json +22 -22
- package/src/Blocks.svelte +33 -1
- package/src/api_docs/ApiBanner.svelte +6 -2
- package/src/api_docs/ApiDocs.svelte +41 -25
- package/src/api_docs/CodeSnippet.svelte +67 -170
- package/src/api_docs/CopyMarkdown.svelte +7 -2
- package/src/api_docs/InstallSnippet.svelte +6 -1
- package/src/api_docs/ParametersSnippet.svelte +6 -1
- package/src/api_docs/RecordingSnippet.svelte +6 -1
- package/src/api_docs/ResponseSnippet.svelte +6 -1
- package/src/api_docs/SkillSnippet.svelte +125 -0
- package/src/api_docs/img/skill.svg +10 -0
- package/src/api_docs/utils.ts +0 -25
- package/src/dependency.ts +19 -1
- package/src/init.svelte.ts +95 -19
package/src/dependency.ts
CHANGED
|
@@ -205,8 +205,10 @@ export class DependencyManager {
|
|
|
205
205
|
get_state_cb: GetStateCallback;
|
|
206
206
|
rerender_cb: RerenderCallback;
|
|
207
207
|
log_cb: LogCallback;
|
|
208
|
+
on_connection_lost_cb: () => void;
|
|
208
209
|
|
|
209
210
|
loading_stati = new LoadingStatus();
|
|
211
|
+
connection_lost = false;
|
|
210
212
|
|
|
211
213
|
constructor(
|
|
212
214
|
dependencies: IDependency[],
|
|
@@ -226,13 +228,15 @@ export class DependencyManager {
|
|
|
226
228
|
duration?: number | null,
|
|
227
229
|
visible?: boolean
|
|
228
230
|
) => void,
|
|
229
|
-
add_to_api_calls: (payload: Payload) => void
|
|
231
|
+
add_to_api_calls: (payload: Payload) => void,
|
|
232
|
+
on_connection_lost_cb: () => void
|
|
230
233
|
) {
|
|
231
234
|
this.add_to_api_calls = add_to_api_calls;
|
|
232
235
|
this.log_cb = log_cb;
|
|
233
236
|
this.update_state_cb = update_state_cb;
|
|
234
237
|
this.get_state_cb = get_state_cb;
|
|
235
238
|
this.rerender_cb = rerender_cb;
|
|
239
|
+
this.on_connection_lost_cb = on_connection_lost_cb;
|
|
236
240
|
this.client = client;
|
|
237
241
|
this.reload(
|
|
238
242
|
dependencies,
|
|
@@ -318,6 +322,7 @@ export class DependencyManager {
|
|
|
318
322
|
* @returns a value if there is no backend fn, a 'submission' if there is a backend fn, or null if there is no dependency
|
|
319
323
|
*/
|
|
320
324
|
async dispatch(event_meta: DispatchFunction | DispatchEvent): Promise<void> {
|
|
325
|
+
if (this.connection_lost) return;
|
|
321
326
|
let deps: Dependency[] | undefined;
|
|
322
327
|
if (event_meta.type === "fn") {
|
|
323
328
|
const dep = this.dependencies_by_fn.get(event_meta.fn_index!);
|
|
@@ -484,6 +489,19 @@ export class DependencyManager {
|
|
|
484
489
|
});
|
|
485
490
|
this.update_loading_stati_state();
|
|
486
491
|
} else if (result.stage === "error") {
|
|
492
|
+
if (result.broken || result.session_not_found) {
|
|
493
|
+
if (!this.connection_lost) {
|
|
494
|
+
this.connection_lost = true;
|
|
495
|
+
this.on_connection_lost_cb();
|
|
496
|
+
}
|
|
497
|
+
this.loading_stati.update({
|
|
498
|
+
status: "complete",
|
|
499
|
+
fn_index: dep.id,
|
|
500
|
+
stream_state: null
|
|
501
|
+
});
|
|
502
|
+
this.update_loading_stati_state();
|
|
503
|
+
break submit_loop;
|
|
504
|
+
}
|
|
487
505
|
if (Array.isArray(result?.message)) {
|
|
488
506
|
result.message.forEach((m: ValidationError, i) => {
|
|
489
507
|
this.update_state_cb(
|
package/src/init.svelte.ts
CHANGED
|
@@ -67,6 +67,7 @@ export class AppTree {
|
|
|
67
67
|
|
|
68
68
|
#get_callbacks = new Map<number, get_data_type>();
|
|
69
69
|
#set_callbacks = new Map<number, set_data_type>();
|
|
70
|
+
#pending_updates = new Map<number, Record<string, unknown>>();
|
|
70
71
|
#event_dispatcher: (id: number, event: string, data: unknown) => void;
|
|
71
72
|
component_ids: number[];
|
|
72
73
|
initial_tabs: Record<number, Tab[]> = {};
|
|
@@ -195,6 +196,21 @@ export class AppTree {
|
|
|
195
196
|
this.#set_callbacks.set(id, _set_data);
|
|
196
197
|
this.#get_callbacks.set(id, _get_data);
|
|
197
198
|
this.components_to_register.delete(id);
|
|
199
|
+
|
|
200
|
+
// Apply any pending updates that were stored while the component
|
|
201
|
+
// was not yet mounted (e.g. hidden in an inactive tab).
|
|
202
|
+
// We must apply AFTER tick() so that the Gradio class's $effect
|
|
203
|
+
// (which syncs from node props) has already run. Otherwise the
|
|
204
|
+
// $effect would overwrite the values we set here.
|
|
205
|
+
const pending = this.#pending_updates.get(id);
|
|
206
|
+
if (pending) {
|
|
207
|
+
this.#pending_updates.delete(id);
|
|
208
|
+
tick().then(() => {
|
|
209
|
+
const _set = this.#set_callbacks.get(id);
|
|
210
|
+
if (_set) _set(pending);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
198
214
|
if (this.components_to_register.size === 0 && !this.resolved) {
|
|
199
215
|
this.resolved = true;
|
|
200
216
|
this.ready_resolve();
|
|
@@ -429,11 +445,24 @@ export class AppTree {
|
|
|
429
445
|
const old_value = node?.props.props.value;
|
|
430
446
|
// @ts-ignore
|
|
431
447
|
const new_props = create_props_shared_props(new_state);
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
448
|
+
// Modify props in-place instead of replacing the entire object.
|
|
449
|
+
// Replacing with a new object via spread can cause Svelte 5's
|
|
450
|
+
// deep $state proxy to lose track of the values during async
|
|
451
|
+
// component mounting/revival.
|
|
452
|
+
for (const key in new_props.shared_props) {
|
|
453
|
+
// @ts-ignore
|
|
454
|
+
node!.props.shared_props[key] = new_props.shared_props[key];
|
|
455
|
+
}
|
|
456
|
+
for (const key in new_props.props) {
|
|
457
|
+
// @ts-ignore
|
|
458
|
+
node!.props.props[key] = new_props.props[key];
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
// Also store as pending so the value can be applied via _set_data
|
|
462
|
+
// when the component eventually mounts and registers
|
|
463
|
+
const existing = this.#pending_updates.get(id) || {};
|
|
464
|
+
this.#pending_updates.set(id, { ...existing, ...new_state });
|
|
465
|
+
|
|
437
466
|
if ("value" in new_state && !dequal(old_value, new_state.value)) {
|
|
438
467
|
this.#event_dispatcher(id, "change", null);
|
|
439
468
|
}
|
|
@@ -469,28 +498,73 @@ export class AppTree {
|
|
|
469
498
|
}
|
|
470
499
|
|
|
471
500
|
async render_previously_invisible_children(id: number) {
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
(node)
|
|
480
|
-
|
|
501
|
+
const node = find_node_by_id(this.root!, id);
|
|
502
|
+
if (!node) return;
|
|
503
|
+
|
|
504
|
+
// Check if this node or any of its descendants need to be made visible.
|
|
505
|
+
// If not, skip entirely to avoid unnecessary reactive updates
|
|
506
|
+
// from mutating the tree through the $state proxy.
|
|
507
|
+
if (
|
|
508
|
+
!this.#hidden_on_startup.has(node.id) &&
|
|
509
|
+
!has_hidden_descendants(node, this.#hidden_on_startup)
|
|
510
|
+
) {
|
|
511
|
+
return;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
make_visible_if_not_rendered(node, this.#hidden_on_startup, true);
|
|
515
|
+
load_components(node, this.#config.api_url);
|
|
481
516
|
}
|
|
482
517
|
}
|
|
483
518
|
|
|
484
519
|
function make_visible_if_not_rendered(
|
|
485
520
|
node: ProcessedComponentMeta,
|
|
486
|
-
hidden_on_startup: Set<number
|
|
521
|
+
hidden_on_startup: Set<number>,
|
|
522
|
+
is_target_node = false
|
|
487
523
|
): void {
|
|
488
524
|
node.props.shared_props.visible = hidden_on_startup.has(node.id)
|
|
489
525
|
? true
|
|
490
526
|
: node.props.shared_props.visible;
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
527
|
+
|
|
528
|
+
if (node.type === "tabs") {
|
|
529
|
+
const selectedId =
|
|
530
|
+
node.props.props.selected ?? node.props.props.initial_tabs?.[0]?.id;
|
|
531
|
+
node.children.forEach((child) => {
|
|
532
|
+
if (
|
|
533
|
+
child.type === "tabitem" &&
|
|
534
|
+
(child.props.props.id === selectedId || child.id === selectedId)
|
|
535
|
+
) {
|
|
536
|
+
make_visible_if_not_rendered(child, hidden_on_startup, false);
|
|
537
|
+
}
|
|
538
|
+
});
|
|
539
|
+
} else if (
|
|
540
|
+
node.type === "accordion" &&
|
|
541
|
+
node.props.props.open === false &&
|
|
542
|
+
!is_target_node
|
|
543
|
+
) {
|
|
544
|
+
// Don't recurse into closed accordion content
|
|
545
|
+
} else {
|
|
546
|
+
node.children.forEach((child) => {
|
|
547
|
+
make_visible_if_not_rendered(child, hidden_on_startup, false);
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
function has_hidden_descendants(
|
|
553
|
+
node: ProcessedComponentMeta,
|
|
554
|
+
hidden_on_startup: Set<number>
|
|
555
|
+
): boolean {
|
|
556
|
+
for (const child of node.children) {
|
|
557
|
+
if (hidden_on_startup.has(child.id)) return true;
|
|
558
|
+
if (has_hidden_descendants(child, hidden_on_startup)) return true;
|
|
559
|
+
}
|
|
560
|
+
return false;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
function load_components(node: ProcessedComponentMeta, api_url: string): void {
|
|
564
|
+
if (node.props.shared_props.visible && !node.component) {
|
|
565
|
+
node.component = get_component(node.type, node.component_class_id, api_url);
|
|
566
|
+
}
|
|
567
|
+
node.children.forEach((child) => load_components(child, api_url));
|
|
494
568
|
}
|
|
495
569
|
|
|
496
570
|
/**
|
|
@@ -719,8 +793,10 @@ function _gather_initial_tabs(
|
|
|
719
793
|
if (!("id" in node.props.props)) {
|
|
720
794
|
node.props.props.id = node.id;
|
|
721
795
|
}
|
|
796
|
+
const i18n = node.props.props.i18n as ((str: string) => string) | undefined;
|
|
797
|
+
const raw_label = node.props.shared_props.label as string;
|
|
722
798
|
initial_tabs[parent_tab_id].push({
|
|
723
|
-
label:
|
|
799
|
+
label: i18n ? i18n(raw_label) : raw_label,
|
|
724
800
|
id: node.props.props.id as string,
|
|
725
801
|
elem_id: node.props.shared_props.elem_id,
|
|
726
802
|
visible: node.props.shared_props.visible as boolean,
|