@gradio/core 1.0.0-dev.3 → 1.0.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/CHANGELOG.md +43 -0
- package/dist/src/Blocks.svelte +25 -10
- package/dist/src/Blocks.svelte.d.ts +2 -1
- package/dist/src/Login.svelte +13 -13
- package/dist/src/Login.svelte.d.ts +1 -0
- package/dist/src/api_docs/ApiDocs.svelte +19 -2
- package/dist/src/api_docs/ApiDocs.svelte.d.ts +1 -0
- package/dist/src/api_docs/ApiRecorder.svelte +0 -3
- package/dist/src/api_docs/CodeSnippet.svelte +63 -19
- package/dist/src/api_docs/CodeSnippet.svelte.d.ts +2 -1
- package/dist/src/api_docs/EndpointDetail.svelte +73 -17
- package/dist/src/api_docs/EndpointDetail.svelte.d.ts +3 -0
- package/dist/src/api_docs/MCPSnippet.svelte +21 -28
- package/dist/src/api_docs/MCPSnippet.svelte.d.ts +1 -0
- package/dist/src/api_docs/PercentileChart.svelte +125 -0
- package/dist/src/api_docs/PercentileChart.svelte.d.ts +22 -0
- package/dist/src/dependency.d.ts +14 -7
- package/dist/src/dependency.js +37 -19
- package/dist/src/init.svelte.d.ts +2 -2
- package/dist/src/init.svelte.js +26 -20
- package/dist/src/types.d.ts +2 -0
- package/package.json +60 -61
- package/src/Blocks.svelte +25 -10
- package/src/Login.svelte +13 -13
- package/src/api_docs/ApiDocs.svelte +19 -2
- package/src/api_docs/ApiRecorder.svelte +0 -3
- package/src/api_docs/CodeSnippet.svelte +63 -19
- package/src/api_docs/EndpointDetail.svelte +73 -17
- package/src/api_docs/MCPSnippet.svelte +21 -28
- package/src/api_docs/PercentileChart.svelte +125 -0
- package/src/dependency.ts +116 -72
- package/src/init.svelte.ts +24 -35
- package/src/types.ts +2 -0
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
import CopyButton from "./CopyButton.svelte";
|
|
4
4
|
import { Tool, Prompt, Resource } from "@gradio/icons";
|
|
5
5
|
import { format_latency, get_color_from_success_rate } from "./utils";
|
|
6
|
+
import PercentileChart from "./PercentileChart.svelte";
|
|
6
7
|
|
|
7
8
|
export let mcp_server_active: boolean;
|
|
8
9
|
export let mcp_server_url_streamable: string;
|
|
10
|
+
export let root: string;
|
|
9
11
|
export let tools: Tool[];
|
|
10
12
|
export let all_tools: Tool[] = [];
|
|
11
13
|
export let selected_tools: Set<string> = new Set();
|
|
@@ -69,7 +71,7 @@
|
|
|
69
71
|
"gradio[mcp]",
|
|
70
72
|
"gradio",
|
|
71
73
|
"upload-mcp",
|
|
72
|
-
|
|
74
|
+
root,
|
|
73
75
|
"<UPLOAD_DIRECTORY>"
|
|
74
76
|
]
|
|
75
77
|
};
|
|
@@ -218,34 +220,19 @@
|
|
|
218
220
|
: "⚠︎ No description provided in function docstring"}
|
|
219
221
|
</span>
|
|
220
222
|
{#if analytics[tool.meta.endpoint_name]}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
>
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
>({Math.round(success_rate * 100)}% successful)</span
|
|
223
|
+
{@const endpoint_analytics = analytics[tool.meta.endpoint_name]}
|
|
224
|
+
{@const p50 =
|
|
225
|
+
endpoint_analytics.process_time_percentiles["50th"]}
|
|
226
|
+
<div class="tool-analytics-wrapper" style="margin-left: 1em;">
|
|
227
|
+
<span
|
|
228
|
+
class="tool-analytics"
|
|
229
|
+
style="color: var(--body-text-color-subdued);"
|
|
229
230
|
>
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
)}
|
|
236
|
-
/
|
|
237
|
-
{format_latency(
|
|
238
|
-
analytics[tool.meta.endpoint_name].process_time_percentiles[
|
|
239
|
-
"90th"
|
|
240
|
-
]
|
|
241
|
-
)}
|
|
242
|
-
/
|
|
243
|
-
{format_latency(
|
|
244
|
-
analytics[tool.meta.endpoint_name].process_time_percentiles[
|
|
245
|
-
"99th"
|
|
246
|
-
]
|
|
247
|
-
)}
|
|
248
|
-
</span>
|
|
231
|
+
{endpoint_analytics.total_requests} requests ({Math.round(
|
|
232
|
+
success_rate * 100
|
|
233
|
+
)}% successful, p50: {format_latency(p50)})
|
|
234
|
+
</span>
|
|
235
|
+
</div>
|
|
249
236
|
{/if}
|
|
250
237
|
</span>
|
|
251
238
|
<span class="tool-arrow">{tool.expanded ? "▼" : "▶"}</span>
|
|
@@ -354,10 +341,16 @@
|
|
|
354
341
|
{/if}
|
|
355
342
|
|
|
356
343
|
<style>
|
|
344
|
+
.tool-analytics-wrapper {
|
|
345
|
+
position: relative;
|
|
346
|
+
display: inline-block;
|
|
347
|
+
}
|
|
348
|
+
|
|
357
349
|
.tool-analytics {
|
|
358
350
|
font-size: 0.95em;
|
|
359
351
|
color: var(--body-text-color-subdued);
|
|
360
352
|
}
|
|
353
|
+
|
|
361
354
|
.transport-selection {
|
|
362
355
|
margin-bottom: var(--size-4);
|
|
363
356
|
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { format_latency } from "./utils";
|
|
3
|
+
|
|
4
|
+
export let p50: number;
|
|
5
|
+
export let p90: number;
|
|
6
|
+
export let p99: number;
|
|
7
|
+
|
|
8
|
+
$: max_latency = Math.max(p50, p90, p99);
|
|
9
|
+
</script>
|
|
10
|
+
|
|
11
|
+
<div class="tooltip-chart">
|
|
12
|
+
<div class="tooltip-arrow"></div>
|
|
13
|
+
<div class="chart-bars">
|
|
14
|
+
<div class="chart-bar-container">
|
|
15
|
+
<div class="chart-bar-label">p50</div>
|
|
16
|
+
<div class="chart-bar-wrapper">
|
|
17
|
+
<div
|
|
18
|
+
class="chart-bar"
|
|
19
|
+
style="width: {(p50 / max_latency) * 100}%"
|
|
20
|
+
></div>
|
|
21
|
+
</div>
|
|
22
|
+
<div class="chart-bar-value">{format_latency(p50)}</div>
|
|
23
|
+
</div>
|
|
24
|
+
<div class="chart-bar-container">
|
|
25
|
+
<div class="chart-bar-label">p90</div>
|
|
26
|
+
<div class="chart-bar-wrapper">
|
|
27
|
+
<div
|
|
28
|
+
class="chart-bar"
|
|
29
|
+
style="width: {(p90 / max_latency) * 100}%"
|
|
30
|
+
></div>
|
|
31
|
+
</div>
|
|
32
|
+
<div class="chart-bar-value">{format_latency(p90)}</div>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="chart-bar-container">
|
|
35
|
+
<div class="chart-bar-label">p99</div>
|
|
36
|
+
<div class="chart-bar-wrapper">
|
|
37
|
+
<div
|
|
38
|
+
class="chart-bar"
|
|
39
|
+
style="width: {(p99 / max_latency) * 100}%"
|
|
40
|
+
></div>
|
|
41
|
+
</div>
|
|
42
|
+
<div class="chart-bar-value">{format_latency(p99)}</div>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<style>
|
|
48
|
+
.tooltip-chart {
|
|
49
|
+
background: var(--background-fill-primary);
|
|
50
|
+
border: 1px solid var(--border-color-primary);
|
|
51
|
+
border-radius: var(--radius-md);
|
|
52
|
+
padding: var(--size-3);
|
|
53
|
+
box-shadow: var(--shadow-drop-lg);
|
|
54
|
+
min-width: 200px;
|
|
55
|
+
position: relative;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.tooltip-arrow {
|
|
59
|
+
position: absolute;
|
|
60
|
+
bottom: -8px;
|
|
61
|
+
left: 50%;
|
|
62
|
+
transform: translateX(-50%);
|
|
63
|
+
width: 0;
|
|
64
|
+
height: 0;
|
|
65
|
+
border-left: 8px solid transparent;
|
|
66
|
+
border-right: 8px solid transparent;
|
|
67
|
+
border-top: 8px solid var(--border-color-primary);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.tooltip-arrow::after {
|
|
71
|
+
content: "";
|
|
72
|
+
position: absolute;
|
|
73
|
+
bottom: 1px;
|
|
74
|
+
left: 50%;
|
|
75
|
+
transform: translateX(-50%);
|
|
76
|
+
width: 0;
|
|
77
|
+
height: 0;
|
|
78
|
+
border-left: 7px solid transparent;
|
|
79
|
+
border-right: 7px solid transparent;
|
|
80
|
+
border-top: 7px solid var(--background-fill-primary);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.chart-bars {
|
|
84
|
+
display: flex;
|
|
85
|
+
flex-direction: column;
|
|
86
|
+
gap: var(--size-2);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.chart-bar-container {
|
|
90
|
+
display: flex;
|
|
91
|
+
align-items: center;
|
|
92
|
+
gap: var(--size-2);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.chart-bar-label {
|
|
96
|
+
font-size: var(--text-sm);
|
|
97
|
+
font-weight: var(--weight-semibold);
|
|
98
|
+
color: var(--body-text-color);
|
|
99
|
+
min-width: 30px;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.chart-bar-wrapper {
|
|
103
|
+
flex: 1;
|
|
104
|
+
height: 16px;
|
|
105
|
+
background: var(--background-fill-secondary);
|
|
106
|
+
border-radius: var(--radius-sm);
|
|
107
|
+
overflow: hidden;
|
|
108
|
+
position: relative;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.chart-bar {
|
|
112
|
+
height: 100%;
|
|
113
|
+
background: var(--color-accent);
|
|
114
|
+
border-radius: var(--radius-sm);
|
|
115
|
+
transition: width 0.3s ease;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.chart-bar-value {
|
|
119
|
+
font-size: var(--text-sm);
|
|
120
|
+
color: var(--body-text-color);
|
|
121
|
+
min-width: 50px;
|
|
122
|
+
text-align: right;
|
|
123
|
+
font-family: var(--font-mono);
|
|
124
|
+
}
|
|
125
|
+
</style>
|
package/src/dependency.ts
CHANGED
|
@@ -9,7 +9,11 @@ import { AsyncFunction } from "./init_utils";
|
|
|
9
9
|
import { Client, type client_return } from "@gradio/client";
|
|
10
10
|
import { LoadingStatus, type LoadingStatusArgs } from "@gradio/statustracker";
|
|
11
11
|
import type { ToastMessage } from "@gradio/statustracker";
|
|
12
|
-
import type {
|
|
12
|
+
import type {
|
|
13
|
+
StatusMessage,
|
|
14
|
+
ValidationError,
|
|
15
|
+
LogMessage
|
|
16
|
+
} from "@gradio/client";
|
|
13
17
|
const MESSAGE_QUOTE_RE = /^'([^]+)'$/;
|
|
14
18
|
|
|
15
19
|
const NOVALUE = Symbol("NOVALUE");
|
|
@@ -36,6 +40,8 @@ export class Dependency {
|
|
|
36
40
|
// in the case of chained events, it would be the id of the initial trigger
|
|
37
41
|
original_trigger_id: number | null = null;
|
|
38
42
|
show_progress_on: number[] | null = null;
|
|
43
|
+
component_prop_inputs: number[] = [];
|
|
44
|
+
show_progress: "full" | "minimal" | "hidden";
|
|
39
45
|
|
|
40
46
|
functions: {
|
|
41
47
|
frontend?: (...args: unknown[]) => Promise<unknown[]>;
|
|
@@ -49,6 +55,7 @@ export class Dependency {
|
|
|
49
55
|
this.inputs = dep_config.inputs;
|
|
50
56
|
this.outputs = dep_config.outputs;
|
|
51
57
|
this.connection_type = dep_config.connection;
|
|
58
|
+
this.show_progress = dep_config.show_progress;
|
|
52
59
|
this.functions = {
|
|
53
60
|
frontend: dep_config.js
|
|
54
61
|
? process_frontend_fn(
|
|
@@ -70,6 +77,7 @@ export class Dependency {
|
|
|
70
77
|
this.cancels = dep_config.cancels;
|
|
71
78
|
this.trigger_modes = dep_config.trigger_mode;
|
|
72
79
|
this.show_progress_on = dep_config.show_progress_on || null;
|
|
80
|
+
this.component_prop_inputs = dep_config.component_prop_inputs || [];
|
|
73
81
|
|
|
74
82
|
for (let i = 0; i < dep_config.event_specific_args?.length || 0; i++) {
|
|
75
83
|
const key = dep_config.event_specific_args[i];
|
|
@@ -146,6 +154,25 @@ interface DispatchEvent {
|
|
|
146
154
|
event_data: unknown;
|
|
147
155
|
}
|
|
148
156
|
|
|
157
|
+
type UpdateStateCallback = (
|
|
158
|
+
id: number,
|
|
159
|
+
state: Record<string, unknown>,
|
|
160
|
+
check_visibility?: boolean
|
|
161
|
+
) => Promise<void>;
|
|
162
|
+
type GetStateCallback = (id: number) => Promise<Record<string, unknown> | null>;
|
|
163
|
+
type RerenderCallback = (
|
|
164
|
+
components: ComponentMeta[],
|
|
165
|
+
layout: LayoutNode
|
|
166
|
+
) => void;
|
|
167
|
+
type LogCallback = (
|
|
168
|
+
title: string,
|
|
169
|
+
message: string,
|
|
170
|
+
fn_index: number,
|
|
171
|
+
type: ToastMessage["type"],
|
|
172
|
+
duration?: number | null,
|
|
173
|
+
visible?: boolean
|
|
174
|
+
) => void;
|
|
175
|
+
|
|
149
176
|
/**
|
|
150
177
|
* Manages all dependencies for an app acting as a bridge between app state and Dependencies
|
|
151
178
|
* Responsible for registering dependencies and dispatching events to them
|
|
@@ -167,21 +194,11 @@ export class DependencyManager {
|
|
|
167
194
|
queue: Set<number> = new Set();
|
|
168
195
|
add_to_api_calls: (payload: Payload) => void;
|
|
169
196
|
|
|
170
|
-
update_state_cb:
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
get_state_cb: (id: number) => Promise<Record<string, unknown> | null>;
|
|
176
|
-
rerender_cb: (components: ComponentMeta[], layout: LayoutNode) => void;
|
|
177
|
-
log_cb: (
|
|
178
|
-
title: string,
|
|
179
|
-
message: string,
|
|
180
|
-
fn_index: number,
|
|
181
|
-
type: ToastMessage["type"],
|
|
182
|
-
duration?: number | null,
|
|
183
|
-
visible?: boolean
|
|
184
|
-
) => void;
|
|
197
|
+
update_state_cb: UpdateStateCallback;
|
|
198
|
+
get_state_cb: GetStateCallback;
|
|
199
|
+
rerender_cb: RerenderCallback;
|
|
200
|
+
log_cb: LogCallback;
|
|
201
|
+
|
|
185
202
|
loading_stati = new LoadingStatus();
|
|
186
203
|
|
|
187
204
|
constructor(
|
|
@@ -205,33 +222,39 @@ export class DependencyManager {
|
|
|
205
222
|
add_to_api_calls: (payload: Payload) => void
|
|
206
223
|
) {
|
|
207
224
|
this.add_to_api_calls = add_to_api_calls;
|
|
208
|
-
this.client = client;
|
|
209
225
|
this.log_cb = log_cb;
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
this.
|
|
226
|
+
this.update_state_cb = update_state_cb;
|
|
227
|
+
this.get_state_cb = get_state_cb;
|
|
228
|
+
this.rerender_cb = rerender_cb;
|
|
229
|
+
this.client = client;
|
|
230
|
+
this.reload(
|
|
231
|
+
dependencies,
|
|
232
|
+
update_state_cb,
|
|
233
|
+
get_state_cb,
|
|
234
|
+
rerender_cb,
|
|
235
|
+
client
|
|
236
|
+
);
|
|
214
237
|
}
|
|
215
238
|
|
|
216
239
|
reload(
|
|
217
240
|
dependencies: IDependency[],
|
|
218
|
-
update_state,
|
|
219
|
-
get_state,
|
|
220
|
-
rerender,
|
|
221
|
-
client
|
|
241
|
+
update_state: UpdateStateCallback,
|
|
242
|
+
get_state: GetStateCallback,
|
|
243
|
+
rerender: RerenderCallback,
|
|
244
|
+
client: Client
|
|
222
245
|
) {
|
|
223
246
|
const { by_id, by_event } = this.create(dependencies);
|
|
224
247
|
this.dependencies_by_event = by_event;
|
|
225
248
|
this.dependencies_by_fn = by_id;
|
|
249
|
+
this.client = client;
|
|
250
|
+
this.update_state_cb = update_state;
|
|
251
|
+
this.get_state_cb = get_state;
|
|
252
|
+
this.rerender_cb = rerender;
|
|
226
253
|
for (const [dep_id, dep] of this.dependencies_by_fn) {
|
|
227
254
|
for (const [output_id] of dep.targets) {
|
|
228
255
|
this.set_event_args(output_id, dep.event_args);
|
|
229
256
|
}
|
|
230
257
|
}
|
|
231
|
-
this.client = client;
|
|
232
|
-
this.update_state_cb = update_state;
|
|
233
|
-
this.get_state_cb = get_state;
|
|
234
|
-
this.rerender_cb = rerender;
|
|
235
258
|
this.register_loading_stati(by_id);
|
|
236
259
|
}
|
|
237
260
|
register_loading_stati(deps: Map<number, Dependency>): void {
|
|
@@ -239,7 +262,8 @@ export class DependencyManager {
|
|
|
239
262
|
this.loading_stati.register(
|
|
240
263
|
dep.id,
|
|
241
264
|
dep.show_progress_on || dep.outputs,
|
|
242
|
-
dep.inputs
|
|
265
|
+
dep.inputs,
|
|
266
|
+
dep.show_progress
|
|
243
267
|
);
|
|
244
268
|
}
|
|
245
269
|
}
|
|
@@ -324,7 +348,10 @@ export class DependencyManager {
|
|
|
324
348
|
this.update_loading_stati_state();
|
|
325
349
|
}
|
|
326
350
|
|
|
327
|
-
const data_payload = await this.gather_state(
|
|
351
|
+
const data_payload = await this.gather_state(
|
|
352
|
+
dep.inputs,
|
|
353
|
+
dep.component_prop_inputs
|
|
354
|
+
);
|
|
328
355
|
const unset_args = await Promise.all(
|
|
329
356
|
dep.targets.map(([output_id]) =>
|
|
330
357
|
this.set_event_args(output_id, dep.event_args)
|
|
@@ -354,7 +381,7 @@ export class DependencyManager {
|
|
|
354
381
|
data: data_payload,
|
|
355
382
|
event_data: event_meta.event_data
|
|
356
383
|
};
|
|
357
|
-
submission!.send_chunk(payload);
|
|
384
|
+
submission!.send_chunk(payload as any);
|
|
358
385
|
unset_args.forEach((fn) => fn());
|
|
359
386
|
continue;
|
|
360
387
|
}
|
|
@@ -375,7 +402,7 @@ export class DependencyManager {
|
|
|
375
402
|
if (dep_submission.type === "void") {
|
|
376
403
|
unset_args.forEach((fn) => fn());
|
|
377
404
|
} else if (dep_submission.type === "data") {
|
|
378
|
-
this.handle_data(dep.outputs, dep_submission.data);
|
|
405
|
+
await this.handle_data(dep.outputs, dep_submission.data);
|
|
379
406
|
unset_args.forEach((fn) => fn());
|
|
380
407
|
} else {
|
|
381
408
|
let stream_state: "open" | "closed" | "waiting" | null = null;
|
|
@@ -408,7 +435,7 @@ export class DependencyManager {
|
|
|
408
435
|
index += 1;
|
|
409
436
|
if (result === null) continue;
|
|
410
437
|
if (result.type === "data") {
|
|
411
|
-
this.handle_data(dep.outputs, result.data);
|
|
438
|
+
await this.handle_data(dep.outputs, result.data);
|
|
412
439
|
}
|
|
413
440
|
if (result.type === "status") {
|
|
414
441
|
if (
|
|
@@ -495,8 +522,9 @@ export class DependencyManager {
|
|
|
495
522
|
(_, b) => b
|
|
496
523
|
);
|
|
497
524
|
this.log_cb(
|
|
498
|
-
|
|
499
|
-
|
|
525
|
+
//@ts-ignore
|
|
526
|
+
result?._title ?? "Error",
|
|
527
|
+
_message || "",
|
|
500
528
|
fn_index,
|
|
501
529
|
"error",
|
|
502
530
|
status.duration,
|
|
@@ -516,6 +544,12 @@ export class DependencyManager {
|
|
|
516
544
|
}
|
|
517
545
|
|
|
518
546
|
if (result.type === "render") {
|
|
547
|
+
this.loading_stati.update({
|
|
548
|
+
status: "complete",
|
|
549
|
+
fn_index: dep.id,
|
|
550
|
+
stream_state: null
|
|
551
|
+
});
|
|
552
|
+
this.update_loading_stati_state();
|
|
519
553
|
const { layout, components, render_id, dependencies } =
|
|
520
554
|
result.data;
|
|
521
555
|
|
|
@@ -660,52 +694,61 @@ export class DependencyManager {
|
|
|
660
694
|
* @param data the data to update the components with
|
|
661
695
|
* */
|
|
662
696
|
async handle_data(outputs: number[], data: unknown[]) {
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
697
|
+
await Promise.all(
|
|
698
|
+
outputs.map(async (output_id, i) => {
|
|
699
|
+
const _data = data[i] === undefined ? NOVALUE : data[i];
|
|
700
|
+
if (_data === NOVALUE) return;
|
|
701
|
+
|
|
702
|
+
if (is_prop_update(_data)) {
|
|
703
|
+
let pending_visibility_update = false;
|
|
704
|
+
let pending_visibility_value = null;
|
|
705
|
+
for (const [update_key, update_value] of Object.entries(_data)) {
|
|
706
|
+
if (update_key === "__type__") continue;
|
|
707
|
+
if (update_key === "visible") {
|
|
708
|
+
pending_visibility_update = true;
|
|
709
|
+
pending_visibility_value = update_value;
|
|
710
|
+
continue;
|
|
711
|
+
}
|
|
712
|
+
await this.update_state_cb(
|
|
713
|
+
outputs[i],
|
|
714
|
+
{
|
|
715
|
+
[update_key]: update_value
|
|
716
|
+
},
|
|
717
|
+
false
|
|
718
|
+
);
|
|
676
719
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
{
|
|
689
|
-
visible: pending_visibility_value
|
|
690
|
-
},
|
|
691
|
-
true
|
|
692
|
-
);
|
|
720
|
+
if (pending_visibility_update) {
|
|
721
|
+
await this.update_state_cb(
|
|
722
|
+
outputs[i],
|
|
723
|
+
{
|
|
724
|
+
visible: pending_visibility_value
|
|
725
|
+
},
|
|
726
|
+
true
|
|
727
|
+
);
|
|
728
|
+
}
|
|
729
|
+
} else {
|
|
730
|
+
await this.update_state_cb(output_id, { value: _data }, false);
|
|
693
731
|
}
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
}
|
|
697
|
-
});
|
|
732
|
+
})
|
|
733
|
+
);
|
|
698
734
|
}
|
|
699
735
|
|
|
700
736
|
/**
|
|
701
737
|
* Gathers the current state of the inputs
|
|
702
738
|
*
|
|
703
739
|
* @param ids the ids of the components to gather state from
|
|
740
|
+
* @param prop_indices the indices (relative to ids array) that should return all component props instead of just the value
|
|
704
741
|
* @returns an array of the current state of the components, in the same order as the ids
|
|
705
742
|
*/
|
|
706
|
-
async gather_state(
|
|
743
|
+
async gather_state(
|
|
744
|
+
ids: number[],
|
|
745
|
+
prop_indices: number[] = []
|
|
746
|
+
): Promise<(unknown | null)[]> {
|
|
707
747
|
return (await Promise.all(ids.map((id) => this.get_state_cb(id)))).map(
|
|
708
|
-
(state) => {
|
|
748
|
+
(state, index) => {
|
|
749
|
+
if (prop_indices.includes(index)) {
|
|
750
|
+
return state ?? null;
|
|
751
|
+
}
|
|
709
752
|
return state?.value ?? null;
|
|
710
753
|
}
|
|
711
754
|
);
|
|
@@ -722,7 +765,8 @@ export class DependencyManager {
|
|
|
722
765
|
args: Record<string, unknown>
|
|
723
766
|
): Promise<() => void> {
|
|
724
767
|
let current_args: Record<string, unknown> = {};
|
|
725
|
-
const current_state = await this.get_state_cb(id);
|
|
768
|
+
const current_state = await this.get_state_cb?.(id);
|
|
769
|
+
if (!current_state) return () => {};
|
|
726
770
|
for (const [key] of Object.entries(args)) {
|
|
727
771
|
current_args[key] = current_state?.[key] ?? null;
|
|
728
772
|
}
|