@gradio/client 0.17.0 → 0.18.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.
Files changed (62) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/dist/client.d.ts +15 -4
  3. package/dist/client.d.ts.map +1 -1
  4. package/dist/constants.d.ts +8 -2
  5. package/dist/constants.d.ts.map +1 -1
  6. package/dist/helpers/data.d.ts +2 -2
  7. package/dist/helpers/data.d.ts.map +1 -1
  8. package/dist/helpers/init_helpers.d.ts.map +1 -1
  9. package/dist/helpers/spaces.d.ts.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +219 -176
  13. package/dist/test/handlers.d.ts +3 -0
  14. package/dist/test/handlers.d.ts.map +1 -0
  15. package/dist/test/mock_eventsource.d.ts +2 -0
  16. package/dist/test/mock_eventsource.d.ts.map +1 -0
  17. package/dist/test/server.d.ts +2 -0
  18. package/dist/test/server.d.ts.map +1 -0
  19. package/dist/test/test_data.d.ts +76 -0
  20. package/dist/test/test_data.d.ts.map +1 -0
  21. package/dist/types.d.ts +4 -3
  22. package/dist/types.d.ts.map +1 -1
  23. package/dist/upload.d.ts +2 -2
  24. package/dist/upload.d.ts.map +1 -1
  25. package/dist/utils/duplicate.d.ts.map +1 -1
  26. package/dist/utils/stream.d.ts +1 -1
  27. package/dist/utils/stream.d.ts.map +1 -1
  28. package/dist/utils/submit.d.ts.map +1 -1
  29. package/dist/utils/upload_files.d.ts.map +1 -1
  30. package/dist/utils/view_api.d.ts.map +1 -1
  31. package/package.json +8 -2
  32. package/src/client.ts +50 -24
  33. package/src/constants.ts +9 -2
  34. package/src/helpers/api_info.ts +4 -4
  35. package/src/helpers/data.ts +46 -28
  36. package/src/helpers/init_helpers.ts +7 -11
  37. package/src/helpers/spaces.ts +8 -3
  38. package/src/index.ts +1 -1
  39. package/src/test/api_info.test.ts +456 -0
  40. package/src/test/data.test.ts +281 -0
  41. package/src/test/handlers.ts +438 -0
  42. package/src/test/init.test.ts +139 -0
  43. package/src/test/init_helpers.test.ts +94 -0
  44. package/src/test/mock_eventsource.ts +11 -0
  45. package/src/test/post_data.test.ts +45 -0
  46. package/src/test/server.ts +6 -0
  47. package/src/test/spaces.test.ts +145 -0
  48. package/src/test/stream.test.ts +67 -0
  49. package/src/test/test_data.ts +557 -0
  50. package/src/test/upload_files.test.ts +42 -0
  51. package/src/test/view_api.test.ts +53 -0
  52. package/src/types.ts +4 -3
  53. package/src/upload.ts +4 -8
  54. package/src/utils/duplicate.ts +20 -3
  55. package/src/utils/handle_blob.ts +1 -1
  56. package/src/utils/post_data.ts +1 -1
  57. package/src/utils/stream.ts +29 -20
  58. package/src/utils/submit.ts +23 -15
  59. package/src/utils/upload_files.ts +11 -6
  60. package/src/utils/view_api.ts +4 -7
  61. package/vite.config.js +7 -0
  62. package/src/utils/client.node-test.ts +0 -173
package/dist/index.js CHANGED
@@ -10,11 +10,18 @@ function semiver$1(a, b, bool) {
10
10
  b = b.split(".");
11
11
  return fn(a[0], b[0]) || fn(a[1], b[1]) || (b[2] = b.slice(2).join("."), bool = /[.-]/.test(a[2] = a.slice(2).join(".")), bool == /[.-]/.test(b[2]) ? fn(a[2], b[2]) : bool ? -1 : 1);
12
12
  }
13
+ const UPLOAD_URL = "upload";
13
14
  const CONFIG_URL = "config";
14
15
  const API_INFO_URL = "info";
16
+ const RUNTIME_URL = "runtime";
17
+ const SLEEPTIME_URL = "sleeptime";
15
18
  const SPACE_FETCHER_URL = "https://gradio-space-api-fetcher-v2.hf.space/api";
