@gradio/client 2.2.0 → 2.2.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,11 @@
1
1
  # @gradio/client
2
2
 
3
+ ## 2.2.1
4
+
5
+ ### Fixes
6
+
7
+ - [#13403](https://github.com/gradio-app/gradio/pull/13403) [`df56862`](https://github.com/gradio-app/gradio/commit/df56862a1531fc372a3248716dc4bd07e6db1c52) - [js-client] close submit iterator on next/close race. Thanks @hysts!
8
+
3
9
  ## 2.2.0
4
10
 
5
11
  ### Features
package/dist/browser.js CHANGED
@@ -1,5 +1,5 @@
1
- const Ke = "host", Ae = "queue/data", Ve = "queue/join", we = "upload", Ye = "login", K = "config", Qe = "info", Xe = "runtime", et = "sleeptime", tt = "heartbeat", st = "component_server", nt = "reset", ot = "cancel", it = "app_id", xe = "This application is currently busy. Please try again. ", L = "Connection errored out. ", C = "Could not resolve app config. ", rt = "Could not get space status. ", at = "Could not get API info. ", ue = "Space metadata could not be loaded. ", ct = "Invalid URL. A full URL path is required.", ut = "Not authorized to access this space. ", De = "Invalid credentials. Could not login. ", lt = "Login credentials are required to access this space.", pt = "File system access is only available in Node.js environments", Ce = "Root URL not found in client config", dt = "Error uploading file";
2
- async function ye(e, s, t) {
1
+ const Ke = "host", xe = "queue/data", Ve = "queue/join", ye = "upload", Ye = "login", K = "config", Qe = "info", Xe = "runtime", et = "sleeptime", tt = "heartbeat", st = "component_server", nt = "reset", ot = "cancel", it = "app_id", De = "This application is currently busy. Please try again. ", L = "Connection errored out. ", C = "Could not resolve app config. ", rt = "Could not get space status. ", at = "Could not get API info. ", ue = "Space metadata could not be loaded. ", ct = "Invalid URL. A full URL path is required.", ut = "Not authorized to access this space. ", Ce = "Invalid credentials. Could not login. ", lt = "Login credentials are required to access this space.", pt = "File system access is only available in Node.js environments", Le = "Root URL not found in client config", dt = "Error uploading file";
2
+ async function be(e, s, t) {
3
3
  try {
4
4
  return (await (await fetch(`https://huggingface.co/api/spaces/${e}/jwt`, {
5
5
  headers: {
@@ -28,7 +28,7 @@ async function ft(e) {
28
28
  const n = await this.fetch(t, {
29
29
  headers: s,
30
30
  credentials: "include"
31
- }), o = await be(n, !!this.options.auth);
31
+ }), o = await ve(n, !!this.options.auth);
32
32
  o.root = e || o.root, window.gradio_config = {
33
33
  ...o,
34
34
  current_page: window.gradio_config.current_page
@@ -43,17 +43,17 @@ async function ft(e) {
43
43
  const n = await this.fetch(t, {
44
44
  headers: s,
45
45
  credentials: "include"
46
- }), o = await be(n, !!this.options.auth);
46
+ }), o = await ve(n, !!this.options.auth);
47
47
  return o.root || (o.root = e), o;
48
48
  }
49
49
  throw new Error(C);
50
50
  }
51
- async function be(e, s) {
51
+ async function ve(e, s) {
52
52
  if (e?.status === 401 && !s) {
53
53
  const n = (await e.json())?.detail?.auth_message;
54
54
  throw new Error(n || lt);
55
55
  } else if (e?.status === 401 && s)
56
- throw new Error(De);
56
+ throw new Error(Ce);
57
57
  if (e?.status === 200) {
58
58
  let t = await e.json();
59
59
  return t.dependencies?.forEach((n, o) => {
@@ -70,7 +70,7 @@ async function _t() {
70
70
  );
71
71
  try {
72
72
  if (this.options.auth) {
73
- const t = await Le(
73
+ const t = await Ne(
74
74
  e,
75
75
  s,
76
76
  this.options.auth,
@@ -83,7 +83,7 @@ async function _t() {
83
83
  throw Error(t.message);
84
84
  }
85
85
  }
86
- async function Le(e, s, t, n, o) {
86
+ async function Ne(e, s, t, n, o) {
87
87
  const r = new FormData();
88
88
  r.append("username", t?.[0]), r.append("password", t?.[1]);
89
89
  let i = {};
@@ -96,7 +96,7 @@ async function Le(e, s, t, n, o) {
96
96
  });
97
97
  if (a.status === 200)
98
98
  return a.headers.get("set-cookie");
99
- throw a.status === 401 ? new Error(De) : new Error(ue);
99
+ throw a.status === 401 ? new Error(Ce) : new Error(ue);
100
100
  }
101
101
  function re(e) {
102
102
  if (e.startsWith("http")) {
@@ -113,7 +113,7 @@ function re(e) {
113
113
  host: new URL(e).host
114
114
  };
115
115
  }
116
- const Ne = (e) => {
116
+ const Pe = (e) => {
117
117
  let s = [];
118
118
  return e.split(/,(?=\s*[^\s=;]+=[^\s=;]+)/).forEach((n) => {
119
119
  const [o, r] = n.split(";")[0].split("=");
@@ -233,7 +233,7 @@ function wt(e, s, t, n) {
233
233
  function yt(e, s) {
234
234
  return s === "GallerySerializable" ? "array of [file, label] tuples" : s === "ListStringSerializable" ? "array of strings" : s === "FileSerializable" ? "array of files or single file" : e?.description;
235
235
  }
236
- function ve(e, s) {
236
+ function Ee(e, s) {
237
237
  switch (e.msg) {
238
238
  case "send_data":
239
239
  return { type: "data" };
@@ -244,7 +244,7 @@ function ve(e, s) {
244
244
  type: "update",
245
245
  status: {
246
246
  queue: !0,
247
- message: xe,
247
+ message: De,
248
248
  stage: "error",
249
249
  code: e.code,
250
250
  success: e.success
@@ -433,7 +433,7 @@ async function Et(e, s, t) {
433
433
  l.append("files", c);
434
434
  });
435
435
  try {
436
- const c = t ? `${e}${this.api_prefix}/${we}?upload_id=${t}` : `${e}${this.api_prefix}/${we}`;
436
+ const c = t ? `${e}${this.api_prefix}/${ye}?upload_id=${t}` : `${e}${this.api_prefix}/${ye}`;
437
437
  i = await this.fetch(c, {
438
438
  method: "POST",
439
439
  body: l,
@@ -461,14 +461,14 @@ const St = {
461
461
  }, kt = {
462
462
  radix: 1024,
463
463
  unit: ["b", "Kb", "Mb", "Gb", "Tb", "Pb", "Eb", "Zb", "Yb"]
464
- }, Ee = {
464
+ }, Se = {
465
465
  si: St,
466
466
  iec: $t,
467
467
  jedec: kt
468
468
  };
469
469
  function Rt(e, s = 1, t = "jedec") {
470
470
  e = Math.abs(e);
471
- const { radix: n, unit: o } = Ee[t] || Ee.jedec;
471
+ const { radix: n, unit: o } = Se[t] || Se.jedec;
472
472
  let r = 0;
473
473
  for (; e >= n; )
474
474
  e /= n, ++r;
@@ -536,7 +536,7 @@ class Q {
536
536
  this.path = s, this.url = t, this.orig_name = n, this.size = o, this.blob = t ? void 0 : r, this.is_stream = i, this.mime_type = a, this.alt_text = u, this.b64 = l;
537
537
  }
538
538
  }
539
- class Pe {
539
+ class je {
540
540
  type;
541
541
  command;
542
542
  meta;
@@ -546,7 +546,7 @@ class Pe {
546
546
  }
547
547
  }
548
548
  const Tt = typeof process < "u" && process.versions && process.versions.node;
549
- function Se(e, s, t) {
549
+ function $e(e, s, t) {
550
550
  for (; t.length > 1; ) {
551
551
  const o = t.shift();
552
552
  if (typeof o == "string" || typeof o == "number")
@@ -627,7 +627,7 @@ function os(e) {
627
627
  meta: { _type: "gradio.FileData" }
628
628
  };
629
629
  if (Tt)
630
- return new Pe("upload_file", {
630
+ return new je("upload_file", {
631
631
  path: e,
632
632
  name: e,
633
633
  orig_path: e
@@ -695,27 +695,27 @@ async function Dt(e, s, t) {
695
695
  })
696
696
  )).forEach(({ path: i, file_url: a, type: u, name: l }) => {
697
697
  if (u === "Gallery")
698
- Se(s, a, i);
698
+ $e(s, a, i);
699
699
  else if (a) {
700
700
  const p = new Q({ path: a, orig_name: l });
701
- Se(s, p, i);
701
+ $e(s, p, i);
702
702
  }
703
703
  }), s;
704
704
  }
705
705
  async function Ct(e, s) {
706
706
  if (!(e.config?.root || e.config?.root_url))
707
- throw new Error(Ce);
708
- await je(e, s);
707
+ throw new Error(Le);
708
+ await Ie(e, s);
709
709
  }
710
- async function je(e, s, t = []) {
710
+ async function Ie(e, s, t = []) {
711
711
  for (const n in s)
712
- s[n] instanceof Pe ? await Lt(e, s, n) : typeof s[n] == "object" && s[n] !== null && await je(e, s[n], [...t, n]);
712
+ s[n] instanceof je ? await Lt(e, s, n) : typeof s[n] == "object" && s[n] !== null && await Ie(e, s[n], [...t, n]);
713
713
  }
714
714
  async function Lt(e, s, t) {
715
715
  let n = s[t];
716
716
  const o = e.config?.root || e.config?.root_url;
717
717
  if (!o)
718
- throw new Error(Ce);
718
+ throw new Error(Le);
719
719
  try {
720
720
  let r, i;
721
721
  if (typeof process < "u" && process.versions && process.versions.node) {
@@ -815,7 +815,7 @@ async function F(e, s, t) {
815
815
  load_status: "error",
816
816
  message: "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
817
817
  detail: i,
818
- discussions_enabled: await $e(a)
818
+ discussions_enabled: await ke(a)
819
819
  });
820
820
  break;
821
821
  case "RUNNING":
@@ -853,12 +853,12 @@ async function F(e, s, t) {
853
853
  load_status: "error",
854
854
  message: "This space is experiencing an issue.",
855
855
  detail: i,
856
- discussions_enabled: await $e(a)
856
+ discussions_enabled: await ke(a)
857
857
  });
858
858
  break;
859
859
  }
860
860
  }
861
- const Ie = async (e, s) => {
861
+ const Ue = async (e, s) => {
862
862
  let t = 0;
863
863
  const n = 12, o = 5e3;
864
864
  return new Promise((r) => {
@@ -867,13 +867,13 @@ const Ie = async (e, s) => {
867
867
  le.test(e) ? "space_name" : "subdomain",
868
868
  (i) => {
869
869
  s(i), i.status === "running" || i.status === "error" || i.status === "paused" || i.status === "space_error" ? r() : (i.status === "sleeping" || i.status === "building") && (t < n ? (t++, setTimeout(() => {
870
- Ie(e, s).then(r);
870
+ Ue(e, s).then(r);
871
871
  }, o)) : r());
872
872
  }
873
873
  );
874
874
  });
875
875
  }, jt = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
876
- async function $e(e) {
876
+ async function ke(e) {
877
877
  try {
878
878
  const s = await fetch(
879
879
  `https://huggingface.co/api/spaces/${e}/discussions`,
@@ -926,7 +926,7 @@ async function Ut(e, s, t) {
926
926
  throw new Error(r.message);
927
927
  }
928
928
  }
929
- const ke = [
929
+ const Re = [
930
930
  "cpu-basic",
931
931
  "cpu-upgrade",
932
932
  "cpu-xl",
@@ -943,20 +943,20 @@ const ke = [
943
943
  ];
944
944
  async function qt(e, s) {
945
945
  const { token: t, private: n, hardware: o, timeout: r, auth: i } = s;
946
- if (o && !ke.includes(o))
946
+ if (o && !Re.includes(o))
947
947
  throw new Error(
948
- `Invalid hardware type provided. Valid types are: ${ke.map((m) => `"${m}"`).join(",")}.`
948
+ `Invalid hardware type provided. Valid types are: ${Re.map((m) => `"${m}"`).join(",")}.`
949
949
  );
950
950
  const { http_protocol: a, host: u } = await pe(e, t);
951
951
  let l = null;
952
952
  if (i) {
953
- const m = await Le(
953
+ const m = await Ne(
954
954
  a,
955
955
  u,
956
956
  i,
957
957
  fetch
958
958
  );
959
- m && (l = Ne(m));
959
+ m && (l = Pe(m));
960
960
  }
961
961
  const p = {
962
962
  Authorization: `Bearer ${t}`,
@@ -1007,22 +1007,22 @@ function zt(e) {
1007
1007
  if (t)
1008
1008
  return t[1];
1009
1009
  }
1010
- const Re = "supports-zerogpu-headers";
1011
- let Oe = !1;
1010
+ const Oe = "supports-zerogpu-headers";
1011
+ let Te = !1;
1012
1012
  function Bt() {
1013
1013
  return typeof window < "u" && typeof document < "u" && typeof window.addEventListener == "function";
1014
1014
  }
1015
- function Ue(e) {
1015
+ function qe(e) {
1016
1016
  return e.includes(".dev.") ? `https://moon-${e.split(".")[1]}.dev.spaces.huggingface.tech` : e.endsWith(".hf.space") ? "https://huggingface.co" : null;
1017
1017
  }
1018
1018
  function Gt() {
1019
- if (!Bt() || Oe)
1019
+ if (!Bt() || Te)
1020
1020
  return;
1021
1021
  window.addEventListener("message", (s) => {
1022
- s.data === Re && (window.supports_zerogpu_headers = !0);
1023
- }), Oe = !0;
1024
- const e = Ue(window.location.hostname);
1025
- e && window.parent !== window && window.parent.postMessage(Re, e);
1022
+ s.data === Oe && (window.supports_zerogpu_headers = !0);
1023
+ }), Te = !0;
1024
+ const e = qe(window.location.hostname);
1025
+ e && window.parent !== window && window.parent.postMessage(Oe, e);
1026
1026
  }
1027
1027
  class Mt extends TransformStream {
1028
1028
  #e = "";
@@ -1065,7 +1065,7 @@ function Ht(e) {
1065
1065
  e.substring(n + t[0].length)
1066
1066
  ];
1067
1067
  }
1068
- function Te(e, s, t) {
1068
+ function Ae(e, s, t) {
1069
1069
  e.get(s) || e.set(s, t);
1070
1070
  }
1071
1071
  async function* Jt(e, s) {
@@ -1088,7 +1088,7 @@ async function* Jt(e, s) {
1088
1088
  }
1089
1089
  async function Wt(e, s) {
1090
1090
  let t = new Request(e, s);
1091
- Te(t.headers, "Accept", "text/event-stream"), Te(t.headers, "Content-Type", "application/json");
1091
+ Ae(t.headers, "Accept", "text/event-stream"), Ae(t.headers, "Content-Type", "application/json");
1092
1092
  let n = await fetch(t);
1093
1093
  if (!n.ok)
1094
1094
  throw n;
@@ -1109,7 +1109,7 @@ async function Zt() {
1109
1109
  n.open = !0;
1110
1110
  let a = null, u = new URLSearchParams({
1111
1111
  session_hash: this.session_hash
1112
- }).toString(), l = new URL(`${o.root}${this.api_prefix}/${Ae}?${u}`);
1112
+ }).toString(), l = new URL(`${o.root}${this.api_prefix}/${xe}?${u}`);
1113
1113
  if (r && l.searchParams.set("__sign", r), a = this.stream(l), !a) {
1114
1114
  console.warn("Cannot connect to SSE endpoint: " + l.toString());
1115
1115
  return;
@@ -1232,9 +1232,9 @@ function Qt(e, s = {}) {
1232
1232
  function Xt(e, s = {}, t, n, o, r) {
1233
1233
  try {
1234
1234
  let i = function(h) {
1235
- (o || Ge[h.type]) && p(h);
1235
+ (o || Me[h.type]) && p(h);
1236
1236
  }, a = function() {
1237
- for (Je = !0; M.length > 0; )
1237
+ for (me = !0; M.length > 0; )
1238
1238
  M.shift()({
1239
1239
  value: void 0,
1240
1240
  done: !0
@@ -1246,7 +1246,7 @@ function Xt(e, s = {}, t, n, o, r) {
1246
1246
  }, p = function(h) {
1247
1247
  u({ value: h, done: !1 });
1248
1248
  }, c = function() {
1249
- return oe.length > 0 ? Promise.resolve(oe.shift()) : new Promise((h) => M.push(h));
1249
+ return oe.length > 0 ? Promise.resolve(oe.shift()) : me ? Promise.resolve({ value: void 0, done: !0 }) : new Promise((h) => M.push(h));
1250
1250
  };
1251
1251
  const { token: g } = this.options, {
1252
1252
  fetch: w,
@@ -1259,11 +1259,11 @@ function Xt(e, s = {}, t, n, o, r) {
1259
1259
  pending_stream_messages: ee,
1260
1260
  pending_diff_streams: te,
1261
1261
  event_callbacks: se,
1262
- unclosed_events: qe,
1262
+ unclosed_events: ze,
1263
1263
  post_data: ne,
1264
1264
  options: J,
1265
1265
  api_prefix: T
1266
- } = this, he = r || { "x-gradio-user": "api" }, ze = this;
1266
+ } = this, he = r || { "x-gradio-user": "api" }, Be = this;
1267
1267
  if (!H) throw new Error("No API found");
1268
1268
  if (!f) throw new Error("Could not resolve app config");
1269
1269
  let { fn_index: d, endpoint_info: fe, dependency: B } = ts(
@@ -1271,17 +1271,17 @@ function Xt(e, s = {}, t, n, o, r) {
1271
1271
  e,
1272
1272
  z,
1273
1273
  f
1274
- ), Be = bt(s, fe), j, A = f.protocol ?? "ws";
1274
+ ), Ge = bt(s, fe), j, A = f.protocol ?? "ws";
1275
1275
  if (A === "ws")
1276
1276
  throw new Error("WebSocket protocol is not supported in this version");
1277
1277
  let I = "", ss = () => I;
1278
1278
  const _ = typeof e == "number" ? "/predict" : e;
1279
1279
  let W, v = null, x = !1, _e = {}, G = typeof window < "u" && typeof document < "u" ? new URLSearchParams(window.location.search).toString() : "";
1280
- const Ge = J?.events?.reduce(
1280
+ const Me = J?.events?.reduce(
1281
1281
  (h, R) => (h[R] = !0, h),
1282
1282
  {}
1283
1283
  ) || {};
1284
- async function Me() {
1284
+ async function Fe() {
1285
1285
  let h = {}, R = {};
1286
1286
  h = { event_id: v }, R = { event_id: v, session_hash: m, fn_index: d };
1287
1287
  try {
@@ -1302,7 +1302,7 @@ function Xt(e, s = {}, t, n, o, r) {
1302
1302
  );
1303
1303
  }
1304
1304
  }
1305
- const Fe = async (h) => {
1305
+ const He = async (h) => {
1306
1306
  await this._resolve_heartbeat(h);
1307
1307
  };
1308
1308
  async function ge(h) {
@@ -1318,16 +1318,16 @@ function Xt(e, s = {}, t, n, o, r) {
1318
1318
  const Z = f.components.some((E) => E.type === "state"), y = f.dependencies.some(
1319
1319
  (E) => E.targets.some((U) => U[1] === "unload")
1320
1320
  );
1321
- f.connect_heartbeat = Z || y, await Fe(f), i({
1321
+ f.connect_heartbeat = Z || y, await He(f), i({
1322
1322
  type: "render",
1323
1323
  data: h,
1324
1324
  endpoint: _,
1325
1325
  fn_index: d
1326
1326
  });
1327
1327
  }
1328
- const He = this.handle_blob(
1328
+ const Je = this.handle_blob(
1329
1329
  f.root,
1330
- Be,
1330
+ Ge,
1331
1331
  fe
1332
1332
  ).then(async (h) => {
1333
1333
  if (W = {
@@ -1420,14 +1420,14 @@ function Xt(e, s = {}, t, n, o, r) {
1420
1420
  session_hash: m
1421
1421
  }).toString();
1422
1422
  let y = new URL(
1423
- `${f.root}${T}/${Ae}?${G ? G + "&" : ""}${Z}`
1423
+ `${f.root}${T}/${xe}?${G ? G + "&" : ""}${Z}`
1424
1424
  );
1425
1425
  if (this.jwt && y.searchParams.set("__sign", this.jwt), j = this.stream(y), !j)
1426
1426
  return Promise.reject(
1427
1427
  new Error("Cannot connect to SSE endpoint: " + y.toString())
1428
1428
  );
1429
1429
  j.onmessage = async function(E) {
1430
- const U = JSON.parse(E.data), { type: O, status: D, data: b } = ve(
1430
+ const U = JSON.parse(E.data), { type: O, status: D, data: b } = Ee(
1431
1431
  U,
1432
1432
  _e[d]
1433
1433
  );
@@ -1510,7 +1510,7 @@ function Xt(e, s = {}, t, n, o, r) {
1510
1510
  });
1511
1511
  let y = "";
1512
1512
  typeof window < "u" && typeof document < "u" && (y = window?.location?.hostname);
1513
- const E = Ue(y);
1513
+ const E = qe(y);
1514
1514
  return (typeof window < "u" && typeof document < "u" && window.parent != window && !!E && window.supports_zerogpu_headers ? xt("zerogpu-headers", E) : Promise.resolve(null)).then((b) => {
1515
1515
  const q = { ...he, ...b || {} };
1516
1516
  return ne(
@@ -1526,7 +1526,7 @@ function Xt(e, s = {}, t, n, o, r) {
1526
1526
  i({
1527
1527
  type: "status",
1528
1528
  stage: "error",
1529
- message: xe,
1529
+ message: De,
1530
1530
  queue: !0,
1531
1531
  endpoint: _,
1532
1532
  fn_index: d,
@@ -1562,7 +1562,7 @@ function Xt(e, s = {}, t, n, o, r) {
1562
1562
  v = b.event_id, I = v;
1563
1563
  let P = async function(ie) {
1564
1564
  try {
1565
- const { type: S, status: $, data: k, original_msg: We } = ve(
1565
+ const { type: S, status: $, data: k, original_msg: We } = Ee(
1566
1566
  ie,
1567
1567
  _e[d]
1568
1568
  );
@@ -1644,21 +1644,21 @@ function Xt(e, s = {}, t, n, o, r) {
1644
1644
  endpoint: _,
1645
1645
  fn_index: d,
1646
1646
  time: /* @__PURE__ */ new Date()
1647
- }), ["sse_v2", "sse_v2.1", "sse_v3"].includes(A) && (de(X, ze.abort_controller), X.open = !1, a());
1647
+ }), ["sse_v2", "sse_v2.1", "sse_v3"].includes(A) && (de(X, Be.abort_controller), X.open = !1, a());
1648
1648
  }
1649
1649
  };
1650
- v in ee && (ee[v].forEach((ie) => P(ie)), delete ee[v]), se[v] = P, qe.add(v), X.open || await this.open_stream();
1650
+ v in ee && (ee[v].forEach((ie) => P(ie)), delete ee[v]), se[v] = P, ze.add(v), X.open || await this.open_stream();
1651
1651
  }
1652
1652
  });
1653
1653
  }
1654
1654
  });
1655
- let Je = !1;
1656
- const oe = [], M = [], me = {
1657
- [Symbol.asyncIterator]: () => me,
1655
+ let me = !1;
1656
+ const oe = [], M = [], we = {
1657
+ [Symbol.asyncIterator]: () => we,
1658
1658
  next: c,
1659
1659
  throw: async (h) => (l(h), c()),
1660
1660
  return: async () => (a(), { value: void 0, done: !0 }),
1661
- cancel: Me,
1661
+ cancel: Fe,
1662
1662
  send_chunk: (h) => {
1663
1663
  this.post_data(`${f.root}${T}/stream/${I}`, {
1664
1664
  ...h,
@@ -1672,9 +1672,9 @@ function Xt(e, s = {}, t, n, o, r) {
1672
1672
  ), a();
1673
1673
  },
1674
1674
  event_id: () => I,
1675
- wait_for_id: async () => (await He, v)
1675
+ wait_for_id: async () => (await Je, v)
1676
1676
  };
1677
- return me;
1677
+ return we;
1678
1678
  } catch (i) {
1679
1679
  throw console.error("Submit function encountered an error:", i), i;
1680
1680
  }
@@ -1782,11 +1782,11 @@ class Y {
1782
1782
  ), this.api_info = await this.view_api(), this.api_map = ht(this.config?.dependencies || []);
1783
1783
  }
1784
1784
  async _resolve_heartbeat(s) {
1785
- if (s && (this.config = s, this.api_prefix = s.api_prefix || "", this.config && this.config.connect_heartbeat && this.config.space_id && this.options.token && (this.jwt = await ye(
1785
+ if (s && (this.config = s, this.api_prefix = s.api_prefix || "", this.config && this.config.connect_heartbeat && this.config.space_id && this.options.token && (this.jwt = await be(
1786
1786
  this.config.space_id,
1787
1787
  this.options.token,
1788
1788
  this.cookies
1789
- ))), s.space_id && this.options.token && (this.jwt = await ye(s.space_id, this.options.token)), this.config && this.config.connect_heartbeat) {
1789
+ ))), s.space_id && this.options.token && (this.jwt = await be(s.space_id, this.options.token)), this.config && this.config.connect_heartbeat) {
1790
1790
  const t = new URL(
1791
1791
  `${this.config.root}${this.api_prefix}/${tt}/${this.session_hash}`
1792
1792
  );
@@ -1830,7 +1830,7 @@ class Y {
1830
1830
  this.app_reference,
1831
1831
  this.options.token
1832
1832
  ), { status_callback: o } = this.options;
1833
- n && o && await Ie(n, o);
1833
+ n && o && await Ue(n, o);
1834
1834
  let r;
1835
1835
  try {
1836
1836
  let i = `${s}//${t}`;
@@ -1925,7 +1925,7 @@ class Y {
1925
1925
  }
1926
1926
  }
1927
1927
  set_cookies(s) {
1928
- this.cookies = Ne(s).join("; ");
1928
+ this.cookies = Pe(s).join("; ");
1929
1929
  }
1930
1930
  prepare_return_obj() {
1931
1931
  return {
package/dist/index.js CHANGED
@@ -1583,6 +1583,9 @@ function submit(endpoint, data = {}, event_data, trigger_id, all_events, additio
1583
1583
  if (values.length > 0) {
1584
1584
  return Promise.resolve(values.shift());
1585
1585
  }
1586
+ if (done) {
1587
+ return Promise.resolve({ value: void 0, done: true });
1588
+ }
1586
1589
  return new Promise((resolve) => resolvers.push(resolve));
1587
1590
  };
1588
1591
  const { token } = this.options;
@@ -1 +1 @@
1
- {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../src/utils/submit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGX,WAAW,EAMX,cAAc,EACd,MAAM,UAAU,CAAC;AAkBlB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,wBAAgB,MAAM,CACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,IAAI,GAAE,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAC9C,UAAU,CAAC,EAAE,OAAO,EACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,EAC1B,UAAU,CAAC,EAAE,OAAO,EACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,cAAc,CAAC,WAAW,CAAC,CA8pB7B"}
1
+ {"version":3,"file":"submit.d.ts","sourceRoot":"","sources":["../../src/utils/submit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAGX,WAAW,EAMX,cAAc,EACd,MAAM,UAAU,CAAC;AAkBlB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,wBAAgB,MAAM,CACrB,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,GAAG,MAAM,EACzB,IAAI,GAAE,OAAO,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAC9C,UAAU,CAAC,EAAE,OAAO,EACpB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,EAC1B,UAAU,CAAC,EAAE,OAAO,EACpB,kBAAkB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACzC,cAAc,CAAC,WAAW,CAAC,CAiqB7B"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradio/client",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "description": "Gradio API client",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -0,0 +1,92 @@
1
+ import { describe, beforeAll, afterEach, afterAll, test, expect } from "vitest";
2
+
3
+ import { Client } from "../client";
4
+ import { initialise_server } from "./server";
5
+
6
+ let server: Awaited<ReturnType<typeof initialise_server>>;
7
+
8
+ beforeAll(async () => {
9
+ server = await initialise_server();
10
+ await server.start({ quiet: true });
11
+ });
12
+ afterEach(() => server.resetHandlers());
13
+ afterAll(() => server.stop());
14
+
15
+ async function race_with_timeout<T>(
16
+ promise: Promise<T>,
17
+ ms: number,
18
+ message: string
19
+ ): Promise<T> {
20
+ let timer: ReturnType<typeof setTimeout> | undefined;
21
+ const timeout = new Promise<never>((_, reject) => {
22
+ timer = setTimeout(() => reject(new Error(message)), ms);
23
+ });
24
+ try {
25
+ return await Promise.race([promise, timeout]);
26
+ } finally {
27
+ if (timer !== undefined) clearTimeout(timer);
28
+ }
29
+ }
30
+
31
+ describe("submit iterator", () => {
32
+ test("next() after the iterator is closed resolves to {done: true}", async () => {
33
+ const app = await Client.connect("hmb/hello_world");
34
+ // Avoid opening a real SSE stream — the test does not need one.
35
+ app.stream_status.open = true;
36
+
37
+ const iterator = app.submit("/predict", ["hi"]);
38
+ await iterator.return();
39
+
40
+ const result = await race_with_timeout(
41
+ iterator.next(),
42
+ 1000,
43
+ "next() did not resolve after the iterator was closed"
44
+ );
45
+ expect(result).toEqual({ value: undefined, done: true });
46
+ });
47
+
48
+ test("for-await loop terminates when data and complete arrive in the same SSE callback", async () => {
49
+ const app = await Client.connect("hmb/hello_world", {
50
+ events: ["data", "status"]
51
+ });
52
+ app.stream_status.open = true;
53
+
54
+ const iterator = app.submit("/predict", ["hi"]);
55
+ const event_id = await iterator.wait_for_id();
56
+ expect(event_id).toBeTruthy();
57
+
58
+ const callback = app.event_callbacks[event_id as string];
59
+ expect(callback).toBeDefined();
60
+
61
+ const events: { type: string }[] = [];
62
+ const consumer = (async () => {
63
+ for await (const event of iterator) {
64
+ events.push(event as { type: string });
65
+ }
66
+ })();
67
+
68
+ // Let the consumer drain the pending status event pushed by submit()
69
+ // and suspend on a fresh next() call, so a resolver is queued before
70
+ // the SSE callback fires.
71
+ await new Promise((r) => setTimeout(r, 0));
72
+
73
+ // process_completed in the same tick fires a data event (resolving the
74
+ // pending resolver), a status complete event (queued to values because
75
+ // no resolver is registered at that instant), and then close().
76
+ await callback({
77
+ msg: "process_completed",
78
+ output: { data: ["done"] },
79
+ success: true
80
+ });
81
+
82
+ await race_with_timeout(
83
+ consumer,
84
+ 1000,
85
+ "submit iterator did not terminate after process_completed"
86
+ );
87
+
88
+ const types = events.map((e) => e.type);
89
+ expect(types).toContain("data");
90
+ expect(types).toContain("status");
91
+ });
92
+ });
@@ -666,6 +666,9 @@ export function submit(
666
666
  if (values.length > 0) {
667
667
  return Promise.resolve(values.shift() as (typeof values)[0]);
668
668
  }
669
+ if (done) {
670
+ return Promise.resolve({ value: undefined, done: true });
671
+ }
669
672
  return new Promise((resolve) => resolvers.push(resolve));
670
673
  }
671
674