@gradio/core 0.11.1 → 0.12.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 CHANGED
@@ -1,5 +1,44 @@
1
1
  # @gradio/core
2
2
 
3
+ ## 0.12.1
4
+
5
+ ### Features
6
+
7
+ - [#10694](https://github.com/gradio-app/gradio/pull/10694) [`16244f3`](https://github.com/gradio-app/gradio/commit/16244f3c1cb1a65ac1f719142f8fab67512fbb25) - Event Listeners in gradio sketch. Thanks @aliabid94!
8
+
9
+ ### Fixes
10
+
11
+ - [#10719](https://github.com/gradio-app/gradio/pull/10719) [`b710d7c`](https://github.com/gradio-app/gradio/commit/b710d7cf13c1277fd18c7809cad0f707b880ef70) - Fix error display. Thanks @aliabid94!
12
+
13
+ ### Dependency updates
14
+
15
+ - @gradio/code@0.11.2
16
+ - @gradio/video@0.14.4
17
+ - @gradio/client@1.13.1
18
+ - @gradio/wasm@0.17.4
19
+ - @gradio/gallery@0.15.9
20
+ - @gradio/upload@0.15.4
21
+ - @gradio/button@0.4.9
22
+ - @gradio/image@0.21.4
23
+ - @gradio/file@0.12.9
24
+
25
+ ## 0.12.0
26
+
27
+ ### Features
28
+
29
+ - [#10500](https://github.com/gradio-app/gradio/pull/10500) [`16d419b`](https://github.com/gradio-app/gradio/commit/16d419b9f1f18ae4507d18a4739eb83ac4f3fae9) - Allow functions that solely update component properties to run in the frontend by setting `js=True`. Thanks @abidlabs!
30
+
31
+ ### Dependency updates
32
+
33
+ - @gradio/upload@0.15.3
34
+ - @gradio/video@0.14.3
35
+ - @gradio/code@0.11.1
36
+ - @gradio/client@1.13.0
37
+ - @gradio/button@0.4.8
38
+ - @gradio/image@0.21.3
39
+ - @gradio/gallery@0.15.8
40
+ - @gradio/file@0.12.8
41
+
3
42
  ## 0.11.1
4
43
 
5
44
  ### Features
@@ -98,7 +98,11 @@ function set_settings_visible(visible) {
98
98
  let api_calls = [];
99
99
  export let render_complete = false;
100
100
  async function handle_update(data, fn_index) {
101
- const outputs = dependencies.find((dep) => dep.id == fn_index).outputs;
101
+ const dep = dependencies.find((dep2) => dep2.id === fn_index);
102
+ if (!dep) {
103
+ return;
104
+ }
105
+ const outputs = dep.outputs;
102
106
  const meta_updates = data?.map((value, i) => {
103
107
  return {
104
108
  id: outputs[i],
@@ -188,7 +192,11 @@ async function get_component_value_or_event_data(component_id, trigger_id, event
188
192
  return get_data(component_id);
189
193
  }
190
194
  async function trigger_api_call(dep_index, trigger_id = null, event_data = null) {
191
- let dep = dependencies.find((dep2) => dep2.id === dep_index);
195
+ const _dep = dependencies.find((dep2) => dep2.id === dep_index);
196
+ if (_dep === void 0) {
197
+ return;
198
+ }
199
+ const dep = _dep;
192
200
  if (inputs_waiting.length > 0) {
193
201
  for (const input of inputs_waiting) {
194
202
  if (dep.inputs.includes(input)) {
@@ -202,6 +210,17 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
202
210
  if (current_status === "pending" || current_status === "generating") {
203
211
  dep.pending_request = true;
204
212
  }
213
+ let deps_to_remove = [];
214
+ if (dep.render_id != null) {
215
+ dependencies.forEach((other_dep, i) => {
216
+ if (other_dep.rendered_in === dep.render_id) {
217
+ deps_to_remove.push(i);
218
+ }
219
+ });
220
+ }
221
+ deps_to_remove.reverse().forEach((i) => {
222
+ dependencies.splice(i, 1);
223
+ });
205
224
  let payload = {
206
225
  fn_index: dep_index,
207
226
  data: await Promise.all(
@@ -212,7 +231,7 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
212
231
  event_data: dep.collects_event_data ? event_data : null,
213
232
  trigger_id
214
233
  };
215
- if (dep.frontend_fn) {
234
+ if (dep.frontend_fn && typeof dep.frontend_fn !== "boolean") {
216
235
  dep.frontend_fn(
217
236
  payload.data.concat(
218
237
  await Promise.all(dep.outputs.map((id) => get_data(id)))
@@ -235,6 +254,19 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
235
254
  );
236
255
  } else {
237
256
  if (dep.backend_fn) {
257
+ if (dep.js_implementation) {
258
+ let js_fn = new AsyncFunction(
259
+ `let result = await (${dep.js_implementation})(...arguments);
260
+ return (!Array.isArray(result)) ? [result] : result;`
261
+ );
262
+ js_fn(...payload.data).then((js_result) => {
263
+ handle_update(js_result, dep_index);
264
+ payload.js_implementation = true;
265
+ }).catch((error) => {
266
+ console.error(error);
267
+ payload.js_implementation = false;
268
+ });
269
+ }
238
270
  trigger_prediction(dep, payload);
239
271
  }
240
272
  }
@@ -281,7 +313,7 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
281
313
  );
282
314
  } catch (e) {
283
315
  const fn_index = 0;
284
- if (!app.stream_status.open)
316
+ if (app.closed)
285
317
  return;
286
318
  messages = [
287
319
  new_message("Error", String(e), fn_index, "error"),
@@ -299,6 +331,9 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
299
331
  }
300
332
  submit_map.set(dep_index, submission);
301
333
  for await (const message of submission) {
334
+ if (payload2.js_implementation) {
335
+ return;
336
+ }
302
337
  if (message.type === "data") {
303
338
  handle_data(message);
304
339
  } else if (message.type === "render") {
@@ -325,15 +360,6 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
325
360
  let render_layout = data.layout;
326
361
  let _dependencies = data.dependencies;
327
362
  let render_id = data.render_id;
328
- let deps_to_remove = [];
329
- dependencies.forEach((dep2, i) => {
330
- if (dep2.rendered_in === render_id) {
331
- deps_to_remove.push(i);
332
- }
333
- });
334
- deps_to_remove.reverse().forEach((i) => {
335
- dependencies.splice(i, 1);
336
- });
337
363
  _dependencies.forEach((dep2) => {
338
364
  dependencies.push(dep2);
339
365
  });
@@ -390,11 +416,15 @@ async function trigger_api_call(dep_index, trigger_id = null, event_data = null)
390
416
  ];
391
417
  }
392
418
  if (status.stage === "complete" || status.stage === "generating") {
419
+ const deps_triggered_by_state = /* @__PURE__ */ new Set();
393
420
  status.changed_state_ids?.forEach((id) => {
394
421
  dependencies.filter((dep2) => dep2.targets.some(([_id, _2]) => _id === id)).forEach((dep2) => {
395
- wait_then_trigger_api_call(dep2.id, payload2.trigger_id);
422
+ deps_triggered_by_state.add(dep2);
396
423
  });
397
424
  });
425
+ deps_triggered_by_state.forEach((dep2) => {
426
+ wait_then_trigger_api_call(dep2.id, payload2.trigger_id);
427
+ });
398
428
  }
399
429
  if (status.stage === "complete") {
400
430
  dependencies.forEach(async (dep2) => {
@@ -548,7 +578,7 @@ function update_status(id, status, data) {
548
578
  function set_status(statuses) {
549
579
  let updates = [];
550
580
  Object.entries(statuses).forEach(([id, loading_status2]) => {
551
- if (!app.stream_status.open && loading_status2.status === "error") {
581
+ if (app.closed && loading_status2.status === "error") {
552
582
  return;
553
583
  }
554
584
  let dependency = dependencies.find(
@@ -45,7 +45,7 @@ export declare const AsyncFunction: new (...args: string[]) => (...args: any[])
45
45
  * @param output_length the number of outputs
46
46
  * @returns The function, or null if the source code is invalid or missing
47
47
  */
48
- export declare function process_frontend_fn(source: string | null | undefined | false, backend_fn: boolean, input_length: number, output_length: number): ((...args: unknown[]) => Promise<unknown[]>) | null;
48
+ export declare function process_frontend_fn(source: string | null | undefined | boolean, backend_fn: boolean, input_length: number, output_length: number): ((...args: unknown[]) => Promise<unknown[]>) | null;
49
49
  /**
50
50
  * `Dependency.targets` is an array of `[id, trigger]` pairs with the ids as the `fn_id`.
51
51
  * This function take a single list of `Dependency.targets` and add those to the target_map.
package/dist/src/init.js CHANGED
@@ -298,7 +298,7 @@ export const AsyncFunction = Object.getPrototypeOf(async function () { }).constr
298
298
  * @returns The function, or null if the source code is invalid or missing
299
299
  */
300
300
  export function process_frontend_fn(source, backend_fn, input_length, output_length) {
301
- if (!source)
301
+ if (!source || source === true)
302
302
  return null;
303
303
  const wrap = backend_fn ? input_length === 1 : output_length === 1;
304
304
  try {
@@ -39,6 +39,7 @@ export interface Payload {
39
39
  data: unknown[];
40
40
  event_data?: unknown | null;
41
41
  trigger_id?: number | null;
42
+ js_implementation?: boolean | null;
42
43
  }
43
44
  /** A dependency as received from the backend */
44
45
  export interface Dependency {
@@ -65,11 +66,13 @@ export interface Dependency {
65
66
  final_event: Payload | null;
66
67
  show_api: boolean;
67
68
  rendered_in: number | null;
69
+ render_id: number | null;
68
70
  connection: "stream" | "sse";
69
71
  time_limit: number;
70
72
  stream_every: number;
71
73
  like_user_message: boolean;
72
74
  event_specific_args: string[];
75
+ js_implementation: string | null;
73
76
  }
74
77
  interface TypeDescription {
75
78
  input_payload?: string;
package/package.json CHANGED
@@ -1,67 +1,67 @@
1
1
  {
2
2
  "name": "@gradio/core",
3
- "version": "0.11.1",
3
+ "version": "0.12.1",
4
4
  "type": "module",
5
5
  "devDependencies": {
6
6
  "@gradio/accordion": "^0.5.8",
7
- "@gradio/annotatedimage": "^0.9.8",
7
+ "@gradio/annotatedimage": "^0.9.10",
8
8
  "@gradio/atoms": "^0.13.3",
9
+ "@gradio/audio": "^0.17.4",
9
10
  "@gradio/box": "^0.2.12",
10
- "@gradio/checkbox": "^0.4.14",
11
- "@gradio/button": "^0.4.7",
12
- "@gradio/chatbot": "^0.24.1",
13
- "@gradio/audio": "^0.17.2",
11
+ "@gradio/button": "^0.4.9",
12
+ "@gradio/chatbot": "^0.24.3",
14
13
  "@gradio/checkboxgroup": "^0.6.14",
15
- "@gradio/client": "^1.12.0",
14
+ "@gradio/client": "^1.13.1",
15
+ "@gradio/checkbox": "^0.4.14",
16
+ "@gradio/code": "^0.11.2",
16
17
  "@gradio/colorpicker": "^0.4.14",
17
- "@gradio/code": "^0.11.0",
18
18
  "@gradio/column": "^0.2.0",
19
- "@gradio/dataframe": "^0.16.3",
20
- "@gradio/dataset": "^0.4.7",
21
- "@gradio/downloadbutton": "^0.3.7",
22
- "@gradio/dropdown": "^0.9.13",
19
+ "@gradio/dataset": "^0.4.9",
20
+ "@gradio/dataframe": "^0.16.5",
23
21
  "@gradio/datetime": "^0.3.6",
22
+ "@gradio/downloadbutton": "^0.3.9",
23
+ "@gradio/dropdown": "^0.9.13",
24
24
  "@gradio/fallback": "^0.4.14",
25
- "@gradio/fileexplorer": "^0.5.18",
26
- "@gradio/file": "^0.12.7",
25
+ "@gradio/file": "^0.12.9",
26
+ "@gradio/fileexplorer": "^0.5.20",
27
+ "@gradio/gallery": "^0.15.9",
27
28
  "@gradio/form": "^0.2.12",
28
29
  "@gradio/group": "^0.2.0",
29
- "@gradio/gallery": "^0.15.7",
30
30
  "@gradio/highlightedtext": "^0.8.14",
31
- "@gradio/html": "^0.6.5",
32
- "@gradio/image": "^0.21.2",
33
- "@gradio/imageeditor": "^0.12.9",
34
31
  "@gradio/icons": "^0.10.0",
35
- "@gradio/label": "^0.5.6",
32
+ "@gradio/html": "^0.6.5",
33
+ "@gradio/image": "^0.21.4",
34
+ "@gradio/imageeditor": "^0.12.11",
36
35
  "@gradio/json": "^0.5.14",
36
+ "@gradio/label": "^0.5.6",
37
37
  "@gradio/browserstate": "^0.3.1",
38
38
  "@gradio/markdown": "^0.13.4",
39
- "@gradio/model3d": "^0.14.2",
39
+ "@gradio/model3d": "^0.14.4",
40
+ "@gradio/multimodaltextbox": "^0.9.10",
40
41
  "@gradio/nativeplot": "^0.5.8",
41
- "@gradio/number": "^0.5.14",
42
- "@gradio/multimodaltextbox": "^0.9.8",
43
42
  "@gradio/paramviewer": "^0.7.2",
43
+ "@gradio/number": "^0.5.14",
44
44
  "@gradio/plot": "^0.9.9",
45
45
  "@gradio/radio": "^0.6.14",
46
46
  "@gradio/row": "^0.2.1",
47
- "@gradio/sidebar": "^0.1.5",
48
- "@gradio/simpledropdown": "^0.3.14",
49
- "@gradio/simpleimage": "^0.8.18",
47
+ "@gradio/sidebar": "^0.1.6",
48
+ "@gradio/simpleimage": "^0.8.20",
50
49
  "@gradio/simpletextbox": "^0.3.14",
50
+ "@gradio/simpledropdown": "^0.3.14",
51
+ "@gradio/sketchbox": "^0.6.1",
51
52
  "@gradio/slider": "^0.6.2",
52
- "@gradio/sketchbox": "^0.6.0",
53
- "@gradio/statustracker": "^0.10.4",
54
53
  "@gradio/state": "^0.1.2",
55
- "@gradio/tabitem": "^0.4.2",
56
54
  "@gradio/tabs": "^0.4.2",
55
+ "@gradio/tabitem": "^0.4.2",
57
56
  "@gradio/textbox": "^0.10.4",
57
+ "@gradio/statustracker": "^0.10.4",
58
58
  "@gradio/theme": "^0.4.0",
59
- "@gradio/upload": "^0.15.2",
60
59
  "@gradio/timer": "^0.4.4",
61
- "@gradio/uploadbutton": "^0.8.7",
62
- "@gradio/wasm": "^0.17.3",
60
+ "@gradio/upload": "^0.15.4",
61
+ "@gradio/uploadbutton": "^0.8.9",
63
62
  "@gradio/utils": "^0.10.1",
64
- "@gradio/video": "^0.14.2"
63
+ "@gradio/video": "^0.14.4",
64
+ "@gradio/wasm": "^0.17.4"
65
65
  },
66
66
  "msw": {
67
67
  "workerDirectory": "public"
package/src/Blocks.svelte CHANGED
@@ -125,7 +125,11 @@
125
125
 
126
126
  export let render_complete = false;
127
127
  async function handle_update(data: any, fn_index: number): Promise<void> {
128
- const outputs = dependencies.find((dep) => dep.id == fn_index)!.outputs;
128
+ const dep = dependencies.find((dep) => dep.id === fn_index);
129
+ if (!dep) {
130
+ return;
131
+ }
132
+ const outputs = dep.outputs;
129
133
 
130
134
  const meta_updates = data?.map((value: any, i: number) => {
131
135
  return {
@@ -263,7 +267,11 @@
263
267
  trigger_id: number | null = null,
264
268
  event_data: unknown = null
265
269
  ): Promise<void> {
266
- let dep = dependencies.find((dep) => dep.id === dep_index)!;
270
+ const _dep = dependencies.find((dep) => dep.id === dep_index);
271
+ if (_dep === undefined) {
272
+ return;
273
+ }
274
+ const dep = _dep;
267
275
  if (inputs_waiting.length > 0) {
268
276
  for (const input of inputs_waiting) {
269
277
  if (dep.inputs.includes(input)) {
@@ -278,6 +286,18 @@
278
286
  dep.pending_request = true;
279
287
  }
280
288
 
289
+ let deps_to_remove: number[] = [];
290
+ if (dep.render_id != null) {
291
+ dependencies.forEach((other_dep, i) => {
292
+ if (other_dep.rendered_in === dep.render_id) {
293
+ deps_to_remove.push(i);
294
+ }
295
+ });
296
+ }
297
+ deps_to_remove.reverse().forEach((i) => {
298
+ dependencies.splice(i, 1);
299
+ });
300
+
281
301
  let payload: Payload = {
282
302
  fn_index: dep_index,
283
303
  data: await Promise.all(
@@ -289,7 +309,7 @@
289
309
  trigger_id: trigger_id
290
310
  };
291
311
 
292
- if (dep.frontend_fn) {
312
+ if (dep.frontend_fn && typeof dep.frontend_fn !== "boolean") {
293
313
  dep
294
314
  .frontend_fn(
295
315
  payload.data.concat(
@@ -314,6 +334,21 @@
314
334
  );
315
335
  } else {
316
336
  if (dep.backend_fn) {
337
+ if (dep.js_implementation) {
338
+ let js_fn = new AsyncFunction(
339
+ `let result = await (${dep.js_implementation})(...arguments);
340
+ return (!Array.isArray(result)) ? [result] : result;`
341
+ );
342
+ js_fn(...payload.data)
343
+ .then((js_result) => {
344
+ handle_update(js_result, dep_index);
345
+ payload.js_implementation = true;
346
+ })
347
+ .catch((error) => {
348
+ console.error(error);
349
+ payload.js_implementation = false;
350
+ });
351
+ }
317
352
  trigger_prediction(dep, payload);
318
353
  }
319
354
  }
@@ -372,7 +407,7 @@
372
407
  );
373
408
  } catch (e) {
374
409
  const fn_index = 0; // Mock value for fn_index
375
- if (!app.stream_status.open) return; // when a user navigates away in multipage app.
410
+ if (app.closed) return; // when a user navigates away in multipage app.
376
411
  messages = [
377
412
  new_message("Error", String(e), fn_index, "error"),
378
413
  ...messages
@@ -391,6 +426,9 @@
391
426
  submit_map.set(dep_index, submission);
392
427
 
393
428
  for await (const message of submission) {
429
+ if (payload.js_implementation) {
430
+ return;
431
+ }
394
432
  if (message.type === "data") {
395
433
  handle_data(message);
396
434
  } else if (message.type === "render") {
@@ -420,15 +458,6 @@
420
458
  let _dependencies: Dependency[] = data.dependencies;
421
459
  let render_id = data.render_id;
422
460
 
423
- let deps_to_remove: number[] = [];
424
- dependencies.forEach((dep, i) => {
425
- if (dep.rendered_in === render_id) {
426
- deps_to_remove.push(i);
427
- }
428
- });
429
- deps_to_remove.reverse().forEach((i) => {
430
- dependencies.splice(i, 1);
431
- });
432
461
  _dependencies.forEach((dep) => {
433
462
  dependencies.push(dep);
434
463
  });
@@ -511,13 +540,17 @@
511
540
  }
512
541
 
513
542
  if (status.stage === "complete" || status.stage === "generating") {
543
+ const deps_triggered_by_state: Set<Dependency> = new Set();
514
544
  status.changed_state_ids?.forEach((id) => {
515
545
  dependencies
516
546
  .filter((dep) => dep.targets.some(([_id, _]) => _id === id))
517
547
  .forEach((dep) => {
518
- wait_then_trigger_api_call(dep.id, payload.trigger_id);
548
+ deps_triggered_by_state.add(dep);
519
549
  });
520
550
  });
551
+ deps_triggered_by_state.forEach((dep) => {
552
+ wait_then_trigger_api_call(dep.id, payload.trigger_id);
553
+ });
521
554
  }
522
555
  if (status.stage === "complete") {
523
556
  dependencies.forEach(async (dep) => {
@@ -701,7 +734,7 @@
701
734
  value: LoadingStatus;
702
735
  }[] = [];
703
736
  Object.entries(statuses).forEach(([id, loading_status]) => {
704
- if (!app.stream_status.open && loading_status.status === "error") {
737
+ if (app.closed && loading_status.status === "error") {
705
738
  // when a user navigates away in multipage app.
706
739
  return;
707
740
  }
package/src/init.ts CHANGED
@@ -478,12 +478,12 @@ export const AsyncFunction: new (
478
478
  * @returns The function, or null if the source code is invalid or missing
479
479
  */
480
480
  export function process_frontend_fn(
481
- source: string | null | undefined | false,
481
+ source: string | null | undefined | boolean,
482
482
  backend_fn: boolean,
483
483
  input_length: number,
484
484
  output_length: number
485
485
  ): ((...args: unknown[]) => Promise<unknown[]>) | null {
486
- if (!source) return null;
486
+ if (!source || source === true) return null;
487
487
 
488
488
  const wrap = backend_fn ? input_length === 1 : output_length === 1;
489
489
  try {
package/src/types.ts CHANGED
@@ -43,6 +43,7 @@ export interface Payload {
43
43
  data: unknown[];
44
44
  event_data?: unknown | null;
45
45
  trigger_id?: number | null;
46
+ js_implementation?: boolean | null;
46
47
  }
47
48
 
48
49
  /** A dependency as received from the backend */
@@ -70,11 +71,13 @@ export interface Dependency {
70
71
  final_event: Payload | null;
71
72
  show_api: boolean;
72
73
  rendered_in: number | null;
74
+ render_id: number | null;
73
75
  connection: "stream" | "sse";
74
76
  time_limit: number;
75
77
  stream_every: number;
76
78
  like_user_message: boolean;
77
79
  event_specific_args: string[];
80
+ js_implementation: string | null;
78
81
  }
79
82
 
80
83
  interface TypeDescription {