@gradio/core 1.0.0-dev.0 → 1.0.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 +110 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/src/Blocks.svelte +534 -1001
- package/dist/src/Blocks.svelte.d.ts +32 -45
- package/dist/src/Embed.svelte +82 -55
- package/dist/src/Embed.svelte.d.ts +39 -30
- package/dist/src/Login.svelte +33 -29
- package/dist/src/Login.svelte.d.ts +21 -19
- package/dist/src/MountComponents.svelte +19 -25
- package/dist/src/MountComponents.svelte.d.ts +5 -28
- package/dist/src/{init.d.ts → _init.d.ts} +5 -4
- package/dist/src/{init.js → _init.js} +31 -108
- package/dist/src/api_docs/ApiBanner.svelte +12 -8
- package/dist/src/api_docs/ApiBanner.svelte.d.ts +22 -20
- package/dist/src/api_docs/ApiDocs.svelte +356 -247
- package/dist/src/api_docs/ApiDocs.svelte.d.ts +27 -24
- package/dist/src/api_docs/ApiRecorder.svelte +6 -3
- package/dist/src/api_docs/ApiRecorder.svelte.d.ts +19 -17
- package/dist/src/api_docs/CodeSnippet.svelte +122 -48
- package/dist/src/api_docs/CodeSnippet.svelte.d.ts +29 -25
- package/dist/src/api_docs/CopyButton.svelte +69 -13
- package/dist/src/api_docs/CopyButton.svelte.d.ts +18 -16
- package/dist/src/api_docs/CopyMarkdown.svelte +734 -0
- package/dist/src/api_docs/CopyMarkdown.svelte.d.ts +37 -0
- package/dist/src/api_docs/EndpointDetail.svelte +81 -23
- package/dist/src/api_docs/EndpointDetail.svelte.d.ts +23 -18
- package/dist/src/api_docs/IconArrowUpRight.svelte +34 -0
- package/dist/src/api_docs/IconArrowUpRight.svelte.d.ts +20 -0
- package/dist/src/api_docs/IconCaret.svelte +39 -0
- package/dist/src/api_docs/IconCaret.svelte.d.ts +20 -0
- package/dist/src/api_docs/IconHuggingChat.svelte +62 -0
- package/dist/src/api_docs/IconHuggingChat.svelte.d.ts +20 -0
- package/dist/src/api_docs/InputPayload.svelte +17 -11
- package/dist/src/api_docs/InputPayload.svelte.d.ts +25 -23
- package/dist/src/api_docs/InstallSnippet.svelte +9 -6
- package/dist/src/api_docs/InstallSnippet.svelte.d.ts +18 -16
- package/dist/src/api_docs/MCPSnippet.svelte +139 -126
- package/dist/src/api_docs/MCPSnippet.svelte.d.ts +60 -58
- package/dist/src/api_docs/NoApi.svelte +7 -4
- package/dist/src/api_docs/NoApi.svelte.d.ts +20 -18
- package/dist/src/api_docs/ParametersSnippet.svelte +8 -6
- package/dist/src/api_docs/ParametersSnippet.svelte.d.ts +21 -19
- package/dist/src/api_docs/PercentileChart.svelte +125 -0
- package/dist/src/api_docs/PercentileChart.svelte.d.ts +22 -0
- package/dist/src/api_docs/RecordingSnippet.svelte +124 -110
- package/dist/src/api_docs/RecordingSnippet.svelte.d.ts +24 -22
- package/dist/src/api_docs/ResponseSnippet.svelte +7 -5
- package/dist/src/api_docs/ResponseSnippet.svelte.d.ts +21 -19
- package/dist/src/api_docs/Settings.svelte +73 -62
- package/dist/src/api_docs/Settings.svelte.d.ts +25 -23
- package/dist/src/api_docs/SettingsBanner.svelte +11 -8
- package/dist/src/api_docs/SettingsBanner.svelte.d.ts +20 -18
- package/dist/src/api_docs/TryButton.svelte +5 -3
- package/dist/src/api_docs/TryButton.svelte.d.ts +19 -17
- package/dist/src/api_docs/img/IconCheck.svelte +33 -0
- package/dist/src/api_docs/img/IconCheck.svelte.d.ts +26 -0
- package/dist/src/api_docs/img/IconCopy.svelte +40 -0
- package/dist/src/api_docs/img/IconCopy.svelte.d.ts +26 -0
- package/dist/src/api_docs/img/clear.svelte.d.ts +22 -21
- package/dist/src/dependency.d.ts +145 -0
- package/dist/src/dependency.js +668 -0
- package/dist/src/init.svelte.d.ts +78 -0
- package/dist/src/init.svelte.js +469 -0
- package/dist/src/init_utils.d.ts +32 -0
- package/dist/src/init_utils.js +73 -0
- package/dist/src/lang/en.json +10 -1
- package/dist/src/lang/get_lang_names.js +0 -3
- package/dist/src/lang/ru.json +10 -1
- package/dist/src/stores.d.ts +0 -21
- package/dist/src/stories/I18nMultiLanguageTestComponent.svelte +5 -3
- package/dist/src/stories/I18nMultiLanguageTestComponent.svelte.d.ts +16 -14
- package/dist/src/stories/I18nTestSetup.svelte +14 -10
- package/dist/src/stories/I18nTestSetup.svelte.d.ts +18 -16
- package/dist/src/types.d.ts +31 -26
- package/index.ts +1 -1
- package/package.json +62 -63
- package/src/Blocks.svelte +360 -1063
- package/src/MountComponents.svelte +17 -27
- package/src/{init.ts → _init.ts} +49 -126
- package/src/api_docs/ApiDocs.svelte +84 -62
- package/src/api_docs/CodeSnippet.svelte +83 -24
- package/src/api_docs/CopyButton.svelte +61 -7
- package/src/api_docs/CopyMarkdown.svelte +734 -0
- package/src/api_docs/EndpointDetail.svelte +73 -17
- package/src/api_docs/IconArrowUpRight.svelte +34 -0
- package/src/api_docs/IconCaret.svelte +39 -0
- package/src/api_docs/IconHuggingChat.svelte +62 -0
- package/src/api_docs/MCPSnippet.svelte +44 -73
- package/src/api_docs/ParametersSnippet.svelte +1 -1
- package/src/api_docs/PercentileChart.svelte +125 -0
- package/src/api_docs/ResponseSnippet.svelte +1 -1
- package/src/api_docs/Settings.svelte +11 -11
- package/src/api_docs/img/IconCheck.svelte +33 -0
- package/src/api_docs/img/IconCopy.svelte +40 -0
- package/src/dependency.ts +909 -0
- package/src/init.svelte.ts +717 -0
- package/src/init_utils.ts +99 -0
- package/src/lang/en.json +10 -1
- package/src/lang/get_lang_names.js +0 -3
- package/src/lang/ru.json +10 -1
- package/src/stores.ts +22 -22
- package/src/types.ts +55 -43
- package/dist/src/Render.svelte +0 -105
- package/dist/src/Render.svelte.d.ts +0 -31
- package/dist/src/RenderComponent.svelte +0 -72
- package/dist/src/RenderComponent.svelte.d.ts +0 -33
- package/src/Render.svelte +0 -126
- package/src/RenderComponent.svelte +0 -91
package/src/Blocks.svelte
CHANGED
|
@@ -1,131 +1,239 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { tick, onMount } from "svelte";
|
|
2
|
+
import { tick, onMount, setContext, settled, untrack } from "svelte";
|
|
3
3
|
import { _ } from "svelte-i18n";
|
|
4
4
|
import { Client } from "@gradio/client";
|
|
5
5
|
import { writable } from "svelte/store";
|
|
6
6
|
|
|
7
|
-
import type { LoadingStatus, LoadingStatusCollection } from "./stores";
|
|
7
|
+
// import type { LoadingStatus, LoadingStatusCollection } from "./stores";
|
|
8
8
|
|
|
9
|
-
import type {
|
|
10
|
-
|
|
9
|
+
import type {
|
|
10
|
+
ComponentMeta,
|
|
11
|
+
Dependency as IDependency,
|
|
12
|
+
LayoutNode
|
|
13
|
+
} from "./types";
|
|
14
|
+
// import type { UpdateTransaction } from "./_init";
|
|
11
15
|
import { setupi18n } from "./i18n";
|
|
12
16
|
import type { ThemeMode, Payload } from "./types";
|
|
13
17
|
import { Toast } from "@gradio/statustracker";
|
|
14
18
|
import type { ToastMessage } from "@gradio/statustracker";
|
|
15
|
-
import type
|
|
19
|
+
import { type ShareData, type ValueData, GRADIO_ROOT } from "@gradio/utils";
|
|
20
|
+
|
|
16
21
|
import MountComponents from "./MountComponents.svelte";
|
|
17
22
|
import { prefix_css } from "./css";
|
|
23
|
+
import { reactive_formatter } from "./gradio_helper";
|
|
18
24
|
|
|
19
|
-
import type
|
|
20
|
-
import type
|
|
21
|
-
import type
|
|
22
|
-
import type { ComponentType } from "svelte";
|
|
25
|
+
import type ApiDocsInterface from "./api_docs/ApiDocs.svelte";
|
|
26
|
+
import type ApiRecorderInterface from "./api_docs/ApiRecorder.svelte";
|
|
27
|
+
import type SettingsInterface from "./api_docs/Settings.svelte";
|
|
28
|
+
// import type { ComponentType } from "svelte";
|
|
23
29
|
|
|
24
30
|
import logo from "./images/logo.svg";
|
|
25
31
|
import api_logo from "./api_docs/img/api-logo.svg";
|
|
26
32
|
import settings_logo from "./api_docs/img/settings-logo.svg";
|
|
27
33
|
import record_stop from "./api_docs/img/record-stop.svg";
|
|
28
|
-
import {
|
|
29
|
-
import type {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
} from "@gradio/client";
|
|
34
|
+
import { AppTree } from "./init.svelte";
|
|
35
|
+
// import type {
|
|
36
|
+
// LogMessage,
|
|
37
|
+
// RenderMessage,
|
|
38
|
+
// StatusMessage,
|
|
39
|
+
// } from "@gradio/client";
|
|
34
40
|
import * as screen_recorder from "./screen_recorder";
|
|
35
41
|
|
|
36
|
-
|
|
37
|
-
export let components: ComponentMeta[];
|
|
38
|
-
export let layout: LayoutNode;
|
|
39
|
-
export let dependencies: Dependency[];
|
|
40
|
-
export let title = "Gradio";
|
|
41
|
-
export let target: HTMLElement;
|
|
42
|
-
export let autoscroll: boolean;
|
|
43
|
-
export let footer_links = ["gradio", "settings", "api"];
|
|
44
|
-
export let control_page_title = false;
|
|
45
|
-
export let app_mode: boolean;
|
|
46
|
-
export let theme_mode: ThemeMode;
|
|
47
|
-
export let app: Awaited<ReturnType<typeof Client.connect>>;
|
|
48
|
-
export let space_id: string | null;
|
|
49
|
-
export let version: string;
|
|
50
|
-
export let js: string | null;
|
|
51
|
-
export let fill_height = false;
|
|
52
|
-
export let ready: boolean;
|
|
53
|
-
export let username: string | null;
|
|
54
|
-
export let api_prefix = "";
|
|
55
|
-
export let max_file_size: number | undefined = undefined;
|
|
56
|
-
export let initial_layout: ComponentMeta | undefined = undefined;
|
|
57
|
-
export let css: string | null | undefined = null;
|
|
58
|
-
export let vibe_mode = false;
|
|
59
|
-
let broken_connection = false;
|
|
42
|
+
import { DependencyManager } from "./dependency";
|
|
60
43
|
|
|
61
44
|
let {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
45
|
+
root,
|
|
46
|
+
components,
|
|
47
|
+
layout,
|
|
48
|
+
dependencies,
|
|
49
|
+
title,
|
|
50
|
+
target,
|
|
51
|
+
autoscroll,
|
|
52
|
+
footer_links,
|
|
53
|
+
control_page_title,
|
|
54
|
+
app_mode,
|
|
55
|
+
theme_mode,
|
|
56
|
+
app,
|
|
57
|
+
space_id,
|
|
58
|
+
version,
|
|
59
|
+
js,
|
|
60
|
+
fill_height,
|
|
61
|
+
username,
|
|
62
|
+
api_prefix,
|
|
63
|
+
max_file_size,
|
|
64
|
+
initial_layout,
|
|
65
|
+
css,
|
|
66
|
+
vibe_mode,
|
|
67
|
+
search_params,
|
|
68
|
+
render_complete = false,
|
|
69
|
+
ready = $bindable(false),
|
|
70
|
+
reload_count = $bindable(0),
|
|
71
|
+
add_new_message = $bindable()
|
|
72
|
+
}: {
|
|
73
|
+
root: string;
|
|
74
|
+
components: ComponentMeta[];
|
|
75
|
+
layout: LayoutNode;
|
|
76
|
+
dependencies: IDependency[];
|
|
77
|
+
title: string;
|
|
78
|
+
target: HTMLElement;
|
|
79
|
+
autoscroll: boolean;
|
|
80
|
+
footer_links: string[];
|
|
81
|
+
control_page_title: boolean;
|
|
82
|
+
app_mode: boolean;
|
|
83
|
+
theme_mode: ThemeMode;
|
|
84
|
+
app: Awaited<ReturnType<typeof Client.connect>>;
|
|
85
|
+
space_id: string | null;
|
|
86
|
+
version: string;
|
|
87
|
+
js: string | null;
|
|
88
|
+
fill_height: boolean;
|
|
89
|
+
username: string | null;
|
|
90
|
+
api_prefix: string;
|
|
91
|
+
max_file_size: number | undefined;
|
|
92
|
+
initial_layout: ComponentMeta | undefined;
|
|
93
|
+
css: string | null | undefined;
|
|
94
|
+
vibe_mode: boolean;
|
|
95
|
+
search_params: URLSearchParams;
|
|
96
|
+
render_complete: boolean;
|
|
97
|
+
ready: boolean;
|
|
98
|
+
reload_count: number;
|
|
99
|
+
add_new_message: (title: string, message: string, type: string) => void;
|
|
100
|
+
} = $props();
|
|
101
|
+
|
|
102
|
+
components.forEach((comp) => {
|
|
103
|
+
if (!comp.props.i18n) {
|
|
104
|
+
comp.props.i18n = $reactive_formatter;
|
|
105
|
+
}
|
|
76
106
|
});
|
|
77
107
|
|
|
78
|
-
|
|
108
|
+
let app_tree = new AppTree(
|
|
109
|
+
components,
|
|
110
|
+
layout,
|
|
111
|
+
dependencies,
|
|
112
|
+
{
|
|
113
|
+
root,
|
|
114
|
+
theme: theme_mode,
|
|
115
|
+
version,
|
|
116
|
+
api_prefix,
|
|
117
|
+
max_file_size,
|
|
118
|
+
autoscroll
|
|
119
|
+
},
|
|
120
|
+
app,
|
|
121
|
+
$reactive_formatter
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
setContext(GRADIO_ROOT, {
|
|
125
|
+
register: app_tree.register_component.bind(app_tree),
|
|
126
|
+
dispatcher: gradio_event_dispatcher
|
|
127
|
+
});
|
|
79
128
|
|
|
80
|
-
|
|
81
|
-
ready = !!$_layout;
|
|
82
|
-
}
|
|
129
|
+
let messages: (ToastMessage & { fn_index: number })[] = $state([]);
|
|
83
130
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
131
|
+
function gradio_event_dispatcher(
|
|
132
|
+
id: number,
|
|
133
|
+
event: string,
|
|
134
|
+
data: unknown
|
|
135
|
+
): void {
|
|
136
|
+
if (event === "share") {
|
|
137
|
+
const { title, description } = data as ShareData;
|
|
138
|
+
// trigger_share(title, description);
|
|
139
|
+
// TODO: lets combine all of the into a log type with levels
|
|
140
|
+
} else if (event === "error") {
|
|
141
|
+
new_message("Error", data, -1, event, 10, true);
|
|
142
|
+
} else if (event === "warning") {
|
|
143
|
+
new_message("Warning", data, -1, event, 10, true);
|
|
144
|
+
} else if (event === "info") {
|
|
145
|
+
new_message("Info", data, -1, event, 10, true);
|
|
146
|
+
} else if (event == "clear_status") {
|
|
147
|
+
app_tree.update_state(
|
|
148
|
+
id,
|
|
149
|
+
{
|
|
150
|
+
loading_status: {}
|
|
151
|
+
},
|
|
152
|
+
false
|
|
153
|
+
);
|
|
154
|
+
dep_manager.clear_loading_status(id);
|
|
155
|
+
// TODO: the loading_status store should handle this via a method
|
|
156
|
+
// update_status(id, "complete", data);
|
|
157
|
+
} else if (event == "close_stream") {
|
|
158
|
+
dep_manager.close_stream(id);
|
|
159
|
+
} else {
|
|
160
|
+
// Tabs are a bit weird. The Tabs component dispatches 'select' events
|
|
161
|
+
// but the target id corresponds to the child Tab component that was selected.
|
|
162
|
+
// So the id we get from the dispatcher belongs to the Tabs,
|
|
163
|
+
// so we need to pull out the correct id here.
|
|
164
|
+
if (event === "select" && id in app_tree.initial_tabs) {
|
|
165
|
+
// this is the id of the selected tab
|
|
166
|
+
id = data.id;
|
|
167
|
+
}
|
|
168
|
+
dep_manager.dispatch({
|
|
169
|
+
type: "event",
|
|
170
|
+
event_name: event,
|
|
171
|
+
target_id: id,
|
|
172
|
+
event_data: data
|
|
173
|
+
});
|
|
174
|
+
}
|
|
93
175
|
}
|
|
94
176
|
|
|
95
|
-
let
|
|
177
|
+
let api_calls: Payload[] = $state([]);
|
|
178
|
+
let last_api_call: Payload | null = $state(null);
|
|
179
|
+
// We need a callback to add to api_calls from the DependencyManager
|
|
180
|
+
// We can't update a state variable from inside the DependencyManager because
|
|
181
|
+
// svelte won't see it and won't update the UI.
|
|
182
|
+
let add_to_api_calls = (payload: Payload): void => {
|
|
183
|
+
last_api_call = payload;
|
|
184
|
+
if (!api_recorder_visible) return;
|
|
185
|
+
api_calls = [...api_calls, last_api_call];
|
|
186
|
+
};
|
|
96
187
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
188
|
+
let dep_manager = new DependencyManager(
|
|
189
|
+
dependencies,
|
|
190
|
+
app,
|
|
191
|
+
app_tree.update_state.bind(app_tree),
|
|
192
|
+
app_tree.get_state.bind(app_tree),
|
|
193
|
+
app_tree.rerender.bind(app_tree),
|
|
194
|
+
new_message,
|
|
195
|
+
add_to_api_calls
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
$effect(() => {
|
|
199
|
+
reload_count;
|
|
200
|
+
untrack(() => {
|
|
201
|
+
app_tree.reload(components, layout, dependencies, {
|
|
202
|
+
root,
|
|
203
|
+
theme: theme_mode,
|
|
204
|
+
version,
|
|
205
|
+
api_prefix,
|
|
206
|
+
max_file_size,
|
|
207
|
+
autoscroll
|
|
208
|
+
});
|
|
209
|
+
dep_manager.reload(
|
|
210
|
+
dependencies,
|
|
211
|
+
app_tree.update_state.bind(app_tree),
|
|
212
|
+
app_tree.get_state.bind(app_tree),
|
|
213
|
+
app_tree.rerender.bind(app_tree),
|
|
214
|
+
app
|
|
215
|
+
);
|
|
110
216
|
});
|
|
111
|
-
|
|
112
|
-
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
let vibe_editor_width = 350;
|
|
113
220
|
|
|
114
|
-
export let
|
|
115
|
-
let api_docs_visible =
|
|
116
|
-
search_params.get("view") === "api" && footer_links.includes("api")
|
|
117
|
-
|
|
118
|
-
let
|
|
119
|
-
|
|
120
|
-
footer_links.includes("api")
|
|
221
|
+
// export let
|
|
222
|
+
let api_docs_visible = $derived(
|
|
223
|
+
search_params.get("view") === "api" && footer_links.includes("api")
|
|
224
|
+
);
|
|
225
|
+
let settings_visible = $derived(search_params.get("view") === "settings");
|
|
226
|
+
let api_recorder_visible = $derived(
|
|
227
|
+
search_params.get("view") === "api-recorder" && footer_links.includes("api")
|
|
228
|
+
);
|
|
121
229
|
let allow_zoom = true;
|
|
122
230
|
let allow_video_trim = true;
|
|
123
231
|
|
|
124
232
|
// Lazy component loading state
|
|
125
|
-
let ApiDocs: ComponentType<
|
|
126
|
-
let ApiRecorder: ComponentType<
|
|
127
|
-
let Settings: ComponentType<
|
|
128
|
-
let VibeEditor:
|
|
233
|
+
let ApiDocs: ComponentType<ApiDocsInterface> | null = null;
|
|
234
|
+
let ApiRecorder: ComponentType<ApiRecorderInterface> | null = null;
|
|
235
|
+
let Settings: ComponentType<SettingsInterface> | null = null;
|
|
236
|
+
let VibeEditor: any = $state(null);
|
|
129
237
|
|
|
130
238
|
async function loadApiDocs(): Promise<void> {
|
|
131
239
|
if (!ApiDocs || !ApiRecorder) {
|
|
@@ -186,104 +294,19 @@
|
|
|
186
294
|
settings_visible = !settings_visible;
|
|
187
295
|
}
|
|
188
296
|
|
|
189
|
-
let api_calls: Payload[] = [];
|
|
190
|
-
|
|
191
297
|
let layout_creating = false;
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
async function handle_update(data: any, fn_index: number): Promise<void> {
|
|
195
|
-
const dep = dependencies.find((dep) => dep.id === fn_index);
|
|
196
|
-
const input_type = components.find(
|
|
197
|
-
(comp) => comp.id === dep?.inputs[0]
|
|
198
|
-
)?.type;
|
|
199
|
-
if (allow_zoom && dep && input_type !== "dataset") {
|
|
200
|
-
if (dep && dep.inputs && dep.inputs.length > 0 && $is_screen_recording) {
|
|
201
|
-
screen_recorder.zoom(true, dep.inputs, 1.0);
|
|
202
|
-
}
|
|
298
|
+
//
|
|
203
299
|
|
|
204
|
-
if (
|
|
205
|
-
dep &&
|
|
206
|
-
dep.outputs &&
|
|
207
|
-
dep.outputs.length > 0 &&
|
|
208
|
-
$is_screen_recording
|
|
209
|
-
) {
|
|
210
|
-
screen_recorder.zoom(false, dep.outputs, 2.0);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
if (!dep) {
|
|
215
|
-
return;
|
|
216
|
-
}
|
|
217
|
-
const outputs = dep.outputs;
|
|
218
|
-
const meta_updates = data?.map((value: any, i: number) => {
|
|
219
|
-
return {
|
|
220
|
-
id: outputs[i],
|
|
221
|
-
prop: "value_is_output",
|
|
222
|
-
value: true
|
|
223
|
-
};
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
update_value(meta_updates);
|
|
227
|
-
|
|
228
|
-
await tick();
|
|
229
|
-
|
|
230
|
-
const updates: UpdateTransaction[] = [];
|
|
231
|
-
|
|
232
|
-
data?.forEach((value: any, i: number) => {
|
|
233
|
-
if (
|
|
234
|
-
typeof value === "object" &&
|
|
235
|
-
value !== null &&
|
|
236
|
-
value.__type__ === "update"
|
|
237
|
-
) {
|
|
238
|
-
for (const [update_key, update_value] of Object.entries(value)) {
|
|
239
|
-
if (update_key === "__type__") {
|
|
240
|
-
continue;
|
|
241
|
-
} else {
|
|
242
|
-
updates.push({
|
|
243
|
-
id: outputs[i],
|
|
244
|
-
prop: update_key,
|
|
245
|
-
value: update_value
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
} else {
|
|
250
|
-
updates.push({
|
|
251
|
-
id: outputs[i],
|
|
252
|
-
prop: "value",
|
|
253
|
-
value
|
|
254
|
-
});
|
|
255
|
-
}
|
|
256
|
-
});
|
|
257
|
-
update_value(updates);
|
|
258
|
-
|
|
259
|
-
// Handle navbar updates separately since they need to be updated in the store.
|
|
260
|
-
updates.forEach((update) => {
|
|
261
|
-
const component = components.find((comp) => comp.id === update.id);
|
|
262
|
-
if (component && component.type === "navbar") {
|
|
263
|
-
import("./navbar_store").then(({ navbar_config }) => {
|
|
264
|
-
navbar_config.update((current) => ({
|
|
265
|
-
...current,
|
|
266
|
-
[update.prop]: update.value
|
|
267
|
-
}));
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
await tick();
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
let submit_map: Map<number, ReturnType<typeof app.submit>> = new Map();
|
|
276
|
-
|
|
277
|
-
let messages: (ToastMessage & { fn_index: number })[] = [];
|
|
278
300
|
function new_message(
|
|
279
301
|
title: string,
|
|
280
302
|
message: string,
|
|
281
303
|
fn_index: number,
|
|
282
304
|
type: ToastMessage["type"],
|
|
283
305
|
duration: number | null = 10,
|
|
284
|
-
visible =
|
|
285
|
-
):
|
|
286
|
-
return
|
|
306
|
+
visible = false
|
|
307
|
+
): void {
|
|
308
|
+
if (!visible) return;
|
|
309
|
+
messages.push({
|
|
287
310
|
title,
|
|
288
311
|
message,
|
|
289
312
|
fn_index,
|
|
@@ -291,16 +314,10 @@
|
|
|
291
314
|
id: ++_error_id,
|
|
292
315
|
duration,
|
|
293
316
|
visible
|
|
294
|
-
};
|
|
317
|
+
});
|
|
295
318
|
}
|
|
296
319
|
|
|
297
|
-
|
|
298
|
-
title: string,
|
|
299
|
-
message: string,
|
|
300
|
-
type: ToastMessage["type"]
|
|
301
|
-
): void {
|
|
302
|
-
messages = [new_message(title, message, -1, type), ...messages];
|
|
303
|
-
}
|
|
320
|
+
add_new_message = new_message;
|
|
304
321
|
|
|
305
322
|
let _error_id = -1;
|
|
306
323
|
|
|
@@ -324,742 +341,9 @@
|
|
|
324
341
|
let inputs_waiting: number[] = [];
|
|
325
342
|
|
|
326
343
|
// as state updates are not synchronous, we need to ensure updates are flushed before triggering any requests
|
|
327
|
-
function wait_then_trigger_api_call(
|
|
328
|
-
dep_index: number,
|
|
329
|
-
trigger_id: number | null = null,
|
|
330
|
-
event_data: unknown = null
|
|
331
|
-
): void {
|
|
332
|
-
let _unsub = (): void => {};
|
|
333
|
-
function unsub(): void {
|
|
334
|
-
_unsub();
|
|
335
|
-
}
|
|
336
|
-
if ($scheduled_updates) {
|
|
337
|
-
_unsub = scheduled_updates.subscribe((updating) => {
|
|
338
|
-
if (!updating) {
|
|
339
|
-
tick().then(() => {
|
|
340
|
-
trigger_api_call(dep_index, trigger_id, event_data);
|
|
341
|
-
unsub();
|
|
342
|
-
});
|
|
343
|
-
}
|
|
344
|
-
});
|
|
345
|
-
} else {
|
|
346
|
-
trigger_api_call(dep_index, trigger_id, event_data);
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
async function get_component_value_or_event_data(
|
|
351
|
-
component_id: number,
|
|
352
|
-
trigger_id: number | null,
|
|
353
|
-
event_data: unknown
|
|
354
|
-
): Promise<any> {
|
|
355
|
-
if (
|
|
356
|
-
component_id === trigger_id &&
|
|
357
|
-
event_data &&
|
|
358
|
-
(event_data as ValueData).is_value_data === true
|
|
359
|
-
) {
|
|
360
|
-
// @ts-ignore
|
|
361
|
-
return event_data.value;
|
|
362
|
-
}
|
|
363
|
-
return get_data(component_id);
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
async function trigger_api_call(
|
|
367
|
-
dep_index: number,
|
|
368
|
-
trigger_id: number | null = null,
|
|
369
|
-
event_data: unknown = null
|
|
370
|
-
): Promise<void> {
|
|
371
|
-
const _dep = dependencies.find((dep) => dep.id === dep_index);
|
|
372
|
-
if (_dep === undefined) {
|
|
373
|
-
return;
|
|
374
|
-
}
|
|
375
|
-
const dep = _dep;
|
|
376
|
-
if (inputs_waiting.length > 0) {
|
|
377
|
-
for (const input of inputs_waiting) {
|
|
378
|
-
if (dep.inputs.includes(input)) {
|
|
379
|
-
add_new_message("Warning", WAITING_FOR_INPUTS_MESSAGE, "warning");
|
|
380
|
-
return;
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
const current_status = loading_status.get_status_for_fn(dep_index);
|
|
385
|
-
messages = messages.filter(({ fn_index }) => fn_index !== dep_index);
|
|
386
|
-
if (current_status === "pending" || current_status === "generating") {
|
|
387
|
-
dep.pending_request = true;
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
let payload: Payload = {
|
|
391
|
-
fn_index: dep_index,
|
|
392
|
-
data: await Promise.all(
|
|
393
|
-
dep.inputs.map((id) =>
|
|
394
|
-
get_component_value_or_event_data(id, trigger_id, event_data)
|
|
395
|
-
)
|
|
396
|
-
),
|
|
397
|
-
event_data: dep.collects_event_data ? event_data : null,
|
|
398
|
-
trigger_id: trigger_id
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
if (dep.frontend_fn && typeof dep.frontend_fn !== "boolean") {
|
|
402
|
-
dep
|
|
403
|
-
.frontend_fn(
|
|
404
|
-
payload.data.concat(
|
|
405
|
-
await Promise.all(dep.outputs.map((id) => get_data(id)))
|
|
406
|
-
)
|
|
407
|
-
)
|
|
408
|
-
.then((v: unknown[]) => {
|
|
409
|
-
if (dep.backend_fn) {
|
|
410
|
-
payload.data = v;
|
|
411
|
-
trigger_prediction(dep, payload);
|
|
412
|
-
} else {
|
|
413
|
-
handle_update(v, dep_index);
|
|
414
|
-
}
|
|
415
|
-
});
|
|
416
|
-
} else if (dep.types.cancel && dep.cancels) {
|
|
417
|
-
await Promise.all(
|
|
418
|
-
dep.cancels.map(async (fn_index) => {
|
|
419
|
-
const submission = submit_map.get(fn_index);
|
|
420
|
-
submission?.cancel();
|
|
421
|
-
return submission;
|
|
422
|
-
})
|
|
423
|
-
);
|
|
424
|
-
} else {
|
|
425
|
-
if (dep.backend_fn) {
|
|
426
|
-
if (dep.js_implementation) {
|
|
427
|
-
let js_fn = new AsyncFunction(
|
|
428
|
-
`let result = await (${dep.js_implementation})(...arguments);
|
|
429
|
-
return (!Array.isArray(result)) ? [result] : result;`
|
|
430
|
-
);
|
|
431
|
-
js_fn(...payload.data)
|
|
432
|
-
.then((js_result) => {
|
|
433
|
-
handle_update(js_result, dep_index);
|
|
434
|
-
payload.js_implementation = true;
|
|
435
|
-
})
|
|
436
|
-
.catch((error) => {
|
|
437
|
-
console.error(error);
|
|
438
|
-
payload.js_implementation = false;
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
trigger_prediction(dep, payload);
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
function trigger_prediction(dep: Dependency, payload: Payload): void {
|
|
446
|
-
if (dep.trigger_mode === "once") {
|
|
447
|
-
if (!dep.pending_request)
|
|
448
|
-
make_prediction(payload, dep.connection == "stream");
|
|
449
|
-
} else if (dep.trigger_mode === "multiple") {
|
|
450
|
-
make_prediction(payload, dep.connection == "stream");
|
|
451
|
-
} else if (dep.trigger_mode === "always_last") {
|
|
452
|
-
if (!dep.pending_request) {
|
|
453
|
-
make_prediction(payload, dep.connection == "stream");
|
|
454
|
-
} else {
|
|
455
|
-
dep.final_event = payload;
|
|
456
|
-
}
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
async function reconnect(): Promise<void> {
|
|
461
|
-
const connection_status = await app.reconnect();
|
|
462
|
-
if (connection_status === "broken") {
|
|
463
|
-
setTimeout(reconnect, 1000);
|
|
464
|
-
} else if (connection_status === "changed") {
|
|
465
|
-
broken_connection = false;
|
|
466
|
-
messages = [
|
|
467
|
-
new_message(
|
|
468
|
-
"Changed Connection",
|
|
469
|
-
CHANGED_CONNECTION_MESSAGE,
|
|
470
|
-
-1,
|
|
471
|
-
"info",
|
|
472
|
-
3,
|
|
473
|
-
true
|
|
474
|
-
),
|
|
475
|
-
...messages.map((m) =>
|
|
476
|
-
m.message === LOST_CONNECTION_MESSAGE ? { ...m, visible: false } : m
|
|
477
|
-
)
|
|
478
|
-
];
|
|
479
|
-
} else if (connection_status === "connected") {
|
|
480
|
-
broken_connection = false;
|
|
481
|
-
messages = [
|
|
482
|
-
new_message(
|
|
483
|
-
"Reconnected",
|
|
484
|
-
RECONNECTION_MESSAGE,
|
|
485
|
-
-1,
|
|
486
|
-
"success",
|
|
487
|
-
null,
|
|
488
|
-
true
|
|
489
|
-
),
|
|
490
|
-
...messages.map((m) =>
|
|
491
|
-
m.message === LOST_CONNECTION_MESSAGE ? { ...m, visible: false } : m
|
|
492
|
-
)
|
|
493
|
-
];
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
|
|
497
|
-
async function make_prediction(
|
|
498
|
-
payload: Payload,
|
|
499
|
-
streaming = false
|
|
500
|
-
): Promise<void> {
|
|
501
|
-
if (allow_video_trim) {
|
|
502
|
-
screen_recorder.markRemoveSegmentStart();
|
|
503
|
-
}
|
|
504
|
-
if (api_recorder_visible) {
|
|
505
|
-
api_calls = [...api_calls, JSON.parse(JSON.stringify(payload))];
|
|
506
|
-
}
|
|
507
|
-
|
|
508
|
-
let submission: ReturnType<typeof app.submit>;
|
|
509
|
-
app.set_current_payload(payload);
|
|
510
|
-
if (streaming) {
|
|
511
|
-
if (!submit_map.has(dep_index)) {
|
|
512
|
-
dep.inputs.forEach((id) => modify_stream(id, "waiting"));
|
|
513
|
-
} else if (
|
|
514
|
-
submit_map.has(dep_index) &&
|
|
515
|
-
dep.inputs.some((id) => get_stream_state(id) === "waiting")
|
|
516
|
-
) {
|
|
517
|
-
return;
|
|
518
|
-
} else if (
|
|
519
|
-
submit_map.has(dep_index) &&
|
|
520
|
-
dep.inputs.some((id) => get_stream_state(id) === "open")
|
|
521
|
-
) {
|
|
522
|
-
await app.post_data(
|
|
523
|
-
// @ts-ignore
|
|
524
|
-
`${app.config.root + app.config.api_prefix}/stream/${submit_map.get(dep_index).event_id()}`,
|
|
525
|
-
{ ...payload, session_hash: app.session_hash }
|
|
526
|
-
);
|
|
527
|
-
return;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
try {
|
|
531
|
-
submission = app.submit(
|
|
532
|
-
payload.fn_index,
|
|
533
|
-
payload.data as unknown[],
|
|
534
|
-
payload.event_data,
|
|
535
|
-
payload.trigger_id
|
|
536
|
-
);
|
|
537
|
-
} catch (e) {
|
|
538
|
-
const fn_index = 0; // Mock value for fn_index
|
|
539
|
-
if (app.closed) return; // when a user navigates away in multipage app.
|
|
540
|
-
messages = [
|
|
541
|
-
new_message("Error", String(e), fn_index, "error"),
|
|
542
|
-
...messages
|
|
543
|
-
];
|
|
544
|
-
loading_status.update({
|
|
545
|
-
status: "error",
|
|
546
|
-
fn_index,
|
|
547
|
-
eta: 0,
|
|
548
|
-
queue: false,
|
|
549
|
-
queue_position: null
|
|
550
|
-
});
|
|
551
|
-
set_status($loading_status);
|
|
552
|
-
return;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
submit_map.set(dep_index, submission);
|
|
556
|
-
|
|
557
|
-
for await (const message of submission) {
|
|
558
|
-
if (payload.js_implementation) {
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
if (message.type === "data") {
|
|
562
|
-
handle_data(message);
|
|
563
|
-
} else if (message.type === "render") {
|
|
564
|
-
handle_render(message);
|
|
565
|
-
} else if (message.type === "status") {
|
|
566
|
-
handle_status_update(message);
|
|
567
|
-
} else if (message.type === "log") {
|
|
568
|
-
handle_log(message);
|
|
569
|
-
}
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
function handle_data(message: Payload): void {
|
|
573
|
-
const { data, fn_index } = message;
|
|
574
|
-
if (dep.pending_request && dep.final_event) {
|
|
575
|
-
dep.pending_request = false;
|
|
576
|
-
make_prediction(dep.final_event, dep.connection == "stream");
|
|
577
|
-
}
|
|
578
|
-
dep.pending_request = false;
|
|
579
|
-
handle_update(data, fn_index);
|
|
580
|
-
set_status($loading_status);
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
function handle_render(message: RenderMessage): void {
|
|
584
|
-
const { data } = message;
|
|
585
|
-
let _components: ComponentMeta[] = data.components;
|
|
586
|
-
let render_layout: LayoutNode = data.layout;
|
|
587
|
-
let _dependencies: Dependency[] = data.dependencies;
|
|
588
|
-
let render_id = data.render_id;
|
|
589
|
-
|
|
590
|
-
let deps_to_remove: number[] = [];
|
|
591
|
-
dependencies.forEach((old_dep, i) => {
|
|
592
|
-
if (old_dep.rendered_in === dep.render_id) {
|
|
593
|
-
deps_to_remove.push(i);
|
|
594
|
-
}
|
|
595
|
-
});
|
|
596
|
-
deps_to_remove.reverse().forEach((i) => {
|
|
597
|
-
dependencies.splice(i, 1);
|
|
598
|
-
});
|
|
599
|
-
_dependencies.forEach((dep) => {
|
|
600
|
-
dependencies.push(dep);
|
|
601
|
-
});
|
|
602
|
-
|
|
603
|
-
rerender_layout({
|
|
604
|
-
components: _components,
|
|
605
|
-
layout: render_layout,
|
|
606
|
-
root: root + api_prefix,
|
|
607
|
-
dependencies: dependencies,
|
|
608
|
-
render_id: render_id
|
|
609
|
-
});
|
|
610
|
-
_dependencies.forEach((dep) => {
|
|
611
|
-
if (dep.targets.some((dep) => dep[1] === "load")) {
|
|
612
|
-
wait_then_trigger_api_call(dep.id);
|
|
613
|
-
}
|
|
614
|
-
});
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
function handle_log(msg: LogMessage): void {
|
|
618
|
-
const { title, log, fn_index, level, duration, visible } = msg;
|
|
619
|
-
messages = [
|
|
620
|
-
new_message(title, log, fn_index, level, duration, visible),
|
|
621
|
-
...messages
|
|
622
|
-
];
|
|
623
|
-
}
|
|
624
|
-
|
|
625
|
-
function open_stream_events(
|
|
626
|
-
status: StatusMessage,
|
|
627
|
-
id: number,
|
|
628
|
-
dep: Dependency
|
|
629
|
-
): void {
|
|
630
|
-
if (
|
|
631
|
-
status.original_msg === "process_starts" &&
|
|
632
|
-
dep.connection === "stream"
|
|
633
|
-
) {
|
|
634
|
-
modify_stream(id, "open");
|
|
635
|
-
}
|
|
636
|
-
}
|
|
637
|
-
|
|
638
|
-
/* eslint-disable complexity */
|
|
639
|
-
function handle_status_update(message: StatusMessage): void {
|
|
640
|
-
if (message.code === "validation_error") {
|
|
641
|
-
const dep = dependencies.find((dep) => dep.id === message.fn_index);
|
|
642
|
-
if (
|
|
643
|
-
dep === undefined ||
|
|
644
|
-
message.message === undefined ||
|
|
645
|
-
typeof message.message === "string"
|
|
646
|
-
) {
|
|
647
|
-
return;
|
|
648
|
-
}
|
|
649
|
-
|
|
650
|
-
const validation_error_data: {
|
|
651
|
-
id: number;
|
|
652
|
-
prop: string;
|
|
653
|
-
value: unknown;
|
|
654
|
-
}[] = [];
|
|
655
|
-
|
|
656
|
-
message.message.forEach((message, i) => {
|
|
657
|
-
if (message.is_valid) {
|
|
658
|
-
return;
|
|
659
|
-
}
|
|
660
|
-
validation_error_data.push({
|
|
661
|
-
id: dep.inputs[i],
|
|
662
|
-
prop: "validation_error",
|
|
663
|
-
value: message.message
|
|
664
|
-
});
|
|
665
|
-
|
|
666
|
-
validation_error_data.push({
|
|
667
|
-
id: dep.inputs[i],
|
|
668
|
-
prop: "loading_status",
|
|
669
|
-
value: { validation_error: message.message }
|
|
670
|
-
});
|
|
671
|
-
});
|
|
672
|
-
|
|
673
|
-
if (validation_error_data.length > 0) {
|
|
674
|
-
update_value(validation_error_data);
|
|
675
|
-
loading_status.update({
|
|
676
|
-
status: "complete",
|
|
677
|
-
fn_index: message.fn_index,
|
|
678
|
-
eta: 0,
|
|
679
|
-
queue: false,
|
|
680
|
-
queue_position: null
|
|
681
|
-
});
|
|
682
|
-
set_status($loading_status);
|
|
683
|
-
|
|
684
|
-
return;
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
if (message.broken && !broken_connection) {
|
|
688
|
-
messages = [
|
|
689
|
-
new_message(
|
|
690
|
-
"Broken Connection",
|
|
691
|
-
LOST_CONNECTION_MESSAGE,
|
|
692
|
-
-1,
|
|
693
|
-
"error",
|
|
694
|
-
null,
|
|
695
|
-
true
|
|
696
|
-
),
|
|
697
|
-
...messages
|
|
698
|
-
];
|
|
699
|
-
|
|
700
|
-
broken_connection = true;
|
|
701
|
-
setTimeout(reconnect, 1000);
|
|
702
|
-
}
|
|
703
|
-
if (message.session_not_found) {
|
|
704
|
-
messages = [
|
|
705
|
-
new_message(
|
|
706
|
-
"Session Not Found",
|
|
707
|
-
SESSION_NOT_FOUND_MESSAGE,
|
|
708
|
-
-1,
|
|
709
|
-
"error",
|
|
710
|
-
null,
|
|
711
|
-
true
|
|
712
|
-
),
|
|
713
|
-
...messages
|
|
714
|
-
];
|
|
715
|
-
}
|
|
716
|
-
const { fn_index, ...status } = message;
|
|
717
|
-
if (status.stage === "streaming" && status.time_limit) {
|
|
718
|
-
dep.inputs.forEach((id) => {
|
|
719
|
-
set_time_limit(id, status.time_limit);
|
|
720
|
-
});
|
|
721
|
-
}
|
|
722
|
-
dep.inputs.forEach((id) => {
|
|
723
|
-
open_stream_events(message, id, dep);
|
|
724
|
-
});
|
|
725
|
-
//@ts-ignore
|
|
726
|
-
loading_status.update({
|
|
727
|
-
...status,
|
|
728
|
-
time_limit: status.time_limit,
|
|
729
|
-
status: status.stage,
|
|
730
|
-
progress: status.progress_data,
|
|
731
|
-
fn_index
|
|
732
|
-
});
|
|
733
|
-
set_status($loading_status);
|
|
734
|
-
if (
|
|
735
|
-
!showed_duplicate_message &&
|
|
736
|
-
space_id !== null &&
|
|
737
|
-
status.position !== undefined &&
|
|
738
|
-
status.position >= 2 &&
|
|
739
|
-
status.eta !== undefined &&
|
|
740
|
-
status.eta > SHOW_DUPLICATE_MESSAGE_ON_ETA
|
|
741
|
-
) {
|
|
742
|
-
showed_duplicate_message = true;
|
|
743
|
-
messages = [
|
|
744
|
-
new_message("Warning", DUPLICATE_MESSAGE, fn_index, "warning"),
|
|
745
|
-
...messages
|
|
746
|
-
];
|
|
747
|
-
}
|
|
748
|
-
if (
|
|
749
|
-
!showed_mobile_warning &&
|
|
750
|
-
is_mobile_device &&
|
|
751
|
-
status.eta !== undefined &&
|
|
752
|
-
status.eta > SHOW_MOBILE_QUEUE_WARNING_ON_ETA
|
|
753
|
-
) {
|
|
754
|
-
showed_mobile_warning = true;
|
|
755
|
-
messages = [
|
|
756
|
-
new_message("Warning", MOBILE_QUEUE_WARNING, fn_index, "warning"),
|
|
757
|
-
...messages
|
|
758
|
-
];
|
|
759
|
-
}
|
|
760
|
-
|
|
761
|
-
if (status.stage === "complete" || status.stage === "generating") {
|
|
762
|
-
const deps_triggered_by_state: Set<Dependency> = new Set();
|
|
763
|
-
status.changed_state_ids?.forEach((id) => {
|
|
764
|
-
dependencies
|
|
765
|
-
.filter((dep) => dep.targets.some(([_id, _]) => _id === id))
|
|
766
|
-
.forEach((dep) => {
|
|
767
|
-
deps_triggered_by_state.add(dep);
|
|
768
|
-
});
|
|
769
|
-
});
|
|
770
|
-
deps_triggered_by_state.forEach((dep) => {
|
|
771
|
-
wait_then_trigger_api_call(dep.id, payload.trigger_id);
|
|
772
|
-
});
|
|
773
|
-
}
|
|
774
|
-
if (status.stage === "complete") {
|
|
775
|
-
dependencies.forEach(async (dep) => {
|
|
776
|
-
if (
|
|
777
|
-
dep.trigger_after === fn_index &&
|
|
778
|
-
!dep.trigger_only_on_failure
|
|
779
|
-
) {
|
|
780
|
-
wait_then_trigger_api_call(dep.id, payload.trigger_id);
|
|
781
|
-
}
|
|
782
|
-
});
|
|
783
|
-
dep.inputs.forEach((id) => {
|
|
784
|
-
modify_stream(id, "closed");
|
|
785
|
-
});
|
|
786
|
-
submit_map.delete(dep_index);
|
|
787
|
-
}
|
|
788
|
-
if (
|
|
789
|
-
status.stage === "error" &&
|
|
790
|
-
!broken_connection &&
|
|
791
|
-
!message.session_not_found
|
|
792
|
-
) {
|
|
793
|
-
if (status.message && typeof status.message === "string") {
|
|
794
|
-
const _message = status.message.replace(
|
|
795
|
-
MESSAGE_QUOTE_RE,
|
|
796
|
-
(_, b) => b
|
|
797
|
-
);
|
|
798
|
-
const _title = status.title ?? "Error";
|
|
799
|
-
messages = [
|
|
800
|
-
new_message(
|
|
801
|
-
_title,
|
|
802
|
-
_message,
|
|
803
|
-
fn_index,
|
|
804
|
-
"error",
|
|
805
|
-
status.duration,
|
|
806
|
-
status.visible
|
|
807
|
-
),
|
|
808
|
-
...messages
|
|
809
|
-
];
|
|
810
|
-
}
|
|
811
|
-
dependencies.map(async (dep) => {
|
|
812
|
-
if (
|
|
813
|
-
dep.trigger_after === fn_index &&
|
|
814
|
-
(!dep.trigger_only_on_success || dep.trigger_only_on_failure)
|
|
815
|
-
) {
|
|
816
|
-
wait_then_trigger_api_call(dep.id, payload.trigger_id);
|
|
817
|
-
}
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
if (allow_video_trim) {
|
|
822
|
-
screen_recorder.markRemoveSegmentEnd();
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
}
|
|
826
|
-
/* eslint-enable complexity */
|
|
827
|
-
|
|
828
|
-
function trigger_share(title: string | undefined, description: string): void {
|
|
829
|
-
if (space_id === null) {
|
|
830
|
-
return;
|
|
831
|
-
}
|
|
832
|
-
const discussion_url = new URL(
|
|
833
|
-
`https://huggingface.co/spaces/${space_id}/discussions/new`
|
|
834
|
-
);
|
|
835
|
-
if (title !== undefined && title.length > 0) {
|
|
836
|
-
discussion_url.searchParams.set("title", title);
|
|
837
|
-
}
|
|
838
|
-
discussion_url.searchParams.set("description", description);
|
|
839
|
-
window.open(discussion_url.toString(), "_blank");
|
|
840
|
-
}
|
|
841
|
-
|
|
842
|
-
function handle_error_close(e: Event & { detail: number }): void {
|
|
843
|
-
const _id = e.detail;
|
|
844
|
-
messages = messages.filter((m) => m.id !== _id);
|
|
845
|
-
}
|
|
846
|
-
|
|
847
|
-
const is_external_url = (link: string | null): boolean =>
|
|
848
|
-
!!(link && new URL(link, location.href).origin !== location.origin);
|
|
849
|
-
|
|
850
|
-
async function handle_mount(): Promise<void> {
|
|
851
|
-
if (js) {
|
|
852
|
-
let blocks_frontend_fn = new AsyncFunction(
|
|
853
|
-
`let result = await (${js})();
|
|
854
|
-
return (!Array.isArray(result)) ? [result] : result;`
|
|
855
|
-
);
|
|
856
|
-
await blocks_frontend_fn();
|
|
857
|
-
}
|
|
858
|
-
|
|
859
|
-
await tick();
|
|
860
|
-
|
|
861
|
-
var a = target.getElementsByTagName("a");
|
|
862
|
-
|
|
863
|
-
for (var i = 0; i < a.length; i++) {
|
|
864
|
-
const _target = a[i].getAttribute("target");
|
|
865
|
-
const _link = a[i].getAttribute("href");
|
|
866
|
-
|
|
867
|
-
// only target anchor tags with external links
|
|
868
|
-
if (is_external_url(_link) && _target !== "_blank")
|
|
869
|
-
a[i].setAttribute("target", "_blank");
|
|
870
|
-
}
|
|
871
|
-
handle_load_triggers();
|
|
872
|
-
|
|
873
|
-
if (!target || render_complete) return;
|
|
874
|
-
|
|
875
|
-
target.addEventListener("prop_change", (e: Event) => {
|
|
876
|
-
if (!isCustomEvent(e)) throw new Error("not a custom event");
|
|
877
|
-
const { id, prop, value } = e.detail;
|
|
878
|
-
if (prop === "value") {
|
|
879
|
-
update_value([
|
|
880
|
-
{
|
|
881
|
-
id,
|
|
882
|
-
prop: "loading_status",
|
|
883
|
-
value: { validation_error: undefined }
|
|
884
|
-
}
|
|
885
|
-
]);
|
|
886
|
-
}
|
|
887
|
-
update_value([{ id, prop, value }]);
|
|
888
|
-
if (prop === "input_ready" && value === false) {
|
|
889
|
-
inputs_waiting.push(id);
|
|
890
|
-
}
|
|
891
|
-
if (prop === "input_ready" && value === true) {
|
|
892
|
-
inputs_waiting = inputs_waiting.filter((item) => item !== id);
|
|
893
|
-
}
|
|
894
|
-
});
|
|
895
|
-
target.addEventListener("gradio", (e: Event) => {
|
|
896
|
-
if (!isCustomEvent(e)) throw new Error("not a custom event");
|
|
897
|
-
|
|
898
|
-
const { id, event, data } = e.detail;
|
|
899
|
-
|
|
900
|
-
if (event === "share") {
|
|
901
|
-
const { title, description } = data as ShareData;
|
|
902
|
-
trigger_share(title, description);
|
|
903
|
-
} else if (event === "error") {
|
|
904
|
-
messages = [new_message("Error", data, -1, event), ...messages];
|
|
905
|
-
} else if (event === "warning") {
|
|
906
|
-
messages = [new_message("Warning", data, -1, event), ...messages];
|
|
907
|
-
} else if (event === "info") {
|
|
908
|
-
messages = [new_message("Info", data, -1, event), ...messages];
|
|
909
|
-
} else if (event == "clear_status") {
|
|
910
|
-
update_status(id, "complete", data);
|
|
911
|
-
} else if (event == "close_stream") {
|
|
912
|
-
const deps = $targets[id]?.[data];
|
|
913
|
-
deps?.forEach((dep_id) => {
|
|
914
|
-
if (submit_map.has(dep_id)) {
|
|
915
|
-
// @ts-ignore
|
|
916
|
-
const url = `${app.config.root + app.config.api_prefix}/stream/${submit_map.get(dep_id).event_id()}`;
|
|
917
|
-
app.post_data(`${url}/close`, {});
|
|
918
|
-
}
|
|
919
|
-
});
|
|
920
|
-
} else {
|
|
921
|
-
const deps = $targets[id]?.[event];
|
|
922
|
-
|
|
923
|
-
deps?.forEach((dep_id) => {
|
|
924
|
-
requestAnimationFrame(() => {
|
|
925
|
-
wait_then_trigger_api_call(dep_id, id, data);
|
|
926
|
-
});
|
|
927
|
-
});
|
|
928
|
-
}
|
|
929
|
-
});
|
|
930
|
-
|
|
931
|
-
render_complete = true;
|
|
932
|
-
}
|
|
933
|
-
|
|
934
|
-
value_change((id, value) => {
|
|
935
|
-
const deps = $targets[id]?.["change"];
|
|
936
|
-
|
|
937
|
-
deps?.forEach((dep_id) => {
|
|
938
|
-
requestAnimationFrame(() => {
|
|
939
|
-
wait_then_trigger_api_call(dep_id, id, value);
|
|
940
|
-
});
|
|
941
|
-
});
|
|
942
|
-
});
|
|
943
|
-
|
|
944
|
-
const handle_load_triggers = (): void => {
|
|
945
|
-
dependencies.forEach((dep) => {
|
|
946
|
-
if (dep.targets.some((dep) => dep[1] === "load")) {
|
|
947
|
-
wait_then_trigger_api_call(dep.id);
|
|
948
|
-
}
|
|
949
|
-
});
|
|
950
|
-
};
|
|
951
|
-
|
|
952
|
-
$: set_status($loading_status);
|
|
953
|
-
|
|
954
|
-
function update_status(
|
|
955
|
-
id: number,
|
|
956
|
-
status: "error" | "complete" | "pending",
|
|
957
|
-
data: LoadingStatus
|
|
958
|
-
): void {
|
|
959
|
-
data.status = status;
|
|
960
|
-
update_value([
|
|
961
|
-
{
|
|
962
|
-
id,
|
|
963
|
-
prop: "loading_status",
|
|
964
|
-
value: data
|
|
965
|
-
}
|
|
966
|
-
]);
|
|
967
|
-
}
|
|
968
|
-
|
|
969
|
-
function set_status(statuses: LoadingStatusCollection): void {
|
|
970
|
-
let updates: {
|
|
971
|
-
id: number;
|
|
972
|
-
prop: string;
|
|
973
|
-
value: LoadingStatus;
|
|
974
|
-
}[] = [];
|
|
975
|
-
Object.entries(statuses).forEach(([id, loading_status]) => {
|
|
976
|
-
if (app.closed && loading_status.status === "error") {
|
|
977
|
-
// when a user navigates away in multipage app.
|
|
978
|
-
return;
|
|
979
|
-
}
|
|
980
|
-
let dependency = dependencies.find(
|
|
981
|
-
(dep) => dep.id == loading_status.fn_index
|
|
982
|
-
);
|
|
983
|
-
if (dependency === undefined) {
|
|
984
|
-
return;
|
|
985
|
-
}
|
|
986
|
-
loading_status.scroll_to_output = dependency.scroll_to_output;
|
|
987
|
-
loading_status.show_progress = dependency.show_progress;
|
|
988
|
-
updates.push({
|
|
989
|
-
id: parseInt(id),
|
|
990
|
-
prop: "loading_status",
|
|
991
|
-
value: loading_status
|
|
992
|
-
});
|
|
993
|
-
});
|
|
994
|
-
|
|
995
|
-
const inputs_to_update = loading_status.get_inputs_to_update();
|
|
996
|
-
const additional_updates = Array.from(inputs_to_update).map(
|
|
997
|
-
([id, pending_status]) => {
|
|
998
|
-
return {
|
|
999
|
-
id,
|
|
1000
|
-
prop: "pending",
|
|
1001
|
-
value: pending_status === "pending"
|
|
1002
|
-
};
|
|
1003
|
-
}
|
|
1004
|
-
);
|
|
1005
|
-
|
|
1006
|
-
update_value([...updates, ...additional_updates]);
|
|
1007
|
-
}
|
|
1008
|
-
|
|
1009
|
-
function isCustomEvent(event: Event): event is CustomEvent {
|
|
1010
|
-
return "detail" in event;
|
|
1011
|
-
}
|
|
1012
344
|
|
|
1013
345
|
let is_screen_recording = writable(false);
|
|
1014
346
|
|
|
1015
|
-
onMount(() => {
|
|
1016
|
-
is_mobile_device =
|
|
1017
|
-
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
1018
|
-
navigator.userAgent
|
|
1019
|
-
);
|
|
1020
|
-
|
|
1021
|
-
screen_recorder.initialize(
|
|
1022
|
-
root,
|
|
1023
|
-
(title, message, type) => {
|
|
1024
|
-
add_new_message(title, message, type);
|
|
1025
|
-
},
|
|
1026
|
-
(isRecording) => {
|
|
1027
|
-
$is_screen_recording = isRecording;
|
|
1028
|
-
}
|
|
1029
|
-
);
|
|
1030
|
-
|
|
1031
|
-
const handleVibeEditorResize = (event: CustomEvent): void => {
|
|
1032
|
-
vibe_editor_width = event.detail.width;
|
|
1033
|
-
};
|
|
1034
|
-
|
|
1035
|
-
window.addEventListener(
|
|
1036
|
-
"vibeEditorResize",
|
|
1037
|
-
handleVibeEditorResize as EventListener
|
|
1038
|
-
);
|
|
1039
|
-
|
|
1040
|
-
// Load components if they should be visible on initial page load
|
|
1041
|
-
if (api_docs_visible) {
|
|
1042
|
-
loadApiDocs();
|
|
1043
|
-
}
|
|
1044
|
-
if (api_recorder_visible) {
|
|
1045
|
-
loadApiRecorder();
|
|
1046
|
-
}
|
|
1047
|
-
if (settings_visible) {
|
|
1048
|
-
loadSettings();
|
|
1049
|
-
}
|
|
1050
|
-
if (vibe_mode) {
|
|
1051
|
-
loadVibeEditor();
|
|
1052
|
-
}
|
|
1053
|
-
});
|
|
1054
|
-
|
|
1055
|
-
function screen_recording(): void {
|
|
1056
|
-
if ($is_screen_recording) {
|
|
1057
|
-
screen_recorder.stopRecording();
|
|
1058
|
-
} else {
|
|
1059
|
-
screen_recorder.startRecording();
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
347
|
let footer_height = 0;
|
|
1064
348
|
|
|
1065
349
|
let root_container: HTMLElement;
|
|
@@ -1077,7 +361,20 @@
|
|
|
1077
361
|
}
|
|
1078
362
|
}
|
|
1079
363
|
|
|
364
|
+
function screen_recording(): void {
|
|
365
|
+
if ($is_screen_recording) {
|
|
366
|
+
screen_recorder.stopRecording();
|
|
367
|
+
} else {
|
|
368
|
+
screen_recorder.startRecording();
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
1080
372
|
onMount(() => {
|
|
373
|
+
is_mobile_device =
|
|
374
|
+
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
|
375
|
+
navigator.userAgent
|
|
376
|
+
);
|
|
377
|
+
|
|
1081
378
|
if ("parentIFrame" in window) {
|
|
1082
379
|
window.parentIFrame?.autoResize(false);
|
|
1083
380
|
}
|
|
@@ -1090,14 +387,26 @@
|
|
|
1090
387
|
subtree: true,
|
|
1091
388
|
attributes: true
|
|
1092
389
|
});
|
|
1093
|
-
|
|
1094
390
|
res.observe(root_container);
|
|
1095
391
|
|
|
392
|
+
app_tree.ready.then(() => {
|
|
393
|
+
ready = true;
|
|
394
|
+
dep_manager.dispatch_load_events();
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
if (vibe_mode) {
|
|
398
|
+
void loadVibeEditor();
|
|
399
|
+
}
|
|
400
|
+
|
|
1096
401
|
return () => {
|
|
1097
402
|
mut.disconnect();
|
|
1098
403
|
res.disconnect();
|
|
1099
404
|
};
|
|
1100
405
|
});
|
|
406
|
+
|
|
407
|
+
function handle_close(id: number): void {
|
|
408
|
+
messages = messages.filter((m) => m.id !== id);
|
|
409
|
+
}
|
|
1101
410
|
</script>
|
|
1102
411
|
|
|
1103
412
|
<svelte:head>
|
|
@@ -1116,167 +425,155 @@
|
|
|
1116
425
|
bind:this={root_container}
|
|
1117
426
|
style:margin-right={vibe_mode ? `${vibe_editor_width}px` : "0"}
|
|
1118
427
|
>
|
|
1119
|
-
{
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
{
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
428
|
+
<MountComponents node={app_tree.root} />
|
|
429
|
+
|
|
430
|
+
{#if footer_links.length > 0}
|
|
431
|
+
<footer bind:clientHeight={footer_height}>
|
|
432
|
+
{#if footer_links.includes("api")}
|
|
433
|
+
<button
|
|
434
|
+
on:click={() => {
|
|
435
|
+
set_api_docs_visible(!api_docs_visible);
|
|
436
|
+
}}
|
|
437
|
+
on:mouseenter={() => {
|
|
438
|
+
loadApiDocs();
|
|
439
|
+
loadApiRecorder();
|
|
440
|
+
}}
|
|
441
|
+
class="show-api"
|
|
442
|
+
>
|
|
443
|
+
{#if app.config?.mcp_server}
|
|
444
|
+
{$_("errors.use_via_api_or_mcp")}
|
|
445
|
+
{:else}
|
|
446
|
+
{$_("errors.use_via_api")}
|
|
447
|
+
{/if}
|
|
448
|
+
<img src={api_logo} alt={$_("common.logo")} />
|
|
449
|
+
</button>
|
|
450
|
+
{/if}
|
|
451
|
+
{#if footer_links.includes("gradio")}
|
|
452
|
+
<div class="divider show-api-divider">·</div>
|
|
453
|
+
<a
|
|
454
|
+
href="https://gradio.app"
|
|
455
|
+
class="built-with"
|
|
456
|
+
target="_blank"
|
|
457
|
+
rel="noreferrer"
|
|
458
|
+
>
|
|
459
|
+
{$_("common.built_with_gradio")}
|
|
460
|
+
<img src={logo} alt={$_("common.logo")} />
|
|
461
|
+
</a>
|
|
462
|
+
{/if}
|
|
1137
463
|
<button
|
|
464
|
+
class:hidden={!$is_screen_recording}
|
|
1138
465
|
on:click={() => {
|
|
1139
|
-
|
|
1140
|
-
}}
|
|
1141
|
-
on:mouseenter={() => {
|
|
1142
|
-
loadApiDocs();
|
|
1143
|
-
loadApiRecorder();
|
|
466
|
+
screen_recording();
|
|
1144
467
|
}}
|
|
1145
|
-
class="
|
|
468
|
+
class="record"
|
|
1146
469
|
>
|
|
1147
|
-
{
|
|
1148
|
-
|
|
1149
|
-
{:else}
|
|
1150
|
-
{$_("errors.use_via_api")}
|
|
1151
|
-
{/if}
|
|
1152
|
-
<img src={api_logo} alt={$_("common.logo")} />
|
|
470
|
+
{$_("common.stop_recording")}
|
|
471
|
+
<img src={record_stop} alt={$_("common.stop_recording")} />
|
|
1153
472
|
</button>
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
class="record"
|
|
1173
|
-
>
|
|
1174
|
-
{$_("common.stop_recording")}
|
|
1175
|
-
<img src={record_stop} alt={$_("common.stop_recording")} />
|
|
1176
|
-
</button>
|
|
1177
|
-
<div class="divider">·</div>
|
|
1178
|
-
{#if footer_links.includes("settings")}
|
|
1179
|
-
<div class="divider" class:hidden={!$is_screen_recording}>·</div>
|
|
1180
|
-
<button
|
|
1181
|
-
on:click={() => {
|
|
1182
|
-
set_settings_visible(!settings_visible);
|
|
1183
|
-
}}
|
|
1184
|
-
on:mouseenter={() => {
|
|
1185
|
-
loadSettings();
|
|
1186
|
-
}}
|
|
1187
|
-
class="settings"
|
|
1188
|
-
>
|
|
1189
|
-
{$_("common.settings")}
|
|
1190
|
-
<img src={settings_logo} alt={$_("common.settings")} />
|
|
1191
|
-
</button>
|
|
1192
|
-
{/if}
|
|
1193
|
-
</footer>
|
|
1194
|
-
{/if}
|
|
1195
|
-
</div>
|
|
1196
|
-
|
|
1197
|
-
{#if api_recorder_visible && ApiRecorder}
|
|
1198
|
-
<!-- TODO: fix -->
|
|
1199
|
-
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
1200
|
-
<!-- svelte-ignore a11y-no-static-element-interactions-->
|
|
1201
|
-
<div
|
|
1202
|
-
id="api-recorder-container"
|
|
1203
|
-
on:click={() => {
|
|
1204
|
-
set_api_docs_visible(true);
|
|
1205
|
-
api_recorder_visible = false;
|
|
1206
|
-
}}
|
|
1207
|
-
>
|
|
1208
|
-
<svelte:component this={ApiRecorder} {api_calls} {dependencies} />
|
|
473
|
+
<div class="divider">·</div>
|
|
474
|
+
{#if footer_links.includes("settings")}
|
|
475
|
+
<div class="divider" class:hidden={!$is_screen_recording}>·</div>
|
|
476
|
+
<button
|
|
477
|
+
on:click={() => {
|
|
478
|
+
set_settings_visible(!settings_visible);
|
|
479
|
+
}}
|
|
480
|
+
on:mouseenter={() => {
|
|
481
|
+
loadSettings();
|
|
482
|
+
}}
|
|
483
|
+
class="settings"
|
|
484
|
+
>
|
|
485
|
+
{$_("common.settings")}
|
|
486
|
+
<img src={settings_logo} alt={$_("common.settings")} />
|
|
487
|
+
</button>
|
|
488
|
+
{/if}
|
|
489
|
+
</footer>
|
|
490
|
+
{/if}
|
|
1209
491
|
</div>
|
|
1210
|
-
{
|
|
1211
|
-
|
|
1212
|
-
{#if api_docs_visible && $_layout && ApiDocs}
|
|
1213
|
-
<div class="api-docs">
|
|
492
|
+
{#if api_recorder_visible && ApiRecorder}
|
|
1214
493
|
<!-- TODO: fix -->
|
|
1215
494
|
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
1216
495
|
<!-- svelte-ignore a11y-no-static-element-interactions-->
|
|
1217
496
|
<div
|
|
1218
|
-
|
|
497
|
+
id="api-recorder-container"
|
|
1219
498
|
on:click={() => {
|
|
1220
|
-
set_api_docs_visible(
|
|
499
|
+
set_api_docs_visible(true);
|
|
500
|
+
api_recorder_visible = false;
|
|
1221
501
|
}}
|
|
1222
|
-
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
502
|
+
>
|
|
503
|
+
<svelte:component this={ApiRecorder} {api_calls} {dependencies} />
|
|
504
|
+
</div>
|
|
505
|
+
{/if}
|
|
506
|
+
|
|
507
|
+
{#if api_docs_visible && app_tree.root && ApiDocs}
|
|
508
|
+
<div class="api-docs">
|
|
509
|
+
<!-- TODO: fix -->
|
|
510
|
+
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
511
|
+
<!-- svelte-ignore a11y-no-static-element-interactions-->
|
|
512
|
+
<div
|
|
513
|
+
class="backdrop"
|
|
514
|
+
on:click={() => {
|
|
1228
515
|
set_api_docs_visible(false);
|
|
1229
|
-
api_calls = [];
|
|
1230
|
-
api_recorder_visible = api_recorder_visible =
|
|
1231
|
-
event.detail?.api_recorder_visible;
|
|
1232
516
|
}}
|
|
1233
|
-
{dependencies}
|
|
1234
|
-
{root}
|
|
1235
|
-
{app}
|
|
1236
|
-
{space_id}
|
|
1237
|
-
{api_calls}
|
|
1238
|
-
{username}
|
|
1239
517
|
/>
|
|
518
|
+
<div class="api-docs-wrap">
|
|
519
|
+
<svelte:component
|
|
520
|
+
this={ApiDocs}
|
|
521
|
+
root_node={app_tree.root}
|
|
522
|
+
on:close={(event) => {
|
|
523
|
+
set_api_docs_visible(false);
|
|
524
|
+
api_calls = [];
|
|
525
|
+
api_recorder_visible = api_recorder_visible =
|
|
526
|
+
event.detail?.api_recorder_visible;
|
|
527
|
+
}}
|
|
528
|
+
{dependencies}
|
|
529
|
+
{root}
|
|
530
|
+
{app}
|
|
531
|
+
{space_id}
|
|
532
|
+
{api_calls}
|
|
533
|
+
{username}
|
|
534
|
+
{last_api_call}
|
|
535
|
+
/>
|
|
536
|
+
</div>
|
|
1240
537
|
</div>
|
|
1241
|
-
|
|
1242
|
-
{/if}
|
|
538
|
+
{/if}
|
|
1243
539
|
|
|
1244
|
-
{#if settings_visible &&
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
set_settings_visible(false);
|
|
1253
|
-
}}
|
|
1254
|
-
/>
|
|
1255
|
-
<div class="api-docs-wrap">
|
|
1256
|
-
<svelte:component
|
|
1257
|
-
this={Settings}
|
|
1258
|
-
bind:allow_zoom
|
|
1259
|
-
bind:allow_video_trim
|
|
1260
|
-
on:close={() => {
|
|
540
|
+
{#if settings_visible && app.config && app_tree.root && Settings}
|
|
541
|
+
<div class="api-docs">
|
|
542
|
+
<!-- TODO: fix -->
|
|
543
|
+
<!-- svelte-ignore a11y-click-events-have-key-events-->
|
|
544
|
+
<!-- svelte-ignore a11y-no-static-element-interactions-->
|
|
545
|
+
<div
|
|
546
|
+
class="backdrop"
|
|
547
|
+
on:click={() => {
|
|
1261
548
|
set_settings_visible(false);
|
|
1262
549
|
}}
|
|
1263
|
-
on:start_recording={() => {
|
|
1264
|
-
screen_recording();
|
|
1265
|
-
}}
|
|
1266
|
-
pwa_enabled={app.config.pwa}
|
|
1267
|
-
{root}
|
|
1268
|
-
{space_id}
|
|
1269
550
|
/>
|
|
551
|
+
<div class="api-docs-wrap">
|
|
552
|
+
<svelte:component
|
|
553
|
+
this={Settings}
|
|
554
|
+
bind:allow_zoom
|
|
555
|
+
bind:allow_video_trim
|
|
556
|
+
on:close={() => {
|
|
557
|
+
set_settings_visible(false);
|
|
558
|
+
}}
|
|
559
|
+
on:start_recording={() => {
|
|
560
|
+
screen_recording();
|
|
561
|
+
}}
|
|
562
|
+
pwa_enabled={app.config.pwa}
|
|
563
|
+
{root}
|
|
564
|
+
{space_id}
|
|
565
|
+
/>
|
|
566
|
+
</div>
|
|
1270
567
|
</div>
|
|
1271
|
-
|
|
1272
|
-
{/if}
|
|
568
|
+
{/if}
|
|
1273
569
|
|
|
1274
|
-
{#if
|
|
1275
|
-
|
|
1276
|
-
{/if}
|
|
570
|
+
{#if vibe_mode && VibeEditor}
|
|
571
|
+
<svelte:component this={VibeEditor} {app} {root} />
|
|
572
|
+
{/if}
|
|
573
|
+
</div>
|
|
1277
574
|
|
|
1278
|
-
{#if
|
|
1279
|
-
<
|
|
575
|
+
{#if messages}
|
|
576
|
+
<Toast {messages} on_close={handle_close} />
|
|
1280
577
|
{/if}
|
|
1281
578
|
|
|
1282
579
|
<style>
|