@gradio/core 1.0.0-dev.0 → 1.0.0-dev.3

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.
Files changed (106) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/src/Blocks.svelte +518 -1001
  5. package/dist/src/Blocks.svelte.d.ts +31 -45
  6. package/dist/src/Embed.svelte +82 -55
  7. package/dist/src/Embed.svelte.d.ts +39 -30
  8. package/dist/src/Login.svelte +33 -29
  9. package/dist/src/Login.svelte.d.ts +21 -19
  10. package/dist/src/MountComponents.svelte +19 -25
  11. package/dist/src/MountComponents.svelte.d.ts +5 -28
  12. package/dist/src/{init.d.ts → _init.d.ts} +5 -4
  13. package/dist/src/{init.js → _init.js} +31 -108
  14. package/dist/src/api_docs/ApiBanner.svelte +12 -8
  15. package/dist/src/api_docs/ApiBanner.svelte.d.ts +22 -20
  16. package/dist/src/api_docs/ApiDocs.svelte +337 -245
  17. package/dist/src/api_docs/ApiDocs.svelte.d.ts +26 -24
  18. package/dist/src/api_docs/ApiRecorder.svelte +9 -3
  19. package/dist/src/api_docs/ApiRecorder.svelte.d.ts +19 -17
  20. package/dist/src/api_docs/CodeSnippet.svelte +60 -30
  21. package/dist/src/api_docs/CodeSnippet.svelte.d.ts +27 -24
  22. package/dist/src/api_docs/CopyButton.svelte +69 -13
  23. package/dist/src/api_docs/CopyButton.svelte.d.ts +18 -16
  24. package/dist/src/api_docs/CopyMarkdown.svelte +734 -0
  25. package/dist/src/api_docs/CopyMarkdown.svelte.d.ts +37 -0
  26. package/dist/src/api_docs/EndpointDetail.svelte +8 -6
  27. package/dist/src/api_docs/EndpointDetail.svelte.d.ts +20 -18
  28. package/dist/src/api_docs/IconArrowUpRight.svelte +34 -0
  29. package/dist/src/api_docs/IconArrowUpRight.svelte.d.ts +20 -0
  30. package/dist/src/api_docs/IconCaret.svelte +39 -0
  31. package/dist/src/api_docs/IconCaret.svelte.d.ts +20 -0
  32. package/dist/src/api_docs/IconHuggingChat.svelte +62 -0
  33. package/dist/src/api_docs/IconHuggingChat.svelte.d.ts +20 -0
  34. package/dist/src/api_docs/InputPayload.svelte +17 -11
  35. package/dist/src/api_docs/InputPayload.svelte.d.ts +25 -23
  36. package/dist/src/api_docs/InstallSnippet.svelte +9 -6
  37. package/dist/src/api_docs/InstallSnippet.svelte.d.ts +18 -16
  38. package/dist/src/api_docs/MCPSnippet.svelte +119 -99
  39. package/dist/src/api_docs/MCPSnippet.svelte.d.ts +59 -58
  40. package/dist/src/api_docs/NoApi.svelte +7 -4
  41. package/dist/src/api_docs/NoApi.svelte.d.ts +20 -18
  42. package/dist/src/api_docs/ParametersSnippet.svelte +8 -6
  43. package/dist/src/api_docs/ParametersSnippet.svelte.d.ts +21 -19
  44. package/dist/src/api_docs/RecordingSnippet.svelte +124 -110
  45. package/dist/src/api_docs/RecordingSnippet.svelte.d.ts +24 -22
  46. package/dist/src/api_docs/ResponseSnippet.svelte +7 -5
  47. package/dist/src/api_docs/ResponseSnippet.svelte.d.ts +21 -19
  48. package/dist/src/api_docs/Settings.svelte +73 -62
  49. package/dist/src/api_docs/Settings.svelte.d.ts +25 -23
  50. package/dist/src/api_docs/SettingsBanner.svelte +11 -8
  51. package/dist/src/api_docs/SettingsBanner.svelte.d.ts +20 -18
  52. package/dist/src/api_docs/TryButton.svelte +5 -3
  53. package/dist/src/api_docs/TryButton.svelte.d.ts +19 -17
  54. package/dist/src/api_docs/img/IconCheck.svelte +33 -0
  55. package/dist/src/api_docs/img/IconCheck.svelte.d.ts +26 -0
  56. package/dist/src/api_docs/img/IconCopy.svelte +40 -0
  57. package/dist/src/api_docs/img/IconCopy.svelte.d.ts +26 -0
  58. package/dist/src/api_docs/img/clear.svelte.d.ts +22 -21
  59. package/dist/src/dependency.d.ts +142 -0
  60. package/dist/src/dependency.js +653 -0
  61. package/dist/src/init.svelte.d.ts +78 -0
  62. package/dist/src/init.svelte.js +469 -0
  63. package/dist/src/init_utils.d.ts +32 -0
  64. package/dist/src/init_utils.js +73 -0
  65. package/dist/src/lang/en.json +10 -1
  66. package/dist/src/lang/get_lang_names.js +0 -3
  67. package/dist/src/lang/ru.json +10 -1
  68. package/dist/src/stores.d.ts +0 -21
  69. package/dist/src/stories/I18nMultiLanguageTestComponent.svelte +5 -3
  70. package/dist/src/stories/I18nMultiLanguageTestComponent.svelte.d.ts +16 -14
  71. package/dist/src/stories/I18nTestSetup.svelte +14 -10
  72. package/dist/src/stories/I18nTestSetup.svelte.d.ts +18 -16
  73. package/dist/src/types.d.ts +30 -26
  74. package/index.ts +1 -1
  75. package/package.json +59 -59
  76. package/src/Blocks.svelte +344 -1063
  77. package/src/MountComponents.svelte +17 -27
  78. package/src/{init.ts → _init.ts} +49 -126
  79. package/src/api_docs/ApiDocs.svelte +65 -60
  80. package/src/api_docs/ApiRecorder.svelte +3 -0
  81. package/src/api_docs/CodeSnippet.svelte +20 -5
  82. package/src/api_docs/CopyButton.svelte +61 -7
  83. package/src/api_docs/CopyMarkdown.svelte +734 -0
  84. package/src/api_docs/IconArrowUpRight.svelte +34 -0
  85. package/src/api_docs/IconCaret.svelte +39 -0
  86. package/src/api_docs/IconHuggingChat.svelte +62 -0
  87. package/src/api_docs/MCPSnippet.svelte +24 -46
  88. package/src/api_docs/ParametersSnippet.svelte +1 -1
  89. package/src/api_docs/ResponseSnippet.svelte +1 -1
  90. package/src/api_docs/Settings.svelte +11 -11
  91. package/src/api_docs/img/IconCheck.svelte +33 -0
  92. package/src/api_docs/img/IconCopy.svelte +40 -0
  93. package/src/dependency.ts +880 -0
  94. package/src/init.svelte.ts +717 -0
  95. package/src/init_utils.ts +99 -0
  96. package/src/lang/en.json +10 -1
  97. package/src/lang/get_lang_names.js +0 -3
  98. package/src/lang/ru.json +10 -1
  99. package/src/stores.ts +22 -22
  100. package/src/types.ts +54 -43
  101. package/dist/src/Render.svelte +0 -105
  102. package/dist/src/Render.svelte.d.ts +0 -31
  103. package/dist/src/RenderComponent.svelte +0 -72
  104. package/dist/src/RenderComponent.svelte.d.ts +0 -33
  105. package/src/Render.svelte +0 -126
  106. package/src/RenderComponent.svelte +0 -91