16
- const QUEUE_FULL_MSG = "This application is too busy. Keep trying!";
17
- const BROKEN_CONNECTION_MSG = "Connection errored out.";
19
+ const QUEUE_FULL_MSG = "This application is currently busy. Please try again. ";
20
+ const BROKEN_CONNECTION_MSG = "Connection errored out. ";
21
+ const CONFIG_ERROR_MSG = "Could not resolve app config. ";
22
+ const SPACE_STATUS_ERROR_MSG = "Could not get space status. ";
23
+ const API_INFO_ERROR_MSG = "Could not get API info. ";
24
+ const SPACE_METADATA_ERROR_MSG = "Space metadata could not be loaded. ";
18
25
  function resolve_root(base_url, root_path, prioritize_base) {
19
26
  if (root_path.startsWith("http://") || root_path.startsWith("https://")) {
20
27
  return prioritize_base ? base_url : root_path;
@@ -31,7 +38,6 @@ async function get_jwt(space, token) {
31
38
  const jwt = (await r.json()).token;
32
39
  return jwt || false;
33
40
  } catch (e) {
34
- console.error(e);
35
41
  return false;
36
42
  }
37
43
  }
@@ -53,21 +59,18 @@ async function resolve_config(endpoint) {
53
59
  config.root = config_root;
54
60
  return { ...config, path };
55
61
  } else if (endpoint) {
56
- const response = await this.fetch_implementation(
57
- `${endpoint}/${CONFIG_URL}`,
58
- {
59
- headers
60
- }
61
- );
62
+ const response = await this.fetch(`${endpoint}/${CONFIG_URL}`, {
63
+ headers
64
+ });
62
65
  if ((response == null ? void 0 : response.status) === 200) {
63
66
  let config = await response.json();
64
67
  config.path = config.path ?? "";
65
68
  config.root = endpoint;
66
69
  return config;
67
70
  }
68
- throw new Error("Could not get config.");
71
+ throw new Error(CONFIG_ERROR_MSG);
69
72
  }
70
- throw new Error("No config or app endpoint found");
73
+ throw new Error(CONFIG_ERROR_MSG);
71
74
  }
72
75
  function determine_protocol(endpoint) {
73
76
  if (endpoint.startsWith("http")) {
@@ -112,15 +115,15 @@ async function process_endpoint(app_reference, hf_token) {
112
115
  `https://huggingface.co/api/spaces/${_app_reference}/host`,
113
116
  { headers }
114
117
  );
115
- if (res.status !== 200)
116
- throw new Error("Space metadata could not be loaded.");
117
118
  const _host = (await res.json()).host;
118
119
  return {
119
120
  space_id: app_reference,
120
121
  ...determine_protocol(_host)
121
122
  };
122
123
  } catch (e) {
123
- throw new Error("Space metadata could not be loaded." + e.message);
124
+ throw new Error(
125
+ "Space metadata could not be loaded. " + e.message
126
+ );
124
127
  }
125
128
  }
