@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
|
}
|
|
@@ -14,6 +14,7 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
|
|
|
14
14
|
declare const MCPSnippet: $$__sveltets_2_IsomorphicComponent<{
|
|
15
15
|
mcp_server_active: boolean;
|
|
16
16
|
mcp_server_url_streamable: string;
|
|
17
|
+
root: string;
|
|
17
18
|
tools: {
|
|
18
19
|
name: string;
|
|
19
20
|
description: string;
|
|
@@ -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>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
|
|
2
|
+
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
3
|
+
$$bindings?: Bindings;
|
|
4
|
+
} & Exports;
|
|
5
|
+
(internal: unknown, props: Props & {
|
|
6
|
+
$$events?: Events;
|
|
7
|
+
$$slots?: Slots;
|
|
8
|
+
}): Exports & {
|
|
9
|
+
$set?: any;
|
|
10
|
+
$on?: any;
|
|
11
|
+
};
|
|
12
|
+
z_$$bindings?: Bindings;
|
|
13
|
+
}
|
|
14
|
+
declare const PercentileChart: $$__sveltets_2_IsomorphicComponent<{
|
|
15
|
+
p50: number;
|
|
16
|
+
p90: number;
|
|
17
|
+
p99: number;
|
|
18
|
+
}, {
|
|
19
|
+
[evt: string]: CustomEvent<any>;
|
|
20
|
+
}, {}, {}, string>;
|
|
21
|
+
type PercentileChart = InstanceType<typeof PercentileChart>;
|
|
22
|
+
export default PercentileChart;
|
package/dist/src/dependency.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import type { ComponentMeta, Dependency as IDependency, LayoutNode, Payload } fr
|
|
|
2
2
|
import { Client, type client_return } from "@gradio/client";
|
|
3
3
|
import { LoadingStatus } from "@gradio/statustracker";
|
|
4
4
|
import type { ToastMessage } from "@gradio/statustracker";
|
|
5
|
-
import type { StatusMessage } from "@gradio/client";
|
|
5
|
+
import type { StatusMessage, LogMessage } from "@gradio/client";
|
|
6
6
|
/**
|
|
7
7
|
* A dependency as used by the frontend
|
|
8
8
|
* This class represents a discrete dependency that can be triggered by an event
|
|
@@ -21,6 +21,8 @@ export declare class Dependency {
|
|
|
21
21
|
triggers: [number, "success" | "failure" | "all"][];
|
|
22
22
|
original_trigger_id: number | null;
|
|
23
23
|
show_progress_on: number[] | null;
|
|
24
|
+
component_prop_inputs: number[];
|
|
25
|
+
show_progress: "full" | "minimal" | "hidden";
|
|
24
26
|
functions: {
|
|
25
27
|
frontend?: (...args: unknown[]) => Promise<unknown[]>;
|
|
26
28
|
backend: boolean;
|
|
@@ -56,6 +58,10 @@ interface DispatchEvent {
|
|
|
56
58
|
target_id?: number;
|
|
57
59
|
event_data: unknown;
|
|
58
60
|
}
|
|
61
|
+
type UpdateStateCallback = (id: number, state: Record<string, unknown>, check_visibility?: boolean) => Promise<void>;
|
|
62
|
+
type GetStateCallback = (id: number) => Promise<Record<string, unknown> | null>;
|
|
63
|
+
type RerenderCallback = (components: ComponentMeta[], layout: LayoutNode) => void;
|
|
64
|
+
type LogCallback = (title: string, message: string, fn_index: number, type: ToastMessage["type"], duration?: number | null, visible?: boolean) => void;
|
|
59
65
|
/**
|
|
60
66
|
* Manages all dependencies for an app acting as a bridge between app state and Dependencies
|
|
61
67
|
* Responsible for registering dependencies and dispatching events to them
|
|
@@ -75,13 +81,13 @@ export declare class DependencyManager {
|
|
|
75
81
|
client: Client;
|
|
76
82
|
queue: Set<number>;
|
|
77
83
|
add_to_api_calls: (payload: Payload) => void;
|
|
78
|
-
update_state_cb:
|
|
79
|
-
get_state_cb:
|
|
80
|
-
rerender_cb:
|
|
81
|
-
log_cb:
|
|
84
|
+
update_state_cb: UpdateStateCallback;
|
|
85
|
+
get_state_cb: GetStateCallback;
|
|
86
|
+
rerender_cb: RerenderCallback;
|
|
87
|
+
log_cb: LogCallback;
|
|
82
88
|
loading_stati: LoadingStatus;
|
|
83
89
|
constructor(dependencies: IDependency[], client: Client, update_state_cb: (id: number, state: Record<string, unknown>, check_visibility?: boolean) => Promise<void>, get_state_cb: (id: number) => Promise<Record<string, unknown> | null>, rerender_cb: (components: ComponentMeta[], layout: LayoutNode) => void, log_cb: (title: string, message: string, fn_index: number, type: ToastMessage["type"], duration?: number | null, visible?: boolean) => void, add_to_api_calls: (payload: Payload) => void);
|
|
84
|
-
reload(dependencies: IDependency[], update_state:
|
|
90
|
+
reload(dependencies: IDependency[], update_state: UpdateStateCallback, get_state: GetStateCallback, rerender: RerenderCallback, client: Client): void;
|
|
85
91
|
register_loading_stati(deps: Map<number, Dependency>): void;
|
|
86
92
|
clear_loading_status(component_id: number): void;
|
|
87
93
|
update_loading_stati_state(): Promise<void>;
|
|
@@ -115,9 +121,10 @@ export declare class DependencyManager {
|
|
|
115
121
|
* Gathers the current state of the inputs
|
|
116
122
|
*
|
|
117
123
|
* @param ids the ids of the components to gather state from
|
|
124
|
+
* @param prop_indices the indices (relative to ids array) that should return all component props instead of just the value
|
|
118
125
|
* @returns an array of the current state of the components, in the same order as the ids
|
|
119
126
|
*/
|
|
120
|
-
gather_state(ids: number[]): Promise<(unknown | null)[]>;
|
|
127
|
+
gather_state(ids: number[], prop_indices?: number[]): Promise<(unknown | null)[]>;
|
|
121
128
|
/** Sets the event arguments for a specific component
|
|
122
129
|
*
|
|
123
130
|
* @param id the id of the component to set the event arguments for
|
package/dist/src/dependency.js
CHANGED
|
@@ -24,6 +24,8 @@ export class Dependency {
|
|
|
24
24
|
// in the case of chained events, it would be the id of the initial trigger
|
|
25
25
|
original_trigger_id = null;
|
|
26
26
|
show_progress_on = null;
|
|
27
|
+
component_prop_inputs = [];
|
|
28
|
+
show_progress;
|
|
27
29
|
functions;
|
|
28
30
|
constructor(dep_config) {
|
|
29
31
|
this.id = dep_config.id;
|
|
@@ -31,6 +33,7 @@ export class Dependency {
|
|
|
31
33
|
this.inputs = dep_config.inputs;
|
|
32
34
|
this.outputs = dep_config.outputs;
|
|
33
35
|
this.connection_type = dep_config.connection;
|
|
36
|
+
this.show_progress = dep_config.show_progress;
|
|
34
37
|
this.functions = {
|
|
35
38
|
frontend: dep_config.js
|
|
36
39
|
? process_frontend_fn(dep_config.js, dep_config.backend_fn, dep_config.inputs.length, dep_config.outputs.length)
|
|
@@ -45,6 +48,7 @@ export class Dependency {
|
|
|
45
48
|
this.cancels = dep_config.cancels;
|
|
46
49
|
this.trigger_modes = dep_config.trigger_mode;
|
|
47
50
|
this.show_progress_on = dep_config.show_progress_on || null;
|
|
51
|
+
this.component_prop_inputs = dep_config.component_prop_inputs || [];
|
|
48
52
|
for (let i = 0; i < dep_config.event_specific_args?.length || 0; i++) {
|
|
49
53
|
const key = dep_config.event_specific_args[i];
|
|
50
54
|
this.event_args[key] = dep_config[key] ?? null;
|
|
@@ -117,31 +121,31 @@ export class DependencyManager {
|
|
|
117
121
|
loading_stati = new LoadingStatus();
|
|
118
122
|
constructor(dependencies, client, update_state_cb, get_state_cb, rerender_cb, log_cb, add_to_api_calls) {
|
|
119
123
|
this.add_to_api_calls = add_to_api_calls;
|
|
120
|
-
this.client = client;
|
|
121
124
|
this.log_cb = log_cb;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
this.
|
|
125
|
+
this.update_state_cb = update_state_cb;
|
|
126
|
+
this.get_state_cb = get_state_cb;
|
|
127
|
+
this.rerender_cb = rerender_cb;
|
|
128
|
+
this.client = client;
|
|
129
|
+
this.reload(dependencies, update_state_cb, get_state_cb, rerender_cb, client);
|
|
126
130
|
}
|
|
127
131
|
reload(dependencies, update_state, get_state, rerender, client) {
|
|
128
132
|
const { by_id, by_event } = this.create(dependencies);
|
|
129
133
|
this.dependencies_by_event = by_event;
|
|
130
134
|
this.dependencies_by_fn = by_id;
|
|
135
|
+
this.client = client;
|
|
136
|
+
this.update_state_cb = update_state;
|
|
137
|
+
this.get_state_cb = get_state;
|
|
138
|
+
this.rerender_cb = rerender;
|
|
131
139
|
for (const [dep_id, dep] of this.dependencies_by_fn) {
|
|
132
140
|
for (const [output_id] of dep.targets) {
|
|
133
141
|
this.set_event_args(output_id, dep.event_args);
|
|
134
142
|
}
|
|
135
143
|
}
|
|
136
|
-
this.client = client;
|
|
137
|
-
this.update_state_cb = update_state;
|
|
138
|
-
this.get_state_cb = get_state;
|
|
139
|
-
this.rerender_cb = rerender;
|
|
140
144
|
this.register_loading_stati(by_id);
|
|
141
145
|
}
|
|
142
146
|
register_loading_stati(deps) {
|
|
143
147
|
for (const [_, dep] of deps) {
|
|
144
|
-
this.loading_stati.register(dep.id, dep.show_progress_on || dep.outputs, dep.inputs);
|
|
148
|
+
this.loading_stati.register(dep.id, dep.show_progress_on || dep.outputs, dep.inputs, dep.show_progress);
|
|
145
149
|
}
|
|
146
150
|
}
|
|
147
151
|
clear_loading_status(component_id) {
|
|
@@ -206,7 +210,7 @@ export class DependencyManager {
|
|
|
206
210
|
});
|
|
207
211
|
this.update_loading_stati_state();
|
|
208
212
|
}
|
|
209
|
-
const data_payload = await this.gather_state(dep.inputs);
|
|
213
|
+
const data_payload = await this.gather_state(dep.inputs, dep.component_prop_inputs);
|
|
210
214
|
const unset_args = await Promise.all(dep.targets.map(([output_id]) => this.set_event_args(output_id, dep.event_args)));
|
|
211
215
|
const { success, failure, all } = dep.get_triggers();
|
|
212
216
|
try {
|
|
@@ -241,7 +245,7 @@ export class DependencyManager {
|
|
|
241
245
|
unset_args.forEach((fn) => fn());
|
|
242
246
|
}
|
|
243
247
|
else if (dep_submission.type === "data") {
|
|
244
|
-
this.handle_data(dep.outputs, dep_submission.data);
|
|
248
|
+
await this.handle_data(dep.outputs, dep_submission.data);
|
|
245
249
|
unset_args.forEach((fn) => fn());
|
|
246
250
|
}
|
|
247
251
|
else {
|
|
@@ -268,7 +272,7 @@ export class DependencyManager {
|
|
|
268
272
|
if (result === null)
|
|
269
273
|
continue;
|
|
270
274
|
if (result.type === "data") {
|
|
271
|
-
this.handle_data(dep.outputs, result.data);
|
|
275
|
+
await this.handle_data(dep.outputs, result.data);
|
|
272
276
|
}
|
|
273
277
|
if (result.type === "status") {
|
|
274
278
|
if (result.original_msg === "process_starts" &&
|
|
@@ -341,7 +345,9 @@ export class DependencyManager {
|
|
|
341
345
|
return;
|
|
342
346
|
}
|
|
343
347
|
const _message = result?.message?.replace(MESSAGE_QUOTE_RE, (_, b) => b);
|
|
344
|
-
this.log_cb(
|
|
348
|
+
this.log_cb(
|
|
349
|
+
//@ts-ignore
|
|
350
|
+
result?._title ?? "Error", _message || "", fn_index, "error", status.duration, status.visible);
|
|
345
351
|
throw new Error("Dependency function failed");
|
|
346
352
|
}
|
|
347
353
|
else {
|
|
@@ -356,6 +362,12 @@ export class DependencyManager {
|
|
|
356
362
|
}
|
|
357
363
|
}
|
|
358
364
|
if (result.type === "render") {
|
|
365
|
+
this.loading_stati.update({
|
|
366
|
+
status: "complete",
|
|
367
|
+
fn_index: dep.id,
|
|
368
|
+
stream_state: null
|
|
369
|
+
});
|
|
370
|
+
this.update_loading_stati_state();
|
|
359
371
|
const { layout, components, render_id, dependencies } = result.data;
|
|
360
372
|
this.rerender_cb(components, layout);
|
|
361
373
|
// update dependencies
|
|
@@ -470,7 +482,7 @@ export class DependencyManager {
|
|
|
470
482
|
* @param data the data to update the components with
|
|
471
483
|
* */
|
|
472
484
|
async handle_data(outputs, data) {
|
|
473
|
-
outputs.
|
|
485
|
+
await Promise.all(outputs.map(async (output_id, i) => {
|
|
474
486
|
const _data = data[i] === undefined ? NOVALUE : data[i];
|
|
475
487
|
if (_data === NOVALUE)
|
|
476
488
|
return;
|
|
@@ -498,16 +510,20 @@ export class DependencyManager {
|
|
|
498
510
|
else {
|
|
499
511
|
await this.update_state_cb(output_id, { value: _data }, false);
|
|
500
512
|
}
|
|
501
|
-
});
|
|
513
|
+
}));
|
|
502
514
|
}
|
|
503
515
|
/**
|
|
504
516
|
* Gathers the current state of the inputs
|
|
505
517
|
*
|
|
506
518
|
* @param ids the ids of the components to gather state from
|
|
519
|
+
* @param prop_indices the indices (relative to ids array) that should return all component props instead of just the value
|
|
507
520
|
* @returns an array of the current state of the components, in the same order as the ids
|
|
508
521
|
*/
|
|
509
|
-
async gather_state(ids) {
|
|
510
|
-
return (await Promise.all(ids.map((id) => this.get_state_cb(id)))).map((state) => {
|
|
522
|
+
async gather_state(ids, prop_indices = []) {
|
|
523
|
+
return (await Promise.all(ids.map((id) => this.get_state_cb(id)))).map((state, index) => {
|
|
524
|
+
if (prop_indices.includes(index)) {
|
|
525
|
+
return state ?? null;
|
|
526
|
+
}
|
|
511
527
|
return state?.value ?? null;
|
|
512
528
|
});
|
|
513
529
|
}
|
|
@@ -519,7 +535,9 @@ export class DependencyManager {
|
|
|
519
535
|
*/
|
|
520
536
|
async set_event_args(id, args) {
|
|
521
537
|
let current_args = {};
|
|
522
|
-
const current_state = await this.get_state_cb(id);
|
|
538
|
+
const current_state = await this.get_state_cb?.(id);
|
|
539
|
+
if (!current_state)
|
|
540
|
+
return () => { };
|
|
523
541
|
for (const [key] of Object.entries(args)) {
|
|
524
542
|
current_args[key] = current_state?.[key] ?? null;
|
|
525
543
|
}
|
|
@@ -27,8 +27,8 @@ export declare class AppTree {
|
|
|
27
27
|
ready: Promise<void>;
|
|
28
28
|
ready_resolve: () => void;
|
|
29
29
|
resolved: boolean;
|
|
30
|
-
constructor(components: ComponentMeta[], layout: LayoutNode, dependencies: Dependency[], config: AppConfig, app: client_return, reactive_formatter: (str: string) => string);
|
|
31
|
-
reload(components: ComponentMeta[], layout: LayoutNode, dependencies: Dependency[], config: AppConfig): void;
|
|
30
|
+
constructor(components: ComponentMeta[], layout: LayoutNode, dependencies: Dependency[], config: Omit<AppConfig, "api_url">, app: client_return, reactive_formatter: (str: string) => string);
|
|
31
|
+
reload(components: ComponentMeta[], layout: LayoutNode, dependencies: Dependency[], config: Omit<AppConfig, "api_url">): void;
|
|
32
32
|
/**
|
|
33
33
|
* Registers a component with its ID and data callbacks
|
|
34
34
|
* @param id the ID of the component
|
package/dist/src/init.svelte.js
CHANGED
|
@@ -40,7 +40,10 @@ export class AppTree {
|
|
|
40
40
|
this.ready_resolve = resolve;
|
|
41
41
|
});
|
|
42
42
|
this.reactive_formatter = reactive_formatter;
|
|
43
|
-
this.#config =
|
|
43
|
+
this.#config = {
|
|
44
|
+
...config,
|
|
45
|
+
api_url: new URL(config.api_prefix, config.root).toString()
|
|
46
|
+
};
|
|
44
47
|
this.#component_payload = components;
|
|
45
48
|
this.#layout_payload = layout;
|
|
46
49
|
this.#dependency_payload = dependencies;
|
|
@@ -67,7 +70,10 @@ export class AppTree {
|
|
|
67
70
|
reload(components, layout, dependencies, config) {
|
|
68
71
|
this.#layout_payload = layout;
|
|
69
72
|
this.#component_payload = components;
|
|
70
|
-
this.#config =
|
|
73
|
+
this.#config = {
|
|
74
|
+
...config,
|
|
75
|
+
api_url: new URL(config.api_prefix, config.root).toString()
|
|
76
|
+
};
|
|
71
77
|
this.#dependency_payload = dependencies;
|
|
72
78
|
this.root = this.create_node({ id: layout.id, children: [] }, new Map(), true);
|
|
73
79
|
for (const comp of components) {
|
|
@@ -115,11 +121,11 @@ export class AppTree {
|
|
|
115
121
|
process() { }
|
|
116
122
|
postprocess(tree) {
|
|
117
123
|
this.root = this.traverse(tree, [
|
|
118
|
-
(node) => handle_visibility(node, this.#config.
|
|
119
|
-
(node) => untrack_children_of_invisible_parents(node, this
|
|
120
|
-
(node) => handle_empty_forms(node, this
|
|
121
|
-
(node) => translate_props(node
|
|
122
|
-
(node) => apply_initial_tabs(node, this
|
|
124
|
+
(node) => handle_visibility(node, this.#config.api_url),
|
|
125
|
+
(node) => untrack_children_of_invisible_parents(node, this.components_to_register),
|
|
126
|
+
(node) => handle_empty_forms(node, this.components_to_register),
|
|
127
|
+
(node) => translate_props(node),
|
|
128
|
+
(node) => apply_initial_tabs(node, this.initial_tabs),
|
|
123
129
|
(node) => this.find_attached_events(node, this.#dependency_payload)
|
|
124
130
|
]);
|
|
125
131
|
}
|
|
@@ -191,7 +197,7 @@ export class AppTree {
|
|
|
191
197
|
if (reactive_formatter) {
|
|
192
198
|
component.props.i18n = reactive_formatter;
|
|
193
199
|
}
|
|
194
|
-
const processed_props = gather_props(opts.id, component.props, [this.#input_ids, this.#output_ids], this.client, { ...this.#config });
|
|
200
|
+
const processed_props = gather_props(opts.id, component.props, [this.#input_ids, this.#output_ids], this.client, this.#config.api_url, { ...this.#config });
|
|
195
201
|
const type = type_map[component.type] || component.type;
|
|
196
202
|
const node = {
|
|
197
203
|
id: opts.id,
|
|
@@ -201,7 +207,7 @@ export class AppTree {
|
|
|
201
207
|
show_progress_on: null,
|
|
202
208
|
component_class_id: component.component_class_id || component.type,
|
|
203
209
|
component: processed_props.shared_props.visible !== false
|
|
204
|
-
? get_component(component.type, component.component_class_id, this.#config.
|
|
210
|
+
? get_component(component.type, component.component_class_id, this.#config.api_url || "")
|
|
205
211
|
: null,
|
|
206
212
|
key: component.key,
|
|
207
213
|
rendered_in: component.rendered_in,
|
|
@@ -242,7 +248,7 @@ export class AppTree {
|
|
|
242
248
|
this.root = this.traverse(this.root, [
|
|
243
249
|
//@ts-ignore
|
|
244
250
|
(n) => set_visibility_for_updated_node(n, id, new_state.visible),
|
|
245
|
-
(n) => handle_visibility(n, this.#config.
|
|
251
|
+
(n) => handle_visibility(n, this.#config.api_url)
|
|
246
252
|
]);
|
|
247
253
|
already_updated_visibility = true;
|
|
248
254
|
}
|
|
@@ -255,7 +261,7 @@ export class AppTree {
|
|
|
255
261
|
// need to let the UI settle before traversing again
|
|
256
262
|
// otherwise there could be
|
|
257
263
|
await tick();
|
|
258
|
-
this.root = this.traverse(this.root, (n) => handle_visibility(n, this.#config.
|
|
264
|
+
this.root = this.traverse(this.root, (n) => handle_visibility(n, this.#config.api_url));
|
|
259
265
|
}
|
|
260
266
|
/**
|
|
261
267
|
* Gets the current state of a component by its ID
|
|
@@ -304,7 +310,7 @@ export function process_server_fn(id, server_fns, app) {
|
|
|
304
310
|
* @param additional any additional props to include
|
|
305
311
|
* @returns the gathered props as an object with `shared_props` and `props` keys
|
|
306
312
|
*/
|
|
307
|
-
function gather_props(id, props, dependencies, client, additional = {}) {
|
|
313
|
+
function gather_props(id, props, dependencies, client, api_url, additional = {}) {
|
|
308
314
|
const _shared_props = {};
|
|
309
315
|
const _props = {};
|
|
310
316
|
for (const key in props) {
|
|
@@ -336,22 +342,22 @@ function gather_props(id, props, dependencies, client, additional = {}) {
|
|
|
336
342
|
_shared_props.client = client;
|
|
337
343
|
_shared_props.id = id;
|
|
338
344
|
_shared_props.interactive = determine_interactivity(id, _shared_props.interactive, _props.value, dependencies);
|
|
339
|
-
_shared_props.load_component = (name, variant) => get_component(name, "",
|
|
345
|
+
_shared_props.load_component = (name, variant) => get_component(name, "", api_url, variant);
|
|
340
346
|
_shared_props.visible =
|
|
341
347
|
_shared_props.visible === undefined ? true : _shared_props.visible;
|
|
342
348
|
_shared_props.loading_status = {};
|
|
343
349
|
return { shared_props: _shared_props, props: _props };
|
|
344
350
|
}
|
|
345
|
-
function handle_visibility(node,
|
|
351
|
+
function handle_visibility(node, api_url) {
|
|
346
352
|
// Check if the node is visible
|
|
347
353
|
if (node.props.shared_props.visible && !node.component) {
|
|
348
354
|
const result = {
|
|
349
355
|
...node,
|
|
350
|
-
component: get_component(node.type, node.component_class_id,
|
|
356
|
+
component: get_component(node.type, node.component_class_id, api_url),
|
|
351
357
|
children: []
|
|
352
358
|
};
|
|
353
359
|
if (node.children) {
|
|
354
|
-
result.children = node.children.map((child) => handle_visibility(child,
|
|
360
|
+
result.children = node.children.map((child) => handle_visibility(child, api_url));
|
|
355
361
|
}
|
|
356
362
|
return result;
|
|
357
363
|
}
|
|
@@ -372,14 +378,14 @@ function _untrack(node, components_to_register) {
|
|
|
372
378
|
}
|
|
373
379
|
return;
|
|
374
380
|
}
|
|
375
|
-
function untrack_children_of_invisible_parents(node,
|
|
381
|
+
function untrack_children_of_invisible_parents(node, components_to_register) {
|
|
376
382
|
// Check if the node is visible
|
|
377
383
|
if (node.props.shared_props.visible !== true) {
|
|
378
384
|
_untrack(node, components_to_register);
|
|
379
385
|
}
|
|
380
386
|
return node;
|
|
381
387
|
}
|
|
382
|
-
function handle_empty_forms(node,
|
|
388
|
+
function handle_empty_forms(node, components_to_register) {
|
|
383
389
|
// Check if the node is visible
|
|
384
390
|
if (node.type === "form") {
|
|
385
391
|
const all_children_invisible = node.children.every((child) => child.props.shared_props.visible === false);
|
|
@@ -391,7 +397,7 @@ function handle_empty_forms(node, root, components_to_register) {
|
|
|
391
397
|
}
|
|
392
398
|
return node;
|
|
393
399
|
}
|
|
394
|
-
function translate_props(node
|
|
400
|
+
function translate_props(node) {
|
|
395
401
|
const supported_props = [
|
|
396
402
|
"description",
|
|
397
403
|
"info",
|
|
@@ -413,7 +419,7 @@ function translate_props(node, root) {
|
|
|
413
419
|
}
|
|
414
420
|
return node;
|
|
415
421
|
}
|
|
416
|
-
function apply_initial_tabs(node,
|
|
422
|
+
function apply_initial_tabs(node, initial_tabs) {
|
|
417
423
|
if (node.type === "tabs" && node.id in initial_tabs) {
|
|
418
424
|
const tabs = initial_tabs[node.id].sort((a, b) => a.order - b.order);
|
|
419
425
|
node.props.props.initial_tabs = tabs;
|
package/dist/src/types.d.ts
CHANGED
|
@@ -71,6 +71,7 @@ export interface Dependency {
|
|
|
71
71
|
like_user_message: boolean;
|
|
72
72
|
event_specific_args: ("time_limit" | "stream_every" | "like_user_message")[];
|
|
73
73
|
js_implementation: string | null;
|
|
74
|
+
component_prop_inputs: number[];
|
|
74
75
|
}
|
|
75
76
|
interface TypeDescription {
|
|
76
77
|
input_payload?: string;
|
|
@@ -106,5 +107,6 @@ export interface AppConfig {
|
|
|
106
107
|
max_file_size?: number;
|
|
107
108
|
autoscroll: boolean;
|
|
108
109
|
api_prefix: string;
|
|
110
|
+
api_url: string;
|
|
109
111
|
}
|
|
110
112
|
export {};
|