@@ -0,0 +1,78 @@
1
+ import type { ComponentMeta, ProcessedComponentMeta, LayoutNode, Dependency, AppConfig, ServerFunctions } from "./types";
2
+ import type { SharedProps } from "@gradio/utils";
3
+ import { Client } from "@gradio/client";
4
+ type client_return = Awaited<ReturnType<typeof Client.connect>>;
5
+ type set_data_type = (data: Record<string, unknown>) => void;
6
+ type get_data_type = () => Promise<Record<string, unknown>>;
7
+ type visitor<T> = (node: T) => ProcessedComponentMeta;
8
+ type Tab = {
9
+ label: string;
10
+ id: string;
11
+ visible: boolean;
12
+ interactive: boolean;
13
+ elem_id: string | undefined;
14
+ scale: number | null;
15
+ order?: number;
16
+ };
17
+ export declare class AppTree {
18
+ #private;
19
+ /** Need this to set i18n in re-render */
20
+ reactive_formatter: (str: string) => string;
21
+ client: client_return;
22
+ /** the root node of the processed layout tree */
23
+ root: ProcessedComponentMeta | undefined;
24
+ component_ids: number[];
25
+ initial_tabs: Record<number, Tab[]>;
26
+ components_to_register: Set<number>;
27
+ ready: Promise<void>;
28
+ ready_resolve: () => void;
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;
32
+ /**
33
+ * Registers a component with its ID and data callbacks
34
+ * @param id the ID of the component
35
+ * @param _set_data the set data callback
36
+ * @param _get_data the get data callback
37
+ */
38
+ register_component(id: number, _set_data: set_data_type, _get_data: get_data_type): void;
39
+ /**
40
+ * Preprocess the payloads to get the correct state read to build the tree
41
+ */
42
+ prepare(): void;
43
+ /** Processes the layout payload into a tree of components */
44
+ process(): void;
45
+ postprocess(tree: ProcessedComponentMeta): void;
46
+ find_attached_events(node: ProcessedComponentMeta, dependencies: Dependency[]): ProcessedComponentMeta;
47
+ /**
48
+ * Traverses the layout tree and applies a callback to each node
49
+ * @param node the current layout node
50
+ * @param visit the callback to apply to each node
51
+ * @returns the return value of the callback, with a `children` property added for any child nodes
52
+ */
53
+ traverse<T extends LayoutNode | ProcessedComponentMeta>(node: T, visit: visitor<T> | visitor<T>[]): ProcessedComponentMeta;
54
+ /**
55
+ * Creates a processed component node from a layout node
56
+ * @param opts the layout node options
57
+ * @param root whether this is the root node
58
+ * @returns the processed component node
59
+ */
60
+ create_node(opts: LayoutNode, component_map: Map<number, ComponentMeta>, root?: boolean, reactive_formatter?: (str: string) => string): ProcessedComponentMeta;
61
+ rerender(components: ComponentMeta[], layout: LayoutNode): void;
62
+ update_state(id: number, new_state: Partial<SharedProps> & Record<string, unknown>, check_visibility?: boolean): Promise<void>;
63
+ /**
64
+ * Gets the current state of a component by its ID
65
+ * @param id the ID of the component to get the state of
66
+ * @returns the current state of the component, or null if not found
67
+ */
68
+ get_state(id: number): Promise<Record<string, unknown> | null>;
69
+ }
70
+ /**
71
+ * Process the server function names and return a dictionary of functions
72
+ * @param id the component id
73
+ * @param server_fns the server function names
74
+ * @param app the client instance
75
+ * @returns the actual server functions
76
+ */
77
+ export declare function process_server_fn(id: number, server_fns: string[] | undefined, app: client_return): ServerFunctions;
78
+ export {};
@@ -0,0 +1,469 @@
1
+ import { determine_interactivity, get_component, get_inputs_outputs } from "./init_utils";
2
+ import { translate_if_needed } from "./i18n";
3
+ import { tick } from "svelte";
4
+ import { allowed_shared_props } from "@gradio/utils";
5
+ import { Client } from "@gradio/client";
6
+ const type_map = {
7
+ walkthrough: "tabs",
8
+ walkthroughstep: "tabitem"
9
+ };
10
+ export class AppTree {
11
+ /** the raw component structure received from the backend */
12
+ #component_payload;
13
+ /** the raw layout node structure received from the backend */
14
+ #layout_payload;
15
+ /** the raw dependency structure received from the backend */
16
+ #dependency_payload;
17
+ /** Need this to set i18n in re-render */
18
+ reactive_formatter = (str) => str;
19
+ /** the config for the app */
20
+ #config;
21
+ client;
22
+ /** the root node of the processed layout tree */
23
+ root = $state();
24
+ /** a set of all component IDs that are inputs to dependencies */
25
+ #input_ids = new Set();
26
+ /** a set of all component IDs that are outputs of dependencies */
27
+ #output_ids = new Set();
28
+ /** A list of components that are currently loading */
29
+ #pending_components = [];
30
+ #get_callbacks = new Map();
31
+ #set_callbacks = new Map();
32
+ component_ids;
33
+ initial_tabs = {};
34
+ components_to_register = new Set();
35
+ ready;
36
+ ready_resolve;
37
+ resolved = false;
38
+ constructor(components, layout, dependencies, config, app, reactive_formatter) {
39
+ this.ready = new Promise((resolve) => {
40
+ this.ready_resolve = resolve;
41
+ });
42
+ this.reactive_formatter = reactive_formatter;
43
+ this.#config = config;
44
+ this.#component_payload = components;
45
+ this.#layout_payload = layout;
46
+ this.#dependency_payload = dependencies;
47
+ this.root = this.create_node({ id: layout.id, children: [] }, new Map(), true);
48
+ for (const comp of components) {
49
+ if (comp.props.visible != false)
50
+ this.components_to_register.add(comp.id);
51
+ }
52
+ this.client = app;
53
+ this.prepare();
54
+ const component_map = components.reduce((map, comp) => {
55
+ map.set(comp.id, comp);
56
+ return map;
57
+ }, new Map());
58
+ this.root.children = this.#layout_payload.children.map((node) => this.traverse(node, (node) => {
59
+ const new_node = this.create_node(node, component_map, false, this.reactive_formatter);
60
+ return new_node;
61
+ }));
62
+ this.component_ids = components.map((c) => c.id);
63
+ this.initial_tabs = {};
64
+ gather_initial_tabs(this.root, this.initial_tabs);
65
+ this.postprocess(this.root);
66
+ }
67
+ reload(components, layout, dependencies, config) {
68
+ this.#layout_payload = layout;
69
+ this.#component_payload = components;
70
+ this.#config = config;
71
+ this.#dependency_payload = dependencies;
72
+ this.root = this.create_node({ id: layout.id, children: [] }, new Map(), true);
73
+ for (const comp of components) {
74
+ if (comp.props.visible != false)
75
+ this.components_to_register.add(comp.id);
76
+ }
77
+ this.prepare();
78
+ const component_map = components.reduce((map, comp) => {
79
+ map.set(comp.id, comp);
80
+ return map;
81
+ }, new Map());
82
+ this.root.children = this.#layout_payload.children.map((node) => this.traverse(node, (node) => {
83
+ const new_node = this.create_node(node, component_map, false, this.reactive_formatter);
84
+ return new_node;
85
+ }));
86
+ this.component_ids = components.map((c) => c.id);
87
+ this.initial_tabs = {};
88
+ gather_initial_tabs(this.root, this.initial_tabs);
89
+ this.postprocess(this.root);
90
+ }
91
+ /**
92
+ * Registers a component with its ID and data callbacks
93
+ * @param id the ID of the component
94
+ * @param _set_data the set data callback
95
+ * @param _get_data the get data callback
96
+ */
97
+ register_component(id, _set_data, _get_data) {
98
+ this.#set_callbacks.set(id, _set_data);
99
+ this.#get_callbacks.set(id, _get_data);
100
+ this.components_to_register.delete(id);
101
+ if (this.components_to_register.size === 0 && !this.resolved) {
102
+ this.resolved = true;
103
+ this.ready_resolve();
104
+ }
105
+ }
106
+ /**
107
+ * Preprocess the payloads to get the correct state read to build the tree
108
+ */
109
+ prepare() {
110
+ const [inputs, outputs] = get_inputs_outputs(this.#dependency_payload);
111
+ this.#input_ids = inputs;
112
+ this.#output_ids = outputs;
113
+ }
114
+ /** Processes the layout payload into a tree of components */
115
+ process() { }
116
+ postprocess(tree) {
117
+ this.root = this.traverse(tree, [
118
+ (node) => handle_visibility(node, this.#config.root),
119
+ (node) => untrack_children_of_invisible_parents(node, this.#config.root, this.components_to_register),
120
+ (node) => handle_empty_forms(node, this.#config.root, this.components_to_register),
121
+ (node) => translate_props(node, this.#config.root),
122
+ (node) => apply_initial_tabs(node, this.#config.root, this.initial_tabs),
123
+ (node) => this.find_attached_events(node, this.#dependency_payload)
124
+ ]);
125
+ }
126
+ find_attached_events(node, dependencies) {
127
+ const attached_events = dependencies
128
+ .filter((dep) => dep.targets.find(([id]) => id === node.id))
129
+ .map((dep) => {
130
+ const target = dep.targets.find(([id]) => id === node.id);
131
+ return target ? target[1] : null;
132
+ })
133
+ .filter(Boolean);
134
+ node.props.shared_props.attached_events = attached_events;
135
+ return node;
136
+ }
137
+ /**
138
+ * Traverses the layout tree and applies a callback to each node
139
+ * @param node the current layout node
140
+ * @param visit the callback to apply to each node
141
+ * @returns the return value of the callback, with a `children` property added for any child nodes
142
+ */
143
+ traverse(node, visit) {
144
+ function single_visit(node, visit, traverse_fn) {
145
+ const result = visit(node);
146
+ if ("children" in node && node.children.length > 0) {
147
+ result.children =
148
+ node.children?.map((child) => traverse_fn(child, visit)) || [];
149
+ }
150
+ return result;
151
+ }
152
+ if (Array.isArray(visit)) {
153
+ let result = node;
154
+ for (const v of visit) {
155
+ result = single_visit(result, v, this.traverse.bind(this));
156
+ }
157
+ return result;
158
+ }
159
+ else {
160
+ return single_visit(node, visit, this.traverse.bind(this));
161
+ }
162
+ }
163
+ /**
164
+ * Creates a processed component node from a layout node
165
+ * @param opts the layout node options
166
+ * @param root whether this is the root node
167
+ * @returns the processed component node
168
+ */
169
+ create_node(opts, component_map, root = false, reactive_formatter) {
170
+ let component;
171
+ if (!root) {
172
+ component = component_map.get(opts.id);
173
+ }
174
+ else {
175
+ component = {
176
+ type: "column",
177
+ id: opts.id,
178
+ // @ts-ignore
179
+ props: {
180
+ visible: true,
181
+ root: "",
182
+ theme_mode: "light"
183
+ },
184
+ component_class_id: "column",
185
+ key: null
186
+ };
187
+ }
188
+ if (!component) {
189
+ throw new Error(`Component with ID ${opts.id} not found`);
190
+ }
191
+ if (reactive_formatter) {
192
+ component.props.i18n = reactive_formatter;
193
+ }
194
+ const processed_props = gather_props(opts.id, component.props, [this.#input_ids, this.#output_ids], this.client, { ...this.#config });
195
+ const type = type_map[component.type] || component.type;
196
+ const node = {
197
+ id: opts.id,
198
+ type: type,
199
+ props: processed_props,
200
+ children: [],
201
+ show_progress_on: null,
202
+ component_class_id: component.component_class_id || component.type,
203
+ component: processed_props.shared_props.visible !== false
204
+ ? get_component(component.type, component.component_class_id, this.#config.root || "")
205
+ : null,
206
+ key: component.key,
207
+ rendered_in: component.rendered_in,
208
+ documentation: component.documentation
209
+ };
210
+ return node;
211
+ }
212
+ rerender(components, layout) {
213
+ const component_map = components.reduce((map, comp) => {
214
+ map.set(comp.id, comp);
215
+ return map;
216
+ }, new Map());
217
+ const subtree = this.traverse(layout, (node) => {
218
+ const new_node = this.create_node(node, component_map, false, this.reactive_formatter);
219
+ return new_node;
220
+ });
221
+ const n = find_node_by_id(this.root, subtree.id);
222
+ if (!n) {
223
+ throw new Error("Rerender failed: root node not found in current tree");
224
+ }
225
+ n.children = subtree.children;
226
+ }
227
+ /*
228
+ * Updates the state of a component by its ID
229
+ * @param id the ID of the component to update
230
+ * @param new_state the new state to set
231
+ * */
232
+ async update_state(id, new_state, check_visibility = true) {
233
+ // Visibility is tricky 😅
234
+ // If the component is not visible, it has not been rendered
235
+ // and so it has no _set_data callback
236
+ // Therefore, we need to traverse the tree and set the visible prop to true
237
+ // and then render it and its children. After that, we can call the _set_data callback
238
+ const node = find_node_by_id(this.root, id);
239
+ let already_updated_visibility = false;
240
+ if (check_visibility && !node?.component) {
241
+ await tick();
242
+ this.root = this.traverse(this.root, [
243
+ //@ts-ignore
244
+ (n) => set_visibility_for_updated_node(n, id, new_state.visible),
245
+ (n) => handle_visibility(n, this.#config.root)
246
+ ]);
247
+ already_updated_visibility = true;
248
+ }
249
+ const _set_data = this.#set_callbacks.get(id);
250
+ if (!_set_data)
251
+ return;
252
+ _set_data(new_state);
253
+ if (!check_visibility || already_updated_visibility)
254
+ return;
255
+ // need to let the UI settle before traversing again
256
+ // otherwise there could be
257
+ await tick();
258
+ this.root = this.traverse(this.root, (n) => handle_visibility(n, this.#config.root));
259
+ }
260
+ /**
261
+ * Gets the current state of a component by its ID
262
+ * @param id the ID of the component to get the state of
263
+ * @returns the current state of the component, or null if not found
264
+ */
265
+ async get_state(id) {
266
+ const _get_data = this.#get_callbacks.get(id);
267
+ const component = this.#component_payload.find((c) => c.id === id);
268
+ if (!_get_data && !component)
269
+ return null;
270
+ if (_get_data)
271
+ return await _get_data();
272
+ if (component)
273
+ return Promise.resolve({ value: component.props.value });
274
+ return null;
275
+ }
276
+ }
277
+ /**
278
+ * Process the server function names and return a dictionary of functions
279
+ * @param id the component id
280
+ * @param server_fns the server function names
281
+ * @param app the client instance
282
+ * @returns the actual server functions
283
+ */
284
+ export function process_server_fn(id, server_fns, app) {
285
+ if (!server_fns) {
286
+ return {};
287
+ }
288
+ return server_fns.reduce((acc, fn) => {
289
+ acc[fn] = async (...args) => {
290
+ if (args.length === 1) {
291
+ args = args[0];
292
+ }
293
+ const result = await app.component_server(id, fn, args);
294
+ return result;
295
+ };
296
+ return acc;
297
+ }, {});
298
+ }
299
+ /**
300
+ * Gathers the props for a component
301
+ * @param id the ID of the component
302
+ * @param props the props of the component
303
+ * @param dependencies the component's dependencies
304
+ * @param additional any additional props to include
305
+ * @returns the gathered props as an object with `shared_props` and `props` keys
306
+ */
307
+ function gather_props(id, props, dependencies, client, additional = {}) {
308
+ const _shared_props = {};
309
+ const _props = {};
310
+ for (const key in props) {
311
+ // For Tabs (or any component that already has an id prop)
312
+ // Set the id to the props so that it doesn't get overwritten
313
+ if (key === "id" || key === "autoscroll") {
314
+ _props[key] = props[key];
315
+ }
316
+ else if (allowed_shared_props.includes(key)) {
317
+ const _key = key;
318
+ _shared_props[_key] = props[key];
319
+ if (_key === "server_fns") {
320
+ _shared_props.server = process_server_fn(id, props.server_fns, client);
321
+ }
322
+ }
323
+ else {
324
+ _props[key] = props[key];
325
+ }
326
+ }
327
+ for (const key in additional) {
328
+ if (allowed_shared_props.includes(key)) {
329
+ const _key = key;
330
+ _shared_props[_key] = additional[key];
331
+ }
332
+ else {
333
+ _props[key] = additional[key];
334
+ }
335
+ }
336
+ _shared_props.client = client;
337
+ _shared_props.id = id;
338
+ _shared_props.interactive = determine_interactivity(id, _shared_props.interactive, _props.value, dependencies);
339
+ _shared_props.load_component = (name, variant) => get_component(name, "", _shared_props.root || "", variant);
340
+ _shared_props.visible =
341
+ _shared_props.visible === undefined ? true : _shared_props.visible;
342
+ _shared_props.loading_status = {};
343
+ return { shared_props: _shared_props, props: _props };
344
+ }
345
+ function handle_visibility(node, root) {
346
+ // Check if the node is visible
347
+ if (node.props.shared_props.visible && !node.component) {
348
+ const result = {
349
+ ...node,
350
+ component: get_component(node.type, node.component_class_id, root),
351
+ children: []
352
+ };
353
+ if (node.children) {
354
+ result.children = node.children.map((child) => handle_visibility(child, root));
355
+ }
356
+ return result;
357
+ }
358
+ else {
359
+ return node;
360
+ }
361
+ }
362
+ function set_visibility_for_updated_node(node, id, visible) {
363
+ if (node.id == id) {
364
+ node.props.shared_props.visible = visible;
365
+ }
366
+ return node;
367
+ }
368
+ function _untrack(node, components_to_register) {
369
+ components_to_register.delete(node.id);
370
+ if (node.children) {
371
+ node.children.forEach((child) => _untrack(child, components_to_register));
372
+ }
373
+ return;
374
+ }
375
+ function untrack_children_of_invisible_parents(node, root, components_to_register) {
376
+ // Check if the node is visible
377
+ if (node.props.shared_props.visible !== true) {
378
+ _untrack(node, components_to_register);
379
+ }
380
+ return node;
381
+ }
382
+ function handle_empty_forms(node, root, components_to_register) {
383
+ // Check if the node is visible
384
+ if (node.type === "form") {
385
+ const all_children_invisible = node.children.every((child) => child.props.shared_props.visible === false);
386
+ if (all_children_invisible) {
387
+ node.props.shared_props.visible = false;
388
+ components_to_register.delete(node.id);
389
+ return node;
390
+ }
391
+ }
392
+ return node;
393
+ }
394
+ function translate_props(node, root) {
395
+ const supported_props = [
396
+ "description",
397
+ "info",
398
+ "title",
399
+ "placeholder",
400
+ "value",
401
+ "label"
402
+ ];
403
+ for (const attr of Object.keys(node.props.shared_props)) {
404
+ if (supported_props.includes(attr)) {
405
+ // @ts-ignore
406
+ node.props.shared_props[attr] = translate_if_needed(node.props.shared_props[attr]);
407
+ }
408
+ }
409
+ for (const attr of Object.keys(node.props.props)) {
410
+ if (supported_props.includes(attr)) {
411
+ node.props.props[attr] = translate_if_needed(node.props.props[attr]);
412
+ }
413
+ }
414
+ return node;
415
+ }
416
+ function apply_initial_tabs(node, root, initial_tabs) {
417
+ if (node.type === "tabs" && node.id in initial_tabs) {
418
+ const tabs = initial_tabs[node.id].sort((a, b) => a.order - b.order);
419
+ node.props.props.initial_tabs = tabs;
420
+ }
421
+ return node;
422
+ }
423
+ function _gather_initial_tabs(node, initial_tabs, parent_tab_id, order) {
424
+ if (parent_tab_id !== null && node.type === "tabitem") {
425
+ if (!(parent_tab_id in initial_tabs)) {
426
+ initial_tabs[parent_tab_id] = [];
427
+ }
428
+ if (!("id" in node.props.props)) {
429
+ node.props.props.id = node.id;
430
+ }
431
+ initial_tabs[parent_tab_id].push({
432
+ label: node.props.shared_props.label,
433
+ id: node.props.props.id,
434
+ elem_id: node.props.shared_props.elem_id,
435
+ visible: node.props.shared_props.visible,
436
+ interactive: node.props.shared_props.interactive,
437
+ scale: node.props.shared_props.scale || null
438
+ });
439
+ node.props.props.order = order;
440
+ }
441
+ if (node.children) {
442
+ node.children.forEach((child, i) => {
443
+ _gather_initial_tabs(child, initial_tabs, node.type === "tabs" ? node.id : null, node.type === "tabs" ? i : null);
444
+ });
445
+ }
446
+ return;
447
+ }
448
+ function gather_initial_tabs(node, initial_tabs) {
449
+ function single_visit(node) {
450
+ if ("children" in node && node.children.length > 0) {
451
+ node.children?.forEach((child) => _gather_initial_tabs(child, initial_tabs, node.type === "tabs" ? node.id : null, null));
452
+ }
453
+ }
454
+ return single_visit(node);
455
+ }
456
+ function find_node_by_id(tree, id) {
457
+ if (tree.id === id) {
458
+ return tree;
459
+ }
460
+ if (tree.children) {
461
+ for (const child of tree.children) {
462
+ const result = find_node_by_id(child, id);
463
+ if (result) {
464
+ return result;
465
+ }
466
+ }
467
+ }
468
+ return null;
469
+ }
@@ -0,0 +1,32 @@
1
+ import type { Dependency, LoadingComponent } from "./types";
2
+ /**
3
+ * Load a component given its type and class_id without awaiting it
4
+ * @param type
5
+ * @param class_id
6
+ * @param root
7
+ * @returns the loading component
8
+ */
9
+ export declare function get_component(type: string, class_id: string, root: string, variant?: "component" | "example" | "base"): LoadingComponent;
10
+ /**
11
+ * Get all component ids that are an input dependency and all that are an output dependency
12
+ * @param dep the dependency
13
+ * @param inputs the set of inputs
14
+ * @param outputs the set of outputs
15
+ * @returns a tuple of the inputs and outputs
16
+ */
17
+ export declare function get_inputs_outputs(dependencies: Dependency[]): [Set<number>, Set<number>];
18
+ /**
19
+ * Determines if a component is interactive
20
+ * explicitly set interactive prop takes precedence
21
+ * if not set, then if the component is an input to a dependency, it is interactive
22
+ * if not an input, but has no outputs and no default value, it is interactive (for dev)
23
+ * everything else is not interactive
24
+ * @param id component id
25
+ * @param interactive_prop value of the interactive prop
26
+ * @param value the main value of the component
27
+ * @param dependencies a tuple of sets of input and output component ids
28
+ * @returns if the component is interactive
29
+ */
30
+ export declare function determine_interactivity(id: number, interactive_prop: boolean | undefined, value: any, dependencies: [Set<number>, Set<number>]): boolean;
31
+ /** An async version of 'new Function' */
32
+ export declare const AsyncFunction: new (...args: string[]) => (...args: any[]) => Promise<any>;
@@ -0,0 +1,73 @@
1
+ import { load_component } from "virtual:component-loader";
2
+ /**
3
+ * Load a component given its type and class_id without awaiting it
4
+ * @param type
5
+ * @param class_id
6
+ * @param root
7
+ * @returns the loading component
8
+ */
9
+ export function get_component(type, class_id, root, variant = "component") {
10
+ if (type === "api")
11
+ type = "state";
12
+ return load_component({
13
+ api_url: root,
14
+ name: type,
15
+ id: class_id,
16
+ variant
17
+ }).component;
18
+ }
19
+ /**
20
+ * Get all component ids that are an input dependency and all that are an output dependency
21
+ * @param dep the dependency
22
+ * @param inputs the set of inputs
23
+ * @param outputs the set of outputs
24
+ * @returns a tuple of the inputs and outputs
25
+ */
26
+ export function get_inputs_outputs(dependencies) {
27
+ const inputs = new Set();
28
+ const outputs = new Set();
29
+ for (const dep of dependencies) {
30
+ dep.inputs.forEach((input) => inputs.add(input));
31
+ dep.outputs.forEach((output) => outputs.add(output));
32
+ }
33
+ return [inputs, outputs];
34
+ }
35
+ /**
36
+ * Determines if a component is interactive
37
+ * explicitly set interactive prop takes precedence
38
+ * if not set, then if the component is an input to a dependency, it is interactive
39
+ * if not an input, but has no outputs and no default value, it is interactive (for dev)
40
+ * everything else is not interactive
41
+ * @param id component id
42
+ * @param interactive_prop value of the interactive prop
43
+ * @param value the main value of the component
44
+ * @param dependencies a tuple of sets of input and output component ids
45
+ * @returns if the component is interactive
46
+ */
47
+ export function determine_interactivity(id, interactive_prop, value, dependencies) {
48
+ const [inputs, outputs] = dependencies;
49
+ if (interactive_prop === false) {
50
+ return false;
51
+ }
52
+ else if (interactive_prop === true) {
53
+ return true;
54
+ }
55
+ else if (inputs.has(id) ||
56
+ (!outputs.has(id) && has_no_default_value(value))) {
57
+ return true;
58
+ }
59
+ return false;
60
+ }
61
+ /**
62
+ * Check if a value is not a default value
63
+ * @param value the value to check
64
+ * @returns default value boolean
65
+ */
66
+ function has_no_default_value(value) {
67
+ return ((Array.isArray(value) && value.length === 0) ||
68
+ value === "" ||
69
+ value === 0 ||
70
+ !value);
71
+ }
72
+ /** An async version of 'new Function' */
73
+ export const AsyncFunction = Object.getPrototypeOf(async function () { }).constructor;
@@ -36,7 +36,16 @@
36
36
  "cancel": "Cancel",
37
37
  "like": "Like",
38
38
  "dislike": "Dislike",
39
- "clear": "Clear"
39
+ "clear": "Clear",
40
+ "copy_message": "Copy message",
41
+ "copied_message": "Copied message"
42
+ },
43
+ "chat_interface": {
44
+ "new_chat": "New chat",
45
+ "message_placeholder": "Type a message...",
46
+ "additional_inputs": "Additional inputs",
47
+ "chatbot": "Chatbot",
48
+ "conversation": "Conversation"
40
49
  },
41
50
  "checkbox": {
42
51
  "checkbox": "Checkbox",
@@ -23,6 +23,3 @@ for (const lang of langs) {
23
23
  lang_data?.common?.loading || "Loading...";
24
24
  }
25
25
  }
26
-
27
- console.log(lang_names);
28
- console.log(lang_loading);