126
129
  if (RE_SPACE_DOMAIN.test(_app_reference)) {
@@ -329,7 +332,7 @@ async function view_api() {
329
332
  try {
330
333
  let response;
331
334
  if (semiver$1((config == null ? void 0 : config.version) || "2.0.0", "3.30") < 0) {
332
- response = await this.fetch_implementation(SPACE_FETCHER_URL, {
335
+ response = await this.fetch(SPACE_FETCHER_URL, {
333
336
  method: "POST",
334
337
  body: JSON.stringify({
335
338
  serialize: false,
@@ -338,12 +341,9 @@ async function view_api() {
338
341
  headers
339
342
  });
340
343
  } else {
341
- response = await this.fetch_implementation(
342
- `${config == null ? void 0 : config.root}/${API_INFO_URL}`,
343
- {
344
- headers
345
- }
346
- );
344
+ response = await this.fetch(`${config == null ? void 0 : config.root}/${API_INFO_URL}`, {
345
+ headers
346
+ });
347
347
  }
348
348
  if (!response.ok) {
349
349
  throw new Error(BROKEN_CONNECTION_MSG);
@@ -361,12 +361,14 @@ async function view_api() {
361
361
  }
362
362
  }
363
363
  async function upload_files(root_url, files, upload_id) {
364
+ var _a;
364
365
  const headers = {};
365
- if (this.options.hf_token) {
366
+ if ((_a = this == null ? void 0 : this.options) == null ? void 0 : _a.hf_token) {
366
367
  headers.Authorization = `Bearer ${this.options.hf_token}`;
367
368
  }
368
369
  const chunkSize = 1e3;
369
370
  const uploadResponses = [];
371
+ let response;
370
372
  for (let i = 0; i < files.length; i += chunkSize) {
371
373
  const chunk = files.slice(i, i + chunkSize);
372
374
  const formData = new FormData();
@@ -374,17 +376,18 @@ async function upload_files(root_url, files, upload_id) {
374
376
  formData.append("files", file);
375
377
  });
376
378
  try {
377
- const upload_url = upload_id ? `${root_url}/upload?upload_id=${upload_id}` : `${root_url}/upload`;
378
- var response = await this.fetch_implementation(upload_url, {
379
+ const upload_url = upload_id ? `${root_url}/upload?upload_id=${upload_id}` : `${root_url}/${UPLOAD_URL}`;
380
+ response = await this.fetch(upload_url, {
379
381
  method: "POST",
380
382
  body: formData,
381
383
  headers
382
384
  });
383
385
  } catch (e) {
384
- return { error: BROKEN_CONNECTION_MSG };
386
+ throw new Error(BROKEN_CONNECTION_MSG + e.message);
385
387
  }
386
388
  if (!response.ok) {
387
- return { error: await response.text() };
389
+ const error_text = await response.text();
390
+ return { error: `HTTP ${response.status}: ${error_text}` };
388
391
  }
389
392
  const output = await response.json();
390
393
  if (output) {
@@ -393,87 +396,7 @@ async function upload_files(root_url, files, upload_id) {
393
396
  }
394
397
  return { files: uploadResponses };
395
398
  }
396
- function update_object(object, newValue, stack) {
397
- while (stack.length > 1) {
398
- const key2 = stack.shift();
399
- if (typeof key2 === "string" || typeof key2 === "number") {
400
- object = object[key2];
401
- } else {
402
- throw new Error("Invalid key type");
403
- }
404
- }
405
- const key = stack.shift();
406
- if (typeof key === "string" || typeof key === "number") {
407
- object[key] = newValue;
408
- } else {
409
- throw new Error("Invalid key type");
410
- }
411
- }
412
- async function walk_and_store_blobs(param, type = void 0, path = [], root = false, endpoint_info = void 0) {
413
- if (Array.isArray(param)) {
414
- let blob_refs = [];
415
- await Promise.all(
416
- param.map(async (item) => {
417
- var _a;
418
- let new_path = path.slice();
419
- new_path.push(item);
420
- const array_refs = await walk_and_store_blobs(
421
- param[item],
422
- root ? ((_a = endpoint_info == null ? void 0 : endpoint_info.parameters[item]) == null ? void 0 : _a.component) || void 0 : type,
423
- new_path,
424
- false,
425
- endpoint_info
426
- );
427
- blob_refs = blob_refs.concat(array_refs);
428
- })
429
- );
430
- return blob_refs;
431
- } else if (globalThis.Buffer && param instanceof globalThis.Buffer) {
432
- const is_image = type === "Image";
433
- return [
434
- {
435
- path,
436
- blob: is_image ? false : new NodeBlob([param]),
437
- type
438
- }
439
- ];
440
- } else if (typeof param === "object") {
441
- let blob_refs = [];
442
- for (let key in param) {
443
- if (param.hasOwnProperty(key)) {
444
- let new_path = path.slice();
445
- new_path.push(key);
446
- blob_refs = blob_refs.concat(
447
- await walk_and_store_blobs(
448
- // @ts-ignore
449
- param[key],
450
- void 0,
451
- new_path,
452
- false,
453
- endpoint_info
454
- )
455
- );
456
- }
457
- }
458
- return blob_refs;
459
- }
460
- return [];
461
- }
462
- function skip_queue(id, config) {
463
- var _a, _b, _c, _d;
464
- return !(((_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a[id]) == null ? void 0 : _b.queue) === null ? config.enable_queue : (_d = (_c = config == null ? void 0 : config.dependencies) == null ? void 0 : _c[id]) == null ? void 0 : _d.queue) || false;
465
- }
466
- function post_message(message, origin) {
467
- return new Promise((res, _rej) => {
468
- const channel = new MessageChannel();
469
- channel.port1.onmessage = ({ data }) => {
470
- channel.port1.close();
471
- res(data);
472
- };
473
- window.parent.postMessage(message, origin, [channel.port2]);
474
- });
475
- }
476
- async function upload(file_data, root_url, upload_id, max_file_size, upload_fn = upload_files) {
399
+ async function upload(file_data, root_url, upload_id, max_file_size) {
477
400
  let files = (Array.isArray(file_data) ? file_data : [file_data]).map(
478
401
  (file_data2) => file_data2.blob
479
402
  );
@@ -486,7 +409,7 @@ async function upload(file_data, root_url, upload_id, max_file_size, upload_fn =
486
409
  );
487
410
  }
488
411
  return await Promise.all(
489
- await upload_fn(root_url, files, upload_id).then(
412
+ await this.upload_files(root_url, files, upload_id).then(
490
413
  async (response) => {
491
414
  if (response.error) {
492
415
  throw new Error(response.error);
@@ -549,6 +472,95 @@ class FileData {
549
472
  this.alt_text = alt_text;
550
473
  }
551
474
  }
475
+ function update_object(object, newValue, stack) {
476
+ while (stack.length > 1) {
477
+ const key2 = stack.shift();
478
+ if (typeof key2 === "string" || typeof key2 === "number") {
479
+ object = object[key2];
480
+ } else {
481
+ throw new Error("Invalid key type");
482
+ }
483
+ }
484
+ const key = stack.shift();
485
+ if (typeof key === "string" || typeof key === "number") {
486
+ object[key] = newValue;
487
+ } else {
488
+ throw new Error("Invalid key type");
489
+ }
490
+ }
491
+ async function walk_and_store_blobs(data, type = void 0, path = [], root = false, endpoint_info = void 0) {
492
+ if (Array.isArray(data)) {
493
+ let blob_refs = [];
494
+ await Promise.all(
495
+ data.map(async (item) => {
496
+ var _a;
497
+ let new_path = path.slice();
498
+ new_path.push(item);
499
+ const array_refs = await walk_and_store_blobs(
500
+ data[item],
501
+ root ? ((_a = endpoint_info == null ? void 0 : endpoint_info.parameters[item]) == null ? void 0 : _a.component) || void 0 : type,
502
+ new_path,
503
+ false,
504
+ endpoint_info
505
+ );
506
+ blob_refs = blob_refs.concat(array_refs);
507
+ })
508
+ );
509
+ return blob_refs;
510
+ } else if (globalThis.Buffer && data instanceof globalThis.Buffer || data instanceof Blob) {
511
+ const is_image = type === "Image";
512
+ return [
513
+ {
514
+ path,
515
+ blob: is_image ? false : new NodeBlob([data]),
516
+ type
517
+ }
518
+ ];
519
+ } else if (typeof data === "object" && data !== null) {
520
+ let blob_refs = [];
521
+ for (const key of Object.keys(data)) {
522
+ const new_path = [...path, key];
523
+ const value = data[key];
524
+ blob_refs = blob_refs.concat(
525
+ await walk_and_store_blobs(
526
+ value,
527
+ void 0,
528
+ new_path,
529
+ false,
530
+ endpoint_info
531
+ )
532
+ );
533
+ }
534
+ if (!blob_refs.length && !(data instanceof Blob || data instanceof ArrayBuffer || data instanceof Uint8Array)) {
535
+ return [
536
+ {
537
+ path,
538
+ blob: new NodeBlob([JSON.stringify(data)]),
539
+ type: typeof data
540
+ }
541
+ ];
542
+ }
543
+ return blob_refs;
544
+ }
545
+ return [];
546
+ }
547
+ function skip_queue(id, config) {
548
+ var _a, _b;
549
+ if (((_b = (_a = config == null ? void 0 : config.dependencies) == null ? void 0 : _a[id]) == null ? void 0 : _b.queue) !== null) {
550
+ return !config.dependencies[id].queue;
551
+ }
552
+ return !config.enable_queue;
553
+ }
554
+ function post_message(message, origin) {
555
+ return new Promise((res, _rej) => {
556
+ const channel = new MessageChannel();
557
+ channel.port1.onmessage = ({ data }) => {
558
+ channel.port1.close();
559
+ res(data);
560
+ };
561
+ window.parent.postMessage(message, origin, [channel.port2]);
562
+ });
563
+ }
552
564
  async function handle_blob(endpoint, data, api_info) {
553
565
  const self = this;
554
566
  const blobRefs = await walk_and_store_blobs(
@@ -568,7 +580,7 @@ async function handle_blob(endpoint, data, api_info) {
568
580
  path,
569
581
  file_url,
570
582
  type,
571
- name: blob == null ? void 0 : blob.name
583
+ name: blob instanceof File ? blob == null ? void 0 : blob.name : void 0
572
584
  };
573
585
  })
574
586
  );
@@ -588,7 +600,7 @@ async function post_data(url, body, additional_headers) {
588
600
  headers.Authorization = `Bearer ${this.options.hf_token}`;
589
601
  }
590
602
  try {
591
- var response = await this.fetch_implementation(url, {
603
+ var response = await this.fetch(url, {
592
604
  method: "POST",
593
605
  body: JSON.stringify(body),
594
606
  headers: { ...headers, ...additional_headers }
@@ -663,7 +675,7 @@ async function check_space_status(id, type, status_callback) {
663
675
  status_callback({
664
676
  status: "error",
665
677
  load_status: "error",
666
- message: "Could not get space status",
678
+ message: SPACE_STATUS_ERROR_MSG,
667
679
  detail: "NOT_FOUND"
668
680
  });
669
681
  return;
@@ -751,7 +763,7 @@ async function get_space_hardware(space_id, hf_token) {
751
763
  }
752
764
  try {
753
765
  const res = await fetch(
754
- `https://huggingface.co/api/spaces/${space_id}/runtime`,
766
+ `https://huggingface.co/api/spaces/${space_id}/${RUNTIME_URL}`,
755
767
  { headers }
756
768
  );
757
769
  if (res.status !== 200)
@@ -772,7 +784,7 @@ async function set_space_timeout(space_id, timeout, hf_token) {
772
784
  };
773
785
  try {
774
786
  const res = await fetch(
775
- `https://huggingface.co/api/spaces/${space_id}/sleeptime`,
787
+ `https://huggingface.co/api/spaces/${space_id}/${SLEEPTIME_URL}`,
776
788
  {
777
789
  method: "POST",
778
790
  headers: { "Content-Type": "application/json", ...headers },
@@ -827,8 +839,12 @@ async function duplicate(app_reference, options) {
827
839
  body.private = true;
828
840
  }
829
841
  let original_hardware;
830
- if (!hardware) {
831
- original_hardware = await get_space_hardware(app_reference, hf_token);
842
+ try {
843
+ if (!hardware) {
844
+ original_hardware = await get_space_hardware(app_reference, hf_token);
845
+ }
846
+ } catch (e) {
847
+ throw Error(SPACE_METADATA_ERROR_MSG + e.message);
832
848
  }
833
849
  const requested_hardware = hardware || original_hardware || "cpu-basic";
834
850
  body.hardware = requested_hardware;
@@ -854,58 +870,73 @@ async function duplicate(app_reference, options) {
854
870
  }
855
871
  const duplicated_space = await response.json();
856
872
  await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
857
- return await Client.connect(duplicated_space.url, options);
873
+ return await Client.connect(
874
+ get_space_reference(duplicated_space.url),
875
+ options
876
+ );
858
877
  } catch (e) {
859
878
  throw new Error(e);
860
879
  }
861
880
  }
881
+ function get_space_reference(url) {
882
+ const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/;
883
+ const match = url.match(regex);
884
+ if (match) {
885
+ return match[1];
886
+ }
887
+ }
862
888
  function open_stream() {
863
889
  let {
864
890
  event_callbacks,
865
891
  unclosed_events,
866
892
  pending_stream_messages,
867
893
  stream_status,
868
- config
894
+ config,
895
+ jwt
869
896
  } = this;
870
897
  if (!config) {
871
898
  throw new Error("Could not resolve app config");
872
899
  }
873
900
  stream_status.open = true;
874
- let event_source = null;
901
+ let stream = null;
875
902
  let params = new URLSearchParams({
876
903
  session_hash: this.session_hash
877
904
  }).toString();
878
905
  let url = new URL(`${config.root}/queue/data?${params}`);
879
- event_source = this.eventSource_factory(url);
880
- if (!event_source) {
881
- throw new Error("Cannot connect to sse endpoint: " + url.toString());
906
+ if (jwt) {
907
+ url.searchParams.set("__sign", jwt);
908
+ }
909
+ stream = this.stream_factory(url);
910
+ if (!stream) {
911
+ console.warn("Cannot connect to SSE endpoint: " + url.toString());
912
+ return;
882
913
  }
883
- event_source.onmessage = async function(event) {
914
+ stream.onmessage = async function(event) {
884
915
  let _data = JSON.parse(event.data);
885
916
  if (_data.msg === "close_stream") {
886
- close_stream(stream_status, event_source);
917
+ close_stream(stream_status, stream);
887
918
  return;
888
919
  }
889
920
  const event_id = _data.event_id;
890
921
  if (!event_id) {
891
922
  await Promise.all(
892
923
  Object.keys(event_callbacks).map(
893
- (event_id2) => (
894
- // @ts-ignore
895
- event_callbacks[event_id2](_data)
896
- )
897
- // todo: check event_callbacks
924
+ (event_id2) => event_callbacks[event_id2](_data)
898
925
  )
899
926
  );
900
927
  } else if (event_callbacks[event_id] && config) {
901
928
  if (_data.msg === "process_completed" && ["sse", "sse_v1", "sse_v2", "sse_v2.1"].includes(config.protocol)) {
902
929
  unclosed_events.delete(event_id);
903
930
  if (unclosed_events.size === 0) {
904
- close_stream(stream_status, event_source);
931
+ close_stream(stream_status, stream);
905
932
  }
906
933
  }
907
934
  let fn2 = event_callbacks[event_id];
908
- window.setTimeout(fn2, 0, _data);
935
+ if (typeof window !== "undefined") {
936
+ window.setTimeout(fn2, 0, _data);
937
+ } else {
938
+ setImmediate(fn2, _data);
939
+ }
909
940
  } else {
910
941
  if (!pending_stream_messages[event_id]) {
911
942
  pending_stream_messages[event_id] = [];
@@ -913,25 +944,22 @@ function open_stream() {
913
944
  pending_stream_messages[event_id].push(_data);
914
945
  }
915
946
  };
916
- event_source.onerror = async function() {
947
+ stream.onerror = async function() {
917
948
  await Promise.all(
918
949
  Object.keys(event_callbacks).map(
919
- (event_id) => (
920
- // @ts-ignore
921
- event_callbacks[event_id]({
922
- msg: "unexpected_error",
923
- message: BROKEN_CONNECTION_MSG
924
- })
925
- )
950
+ (event_id) => event_callbacks[event_id]({
951
+ msg: "unexpected_error",
952
+ message: BROKEN_CONNECTION_MSG
953
+ })
926
954
  )
927
955
  );
928
- close_stream(stream_status, event_source);
956
+ close_stream(stream_status, stream);
929
957
  };
930
958
  }
931
- function close_stream(stream_status, event_source) {
932
- if (stream_status && event_source) {
959
+ function close_stream(stream_status, stream) {
960
+ if (stream_status && stream) {
933
961
  stream_status.open = false;
934
- event_source == null ? void 0 : event_source.close();
962
+ stream == null ? void 0 : stream.close();
935
963
  }
936
964
  }
937
965
  function apply_diff_stream(pending_diff_streams, event_id, data) {
@@ -1023,7 +1051,7 @@ function submit(endpoint, data, event_data, trigger_id) {
1023
1051
  };
1024
1052
  const { hf_token } = this.options;
1025
1053
  const {
1026
- fetch_implementation,
1054
+ fetch: fetch2,
1027
1055
  app_reference,
1028
1056
  config,
1029
1057
  session_hash,
@@ -1047,7 +1075,7 @@ function submit(endpoint, data, event_data, trigger_id) {
1047
1075
  config
1048
1076
  );
1049
1077
  let websocket;
1050
- let event_source;
1078
+ let stream;
1051
1079
  let protocol = config.protocol ?? "ws";
1052
1080
  const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
1053
1081
  let payload;
@@ -1080,14 +1108,14 @@ function submit(endpoint, data, event_data, trigger_id) {
1080
1108
  }
1081
1109
  cancel_request = { fn_index, session_hash };
1082
1110
  } else {
1083
- event_source == null ? void 0 : event_source.close();
1111
+ stream == null ? void 0 : stream.close();
1084
1112
  cancel_request = { event_id };
1085
1113
  }
1086
1114
  try {
1087
1115
  if (!config) {
1088
1116
  throw new Error("Could not resolve app config");
1089
1117
  }
1090
- await fetch_implementation(`${config.root}/reset`, {
1118
+ await fetch2(`${config.root}/reset`, {
1091
1119
  headers: { "Content-Type": "application/json" },
1092
1120
  method: "POST",
1093
1121
  body: JSON.stringify(cancel_request)
@@ -1098,8 +1126,9 @@ function submit(endpoint, data, event_data, trigger_id) {
1098
1126
  );
1099
1127
  }
1100
1128
  }
1101
- this.handle_blob(`${config.root}`, data, endpoint_info).then(
1129
+ this.handle_blob(config.root, data, endpoint_info).then(
1102
1130
  async (_payload) => {
1131
+ var _a;
1103
1132
  payload = {
1104
1133
  data: _payload || [],
1105
1134
  event_data,
@@ -1291,13 +1320,16 @@ function submit(endpoint, data, event_data, trigger_id) {
1291
1320
  let url = new URL(
1292
1321
  `${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}`
1293
1322
  );
1294
- event_source = this.eventSource_factory(url);
1295
- if (!event_source) {
1296
- throw new Error(
1297
- "Cannot connect to sse endpoint: " + url.toString()
1323
+ if (this.jwt) {
1324
+ url.searchParams.set("__sign", this.jwt);
1325
+ }
1326
+ stream = this.stream_factory(url);
1327
+ if (!stream) {
1328
+ return Promise.reject(
1329
+ new Error("Cannot connect to SSE endpoint: " + url.toString())
1298
1330
  );
1299
1331
  }
1300
- event_source.onmessage = async function(event) {
1332
+ stream.onmessage = async function(event) {
1301
1333
  const _data = JSON.parse(event.data);
1302
1334
  const { type, status, data: data2 } = handle_message(
1303
1335
  _data,
@@ -1312,7 +1344,7 @@ function submit(endpoint, data, event_data, trigger_id) {
1312
1344
  ...status
1313
1345
  });
1314
1346
  if (status.stage === "error") {
1315
- event_source == null ? void 0 : event_source.close();
1347
+ stream == null ? void 0 : stream.close();
1316
1348
  }
1317
1349
  } else if (type === "data") {
1318
1350
  event_id = _data.event_id;
@@ -1331,7 +1363,7 @@ function submit(endpoint, data, event_data, trigger_id) {
1331
1363
  fn_index,
1332
1364
  time: /* @__PURE__ */ new Date()
1333
1365
  });
1334
- event_source == null ? void 0 : event_source.close();
1366
+ stream == null ? void 0 : stream.close();
1335
1367
  }
1336
1368
  } else if (type === "complete") {
1337
1369
  complete = status;
@@ -1374,7 +1406,7 @@ function submit(endpoint, data, event_data, trigger_id) {
1374
1406
  endpoint: _endpoint,
1375
1407
  fn_index
1376
1408
  });
1377
- event_source == null ? void 0 : event_source.close();
1409
+ stream == null ? void 0 : stream.close();
1378
1410
  }
1379
1411
  }
1380
1412
  };
@@ -1387,7 +1419,10 @@ function submit(endpoint, data, event_data, trigger_id) {
1387
1419
  fn_index,
1388
1420
  time: /* @__PURE__ */ new Date()
1389
1421
  });
1390
- let hostname = window.location.hostname;
1422
+ let hostname = "";
1423
+ if (typeof window !== "undefined") {
1424
+ hostname = (_a = window == null ? void 0 : window.location) == null ? void 0 : _a.hostname;
1425
+ }
1391
1426
  let hfhubdev = "dev.spaces.huggingface.tech";
1392
1427
  const origin = hostname.includes(".dev.") ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}` : `https://huggingface.co`;
1393
1428
  const zerogpu_auth_promise = dependency.zerogpu && window.parent != window && config.space_id ? post_message("zerogpu-headers", origin) : Promise.resolve(null);
@@ -1517,7 +1552,7 @@ function submit(endpoint, data, event_data, trigger_id) {
1517
1552
  time: /* @__PURE__ */ new Date()
1518
1553
  });
1519
1554
  if (["sse_v2", "sse_v2.1"].includes(protocol)) {
1520
- close_stream(stream_status, event_source);
1555
+ close_stream(stream_status, stream);
1521
1556
  stream_status.open = false;
1522
1557
  }
1523
1558
  }
@@ -1589,6 +1624,7 @@ class Client {
1589
1624
  __publicField(this, "heartbeat_event", null);
1590
1625
  __publicField(this, "view_api");
1591
1626
  __publicField(this, "upload_files");
1627
+ __publicField(this, "upload");
1592
1628
  __publicField(this, "handle_blob");
1593
1629
  __publicField(this, "post_data");
1594
1630
  __publicField(this, "submit");
@@ -1605,12 +1641,19 @@ class Client {
1605
1641
  this.predict = predict.bind(this);
1606
1642
  this.open_stream = open_stream.bind(this);
1607
1643
  this.resolve_config = resolve_config.bind(this);
1644
+ this.upload = upload.bind(this);
1608
1645
  }
1609
- fetch_implementation(input, init) {
1646
+ fetch(input, init) {
1610
1647
  return fetch(input, init);
1611
1648
  }
1612
- eventSource_factory(url) {
1613
- if (typeof window !== void 0 && typeof EventSource !== "undefined") {
1649
+ stream_factory(url) {
1650
+ if (typeof window === "undefined" || typeof EventSource === "undefined") {
1651
+ import("eventsource").then((EventSourceModule) => {
1652
+ return new EventSourceModule.default(url.toString());
1653
+ }).catch(
1654
+ (error) => console.error("Failed to load EventSource module:", error)
1655
+ );
1656
+ } else {
1614
1657
  return new EventSource(url.toString());
1615
1658
  }
1616
1659
  return null;
@@ -1626,11 +1669,11 @@ class Client {
1626
1669
  await this._resolve_config().then(async ({ config }) => {
1627
1670
  if (config) {
1628
1671
  this.config = config;
1629
- if (this.config) {
1672
+ if (this.config && this.config.connect_heartbeat) {
1630
1673
  const heartbeat_url = new URL(
1631
1674
  `${this.config.root}/heartbeat/${this.session_hash}`
1632
1675
  );
1633
- this.heartbeat_event = this.eventSource_factory(heartbeat_url);
1676
+ this.heartbeat_event = this.stream_factory(heartbeat_url);
1634
1677
  if (this.config.space_id && this.options.hf_token) {
1635
1678
  this.jwt = await get_jwt(
1636
1679
  this.config.space_id,
@@ -1641,7 +1684,7 @@ class Client {
1641
1684
  }
1642
1685
  });
1643
1686
  } catch (e) {
1644
- throw Error(`Could not resolve config: ${e}`);
1687
+ throw Error(CONFIG_ERROR_MSG + e.message);
1645
1688
  }
1646
1689
  this.api_info = await this.view_api();
1647
1690
  this.api_map = map_names_to_ids(((_a = this.config) == null ? void 0 : _a.dependencies) || []);
@@ -1668,7 +1711,7 @@ class Client {
1668
1711
  try {
1669
1712
  config = await this.resolve_config(`${http_protocol}//${host}`);
1670
1713
  if (!config) {
1671
- throw new Error("Could not resolve app config");
1714
+ throw new Error(CONFIG_ERROR_MSG);
1672
1715
  }
1673
1716
  return this.config_success(config);
1674
1717
  } catch (e) {
@@ -1703,7 +1746,7 @@ class Client {
1703
1746
  try {
1704
1747
  this.api_info = await this.view_api();
1705
1748
  } catch (e) {
1706
- console.error(`Could not get API details: ${e.message}`);
1749
+ console.error(API_INFO_ERROR_MSG + e.message);
1707
1750
  }
1708
1751
  return this.prepare_return_obj();
1709
1752
  }
@@ -1715,7 +1758,7 @@ class Client {
1715
1758
  try {
1716
1759
  this.config = await this._resolve_config();
1717
1760
  if (!this.config) {
1718
- throw new Error("Could not resolve app config");
1761
+ throw new Error(CONFIG_ERROR_MSG);
1719
1762
  }
1720
1763
  const _config = await this.config_success(this.config);
1721
1764
  return _config;
@@ -1735,7 +1778,7 @@ class Client {
1735
1778
  async component_server(component_id, fn_name, data) {
1736
1779
  var _a;
1737
1780
  if (!this.config) {
1738
- throw new Error("Could not resolve app config");
1781
+ throw new Error(CONFIG_ERROR_MSG);
1739
1782
  }
1740
1783
  const headers = {};
1741
1784
  const { hf_token } = this.options;
@@ -1776,14 +1819,11 @@ class Client {
1776
1819
  headers.Authorization = `Bearer ${hf_token}`;
1777
1820
  }
1778
1821
  try {
1779
- const response = await this.fetch_implementation(
1780
- `${root_url}/component_server/`,
1781
- {
1782
- method: "POST",
1783
- body,
1784
- headers
1785
- }
1786
- );
1822
+ const response = await this.fetch(`${root_url}/component_server/`, {
1823
+ method: "POST",
1824
+ body,
1825
+ headers
1826
+ });
1787
1827
  if (!response.ok) {
1788
1828
  throw new Error(
1789
1829
  "Could not connect to component server: " + response.statusText
@@ -1808,11 +1848,14 @@ class Client {
1808
1848
  async function client(app_reference, options = {}) {
1809
1849
  return await Client.connect(app_reference, options);
1810
1850
  }
1851
+ async function duplicate_space(app_reference, options) {
1852
+ return await Client.duplicate(app_reference, options);
1853
+ }
1811
1854
  export {
1812
1855
  Client,
1813
1856
  FileData,
1814
1857
  client,
1815
- duplicate,
1858
+ duplicate_space as duplicate,
1816
1859
  predict,
1817
1860
  prepare_files,
1818
1861
  submit,