@gradio/client 0.16.0 → 0.17.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 (63) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +49 -43
  3. package/dist/client.d.ts +52 -70
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/constants.d.ts +17 -0
  6. package/dist/constants.d.ts.map +1 -0
  7. package/dist/helpers/api_info.d.ts +25 -0
  8. package/dist/helpers/api_info.d.ts.map +1 -0
  9. package/dist/helpers/data.d.ts +8 -0
  10. package/dist/helpers/data.d.ts.map +1 -0
  11. package/dist/{utils.d.ts → helpers/init_helpers.d.ts} +6 -18
  12. package/dist/helpers/init_helpers.d.ts.map +1 -0
  13. package/dist/helpers/spaces.d.ts +7 -0
  14. package/dist/helpers/spaces.d.ts.map +1 -0
  15. package/dist/index.d.ts +8 -4
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +1544 -1357
  18. package/dist/types.d.ts +152 -49
  19. package/dist/types.d.ts.map +1 -1
  20. package/dist/upload.d.ts +2 -2
  21. package/dist/upload.d.ts.map +1 -1
  22. package/dist/utils/duplicate.d.ts +4 -0
  23. package/dist/utils/duplicate.d.ts.map +1 -0
  24. package/dist/utils/handle_blob.d.ts +4 -0
  25. package/dist/utils/handle_blob.d.ts.map +1 -0
  26. package/dist/utils/post_data.d.ts +4 -0
  27. package/dist/utils/post_data.d.ts.map +1 -0
  28. package/dist/utils/predict.d.ts +4 -0
  29. package/dist/utils/predict.d.ts.map +1 -0
  30. package/dist/utils/stream.d.ts +8 -0
  31. package/dist/utils/stream.d.ts.map +1 -0
  32. package/dist/utils/submit.d.ts +4 -0
  33. package/dist/utils/submit.d.ts.map +1 -0
  34. package/dist/utils/upload_files.d.ts +4 -0
  35. package/dist/utils/upload_files.d.ts.map +1 -0
  36. package/dist/utils/view_api.d.ts +3 -0
  37. package/dist/utils/view_api.d.ts.map +1 -0
  38. package/dist/{wrapper-6f348d45.js → wrapper-CviSselG.js} +259 -17
  39. package/package.json +3 -2
  40. package/src/client.ts +289 -1692
  41. package/src/constants.ts +20 -0
  42. package/src/globals.d.ts +2 -21
  43. package/src/helpers/api_info.ts +300 -0
  44. package/src/helpers/data.ts +115 -0
  45. package/src/helpers/init_helpers.ts +134 -0
  46. package/src/helpers/spaces.ts +192 -0
  47. package/src/index.ts +16 -10
  48. package/src/types.ts +200 -59
  49. package/src/upload.ts +23 -15
  50. package/src/{client.node-test.ts → utils/client.node-test.ts} +11 -10
  51. package/src/utils/duplicate.ts +87 -0
  52. package/src/utils/handle_blob.ts +47 -0
  53. package/src/utils/post_data.ts +37 -0
  54. package/src/utils/predict.ts +56 -0
  55. package/src/utils/stream.ts +166 -0
  56. package/src/utils/submit.ts +689 -0
  57. package/src/utils/upload_files.ts +46 -0
  58. package/src/utils/view_api.ts +70 -0
  59. package/src/vite-env.d.ts +1 -0
  60. package/tsconfig.json +15 -2
  61. package/vite.config.js +4 -17
  62. package/dist/utils.d.ts.map +0 -1
  63. package/src/utils.ts +0 -314
package/dist/index.js CHANGED
@@ -1,15 +1,74 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
1
7
  var fn = new Intl.Collator(0, { numeric: 1 }).compare;
2
- function semiver(a, b, bool) {
8
+ function semiver$1(a, b, bool) {
3
9
  a = a.split(".");
4
10
  b = b.split(".");
5
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);
6
12
  }
13
+ const CONFIG_URL = "config";
14
+ const API_INFO_URL = "info";
15
+ 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.";
7
18
  function resolve_root(base_url, root_path, prioritize_base) {
8
19
  if (root_path.startsWith("http://") || root_path.startsWith("https://")) {
9
20
  return prioritize_base ? base_url : root_path;
10
21
  }
11
22
  return base_url + root_path;
12
23
  }
24
+ async function get_jwt(space, token) {
25
+ try {
26
+ const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, {
27
+ headers: {
28
+ Authorization: `Bearer ${token}`
29
+ }
30
+ });
31
+ const jwt = (await r.json()).token;
32
+ return jwt || false;
33
+ } catch (e) {
34
+ console.error(e);
35
+ return false;
36
+ }
37
+ }
38
+ function map_names_to_ids(fns) {
39
+ let apis = {};
40
+ fns.forEach(({ api_name }, i) => {
41
+ if (api_name)
42
+ apis[api_name] = i;
43
+ });
44
+ return apis;
45
+ }
46
+ async function resolve_config(endpoint) {
47
+ const headers = this.options.hf_token ? { Authorization: `Bearer ${this.options.hf_token}` } : {};
48
+ headers["Content-Type"] = "application/json";
49
+ if (typeof window !== "undefined" && window.gradio_config && location.origin !== "http://localhost:9876" && !window.gradio_config.dev_mode) {
50
+ const path = window.gradio_config.root;
51
+ const config = window.gradio_config;
52
+ let config_root = resolve_root(endpoint, config.root, false);
53
+ config.root = config_root;
54
+ return { ...config, path };
55
+ } else if (endpoint) {
56
+ const response = await this.fetch_implementation(
57
+ `${endpoint}/${CONFIG_URL}`,
58
+ {
59
+ headers
60
+ }
61
+ );
62
+ if ((response == null ? void 0 : response.status) === 200) {
63
+ let config = await response.json();
64
+ config.path = config.path ?? "";
65
+ config.root = endpoint;
66
+ return config;
67
+ }
68
+ throw new Error("Could not get config.");
69
+ }
70
+ throw new Error("No config or app endpoint found");
71
+ }
13
72
  function determine_protocol(endpoint) {
14
73
  if (endpoint.startsWith("http")) {
15
74
  const { protocol, host } = new URL(endpoint);
@@ -41,10 +100,10 @@ function determine_protocol(endpoint) {
41
100
  }
42
101
  const RE_SPACE_NAME = /^[^\/]*\/[^\/]*$/;
43
102
  const RE_SPACE_DOMAIN = /.*hf\.space\/{0,1}$/;
44
- async function process_endpoint(app_reference, token) {
103
+ async function process_endpoint(app_reference, hf_token) {
45
104
  const headers = {};
46
- if (token) {
47
- headers.Authorization = `Bearer ${token}`;
105
+ if (hf_token) {
106
+ headers.Authorization = `Bearer ${hf_token}`;
48
107
  }
49
108
  const _app_reference = app_reference.trim();
50
109
  if (RE_SPACE_NAME.test(_app_reference)) {
@@ -78,143 +137,331 @@ async function process_endpoint(app_reference, token) {
78
137
  ...determine_protocol(_app_reference)
79
138
  };
80
139
  }
81
- function map_names_to_ids(fns) {
82
- let apis = {};
83
- fns.forEach(({ api_name }, i) => {
84
- if (api_name)
85
- apis[api_name] = i;
140
+ function transform_api_info(api_info, config, api_map) {
141
+ const transformed_info = {
142
+ named_endpoints: {},
143
+ unnamed_endpoints: {}
144
+ };
145
+ Object.keys(api_info).forEach((category) => {
146
+ if (category === "named_endpoints" || category === "unnamed_endpoints") {
147
+ transformed_info[category] = {};
148
+ Object.entries(api_info[category]).forEach(
149
+ ([endpoint, { parameters, returns }]) => {
150
+ const dependencyIndex = config.dependencies.findIndex((dep) => dep.api_name === endpoint) || api_map[endpoint.replace("/", "")] || -1;
151
+ const dependencyTypes = dependencyIndex !== -1 ? config.dependencies[dependencyIndex].types : { continuous: false, generator: false };
152
+ const transform_type = (data, component, serializer, signature_type) => ({
153
+ ...data,
154
+ description: get_description(data.type, serializer),
155
+ type: get_type(data.type, component, serializer, signature_type) || ""
156
+ });
157
+ transformed_info[category][endpoint] = {
158
+ parameters: parameters.map(
159
+ (p) => transform_type(p, p.component, p.serializer, "parameter")
160
+ ),
161
+ returns: returns.map(
162
+ (r) => transform_type(r, r.component, r.serializer, "return")
163
+ ),
164
+ type: dependencyTypes
165
+ };
166
+ }
167
+ );
168
+ }
86
169
  });
87
- return apis;
170
+ return transformed_info;
88
171
  }
89
- const RE_DISABLED_DISCUSSION = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
90
- async function discussions_enabled(space_id) {
91
- try {
92
- const r = await fetch(
93
- `https://huggingface.co/api/spaces/${space_id}/discussions`,
94
- {
95
- method: "HEAD"
96
- }
97
- );
98
- const error = r.headers.get("x-error-message");
99
- if (error && RE_DISABLED_DISCUSSION.test(error))
100
- return false;
101
- return true;
102
- } catch (e) {
103
- return false;
172
+ function get_type(type, component, serializer, signature_type) {
173
+ switch (type.type) {
174
+ case "string":
175
+ return "string";
176
+ case "boolean":
177
+ return "boolean";
178
+ case "number":
179
+ return "number";
180
+ }
181
+ if (serializer === "JSONSerializable" || serializer === "StringSerializable") {
182
+ return "any";
183
+ } else if (serializer === "ListStringSerializable") {
184
+ return "string[]";
185
+ } else if (component === "Image") {
186
+ return signature_type === "parameter" ? "Blob | File | Buffer" : "string";
187
+ } else if (serializer === "FileSerializable") {
188
+ if ((type == null ? void 0 : type.type) === "array") {
189
+ return signature_type === "parameter" ? "(Blob | File | Buffer)[]" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`;
190
+ }
191
+ return signature_type === "parameter" ? "Blob | File | Buffer" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
192
+ } else if (serializer === "GallerySerializable") {
193
+ return signature_type === "parameter" ? "[(Blob | File | Buffer), (string | null)][]" : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`;
104
194
  }
105
195
  }
106
- async function get_space_hardware(space_id, token) {
107
- const headers = {};
108
- if (token) {
109
- headers.Authorization = `Bearer ${token}`;
196
+ function get_description(type, serializer) {
197
+ if (serializer === "GallerySerializable") {
198
+ return "array of [file, label] tuples";
199
+ } else if (serializer === "ListStringSerializable") {
200
+ return "array of strings";
201
+ } else if (serializer === "FileSerializable") {
202
+ return "array of files or single file";
110
203
  }
111
- try {
112
- const res = await fetch(
113
- `https://huggingface.co/api/spaces/${space_id}/runtime`,
114
- { headers }
115
- );
116
- if (res.status !== 200)
117
- throw new Error("Space hardware could not be obtained.");
118
- const { hardware } = await res.json();
119
- return hardware;
120
- } catch (e) {
121
- throw new Error(e.message);
204
+ return type.description;
205
+ }
206
+ function handle_message(data, last_status) {
207
+ const queue = true;
208
+ switch (data.msg) {
209
+ case "send_data":
210
+ return { type: "data" };
211
+ case "send_hash":
212
+ return { type: "hash" };
213
+ case "queue_full":
214
+ return {
215
+ type: "update",
216
+ status: {
217
+ queue,
218
+ message: QUEUE_FULL_MSG,
219
+ stage: "error",
220
+ code: data.code,
221
+ success: data.success
222
+ }
223
+ };
224
+ case "heartbeat":
225
+ return {
226
+ type: "heartbeat"
227
+ };
228
+ case "unexpected_error":
229
+ return {
230
+ type: "unexpected_error",
231
+ status: {
232
+ queue,
233
+ message: data.message,
234
+ stage: "error",
235
+ success: false
236
+ }
237
+ };
238
+ case "estimation":
239
+ return {
240
+ type: "update",
241
+ status: {
242
+ queue,
243
+ stage: last_status || "pending",
244
+ code: data.code,
245
+ size: data.queue_size,
246
+ position: data.rank,
247
+ eta: data.rank_eta,
248
+ success: data.success
249
+ }
250
+ };
251
+ case "progress":
252
+ return {
253
+ type: "update",
254
+ status: {
255
+ queue,
256
+ stage: "pending",
257
+ code: data.code,
258
+ progress_data: data.progress_data,
259
+ success: data.success
260
+ }
261
+ };
262
+ case "log":
263
+ return { type: "log", data };
264
+ case "process_generating":
265
+ return {
266
+ type: "generating",
267
+ status: {
268
+ queue,
269
+ message: !data.success ? data.output.error : null,
270
+ stage: data.success ? "generating" : "error",
271
+ code: data.code,
272
+ progress_data: data.progress_data,
273
+ eta: data.average_duration
274
+ },
275
+ data: data.success ? data.output : null
276
+ };
277
+ case "process_completed":
278
+ if ("error" in data.output) {
279
+ return {
280
+ type: "update",
281
+ status: {
282
+ queue,
283
+ message: data.output.error,
284
+ stage: "error",
285
+ code: data.code,
286
+ success: data.success
287
+ }
288
+ };
289
+ }
290
+ return {
291
+ type: "complete",
292
+ status: {
293
+ queue,
294
+ message: !data.success ? data.output.error : void 0,
295
+ stage: data.success ? "complete" : "error",
296
+ code: data.code,
297
+ progress_data: data.progress_data
298
+ },
299
+ data: data.success ? data.output : null
300
+ };
301
+ case "process_starts":
302
+ return {
303
+ type: "update",
304
+ status: {
305
+ queue,
306
+ stage: "pending",
307
+ code: data.code,
308
+ size: data.rank,
309
+ position: 0,
310
+ success: data.success,
311
+ eta: data.eta
312
+ }
313
+ };
122
314
  }
315
+ return { type: "none", status: { stage: "error", queue } };
123
316
  }
124
- async function set_space_hardware(space_id, new_hardware, token) {
125
- const headers = {};
126
- if (token) {
127
- headers.Authorization = `Bearer ${token}`;
317
+ async function view_api() {
318
+ if (this.api_info)
319
+ return this.api_info;
320
+ const { hf_token } = this.options;
321
+ const { config } = this;
322
+ const headers = { "Content-Type": "application/json" };
323
+ if (hf_token) {
324
+ headers.Authorization = `Bearer ${hf_token}`;
325
+ }
326
+ if (!config) {
327
+ return;
128
328
  }
129
329
  try {
130
- const res = await fetch(
131
- `https://huggingface.co/api/spaces/${space_id}/hardware`,
132
- { headers, body: JSON.stringify(new_hardware) }
133
- );
134
- if (res.status !== 200)
135
- throw new Error(
136
- "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in."
330
+ let response;
331
+ if (semiver$1((config == null ? void 0 : config.version) || "2.0.0", "3.30") < 0) {
332
+ response = await this.fetch_implementation(SPACE_FETCHER_URL, {
333
+ method: "POST",
334
+ body: JSON.stringify({
335
+ serialize: false,
336
+ config: JSON.stringify(config)
337
+ }),
338
+ headers
339
+ });
340
+ } else {
341
+ response = await this.fetch_implementation(
342
+ `${config == null ? void 0 : config.root}/${API_INFO_URL}`,
343
+ {
344
+ headers
345
+ }
137
346
  );
138
- const { hardware } = await res.json();
139
- return hardware;
347
+ }
348
+ if (!response.ok) {
349
+ throw new Error(BROKEN_CONNECTION_MSG);
350
+ }
351
+ let api_info = await response.json();
352
+ if ("api" in api_info) {
353
+ api_info = api_info.api;
354
+ }
355
+ if (api_info.named_endpoints["/predict"] && !api_info.unnamed_endpoints["0"]) {
356
+ api_info.unnamed_endpoints[0] = api_info.named_endpoints["/predict"];
357
+ }
358
+ return transform_api_info(api_info, config, this.api_map);
140
359
  } catch (e) {
141
- throw new Error(e.message);
360
+ "Could not get API info. " + e.message;
142
361
  }
143
362
  }
144
- async function set_space_timeout(space_id, timeout, token) {
363
+ async function upload_files(root_url, files, upload_id) {
145
364
  const headers = {};
146
- if (token) {
147
- headers.Authorization = `Bearer ${token}`;
148
- }
149
- try {
150
- const res = await fetch(
151
- `https://huggingface.co/api/spaces/${space_id}/hardware`,
152
- { headers, body: JSON.stringify({ seconds: timeout }) }
153
- );
154
- if (res.status !== 200)
155
- throw new Error(
156
- "Space hardware could not be set. Please ensure the space hardware provided is valid and that a Hugging Face token is passed in."
157
- );
158
- const { hardware } = await res.json();
159
- return hardware;
160
- } catch (e) {
161
- throw new Error(e.message);
365
+ if (this.options.hf_token) {
366
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
162
367
  }
163
- }
164
- const hardware_types = [
165
- "cpu-basic",
166
- "cpu-upgrade",
167
- "t4-small",
168
- "t4-medium",
169
- "a10g-small",
170
- "a10g-large",
171
- "a100-large"
172
- ];
173
- function apply_edit(target, path, action, value) {
174
- if (path.length === 0) {
175
- if (action === "replace") {
176
- return value;
177
- } else if (action === "append") {
178
- return target + value;
368
+ const chunkSize = 1e3;
369
+ const uploadResponses = [];
370
+ for (let i = 0; i < files.length; i += chunkSize) {
371
+ const chunk = files.slice(i, i + chunkSize);
372
+ const formData = new FormData();
373
+ chunk.forEach((file) => {
374
+ formData.append("files", file);
375
+ });
376
+ 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
+ method: "POST",
380
+ body: formData,
381
+ headers
382
+ });
383
+ } catch (e) {
384
+ return { error: BROKEN_CONNECTION_MSG };
385
+ }
386
+ if (!response.ok) {
387
+ return { error: await response.text() };
388
+ }
389
+ const output = await response.json();
390
+ if (output) {
391
+ uploadResponses.push(...output);
179
392
  }
180
- throw new Error(`Unsupported action: ${action}`);
181
393
  }
182
- let current = target;
183
- for (let i = 0; i < path.length - 1; i++) {
184
- current = current[path[i]];
394
+ return { files: uploadResponses };
395
+ }
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
+ }
185
404
  }
186
- const last_path = path[path.length - 1];
187
- switch (action) {
188
- case "replace":
189
- current[last_path] = value;
190
- break;
191
- case "append":
192
- current[last_path] += value;
193
- break;
194
- case "add":
195
- if (Array.isArray(current)) {
196
- current.splice(Number(last_path), 0, value);
197
- } else {
198
- current[last_path] = value;
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
199
438
  }
200
- break;
201
- case "delete":
202
- if (Array.isArray(current)) {
203
- current.splice(Number(last_path), 1);
204
- } else {
205
- delete current[last_path];
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
+ );
206
456
  }
207
- break;
208
- default:
209
- throw new Error(`Unknown action: ${action}`);
457
+ }
458
+ return blob_refs;
210
459
  }
211
- return target;
460
+ return [];
212
461
  }
213
- function apply_diff(obj, diff) {
214
- diff.forEach(([action, path, value]) => {
215
- obj = apply_edit(obj, path, action, value);
216
- });
217
- return obj;
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;
218
465
  }
219
466
  function post_message(message, origin) {
220
467
  return new Promise((res, _rej) => {
@@ -226,12 +473,20 @@ function post_message(message, origin) {
226
473
  window.parent.postMessage(message, origin, [channel.port2]);
227
474
  });
228
475
  }
229
- async function upload(file_data, root, upload_id, upload_fn = upload_files) {
476
+ async function upload(file_data, root_url, upload_id, max_file_size, upload_fn = upload_files) {
230
477
  let files = (Array.isArray(file_data) ? file_data : [file_data]).map(
231
478
  (file_data2) => file_data2.blob
232
479
  );
480
+ const oversized_files = files.filter(
481
+ (f) => f.size > (max_file_size ?? Infinity)
482
+ );
483
+ if (oversized_files.length) {
484
+ throw new Error(
485
+ `File size exceeds the maximum allowed size of ${max_file_size} bytes: ${oversized_files.map((f) => f.name).join(", ")}`
486
+ );
487
+ }
233
488
  return await Promise.all(
234
- await upload_fn(root, files, void 0, upload_id).then(
489
+ await upload_fn(root_url, files, upload_id).then(
235
490
  async (response) => {
236
491
  if (response.error) {
237
492
  throw new Error(response.error);
@@ -241,7 +496,7 @@ async function upload(file_data, root, upload_id, upload_fn = upload_files) {
241
496
  const file = new FileData({
242
497
  ...file_data[i],
243
498
  path: f,
244
- url: root + "/file=" + f
499
+ url: root_url + "/file=" + f
245
500
  });
246
501
  return file;
247
502
  });
@@ -254,7 +509,7 @@ async function upload(file_data, root, upload_id, upload_fn = upload_files) {
254
509
  }
255
510
  async function prepare_files(files, is_stream) {
256
511
  return files.map(
257
- (f, i) => new FileData({
512
+ (f) => new FileData({
258
513
  path: f.name,
259
514
  orig_name: f.name,
260
515
  blob: f,
@@ -275,7 +530,15 @@ class FileData {
275
530
  mime_type,
276
531
  alt_text
277
532
  }) {
278
- this.meta = { _type: "gradio.FileData" };
533
+ __publicField(this, "path");
534
+ __publicField(this, "url");
535
+ __publicField(this, "orig_name");
536
+ __publicField(this, "size");
537
+ __publicField(this, "blob");
538
+ __publicField(this, "is_stream");
539
+ __publicField(this, "mime_type");
540
+ __publicField(this, "alt_text");
541
+ __publicField(this, "meta", { _type: "gradio.FileData" });
279
542
  this.path = path;
280
543
  this.url = url;
281
544
  this.orig_name = orig_name;
@@ -286,1349 +549,1273 @@ class FileData {
286
549
  this.alt_text = alt_text;
287
550
  }
288
551
  }
289
- const QUEUE_FULL_MSG = "This application is too busy. Keep trying!";
290
- const BROKEN_CONNECTION_MSG = "Connection errored out.";
291
- let NodeBlob;
292
- async function duplicate(app_reference, options) {
293
- const { hf_token, private: _private, hardware, timeout } = options;
294
- if (hardware && !hardware_types.includes(hardware)) {
552
+ async function handle_blob(endpoint, data, api_info) {
553
+ const self = this;
554
+ const blobRefs = await walk_and_store_blobs(
555
+ data,
556
+ void 0,
557
+ [],
558
+ true,
559
+ api_info
560
+ );
561
+ const results = await Promise.all(
562
+ blobRefs.map(async ({ path, blob, type }) => {
563
+ if (!blob)
564
+ return { path, type };
565
+ const response = await self.upload_files(endpoint, [blob]);
566
+ const file_url = response.files && response.files[0];
567
+ return {
568
+ path,
569
+ file_url,
570
+ type,
571
+ name: blob == null ? void 0 : blob.name
572
+ };
573
+ })
574
+ );
575
+ results.forEach(({ path, file_url, type, name }) => {
576
+ if (type === "Gallery") {
577
+ update_object(data, file_url, path);
578
+ } else if (file_url) {
579
+ const file = new FileData({ path: file_url, orig_name: name });
580
+ update_object(data, file, path);
581
+ }
582
+ });
583
+ return data;
584
+ }
585
+ async function post_data(url, body, additional_headers) {
586
+ const headers = { "Content-Type": "application/json" };
587
+ if (this.options.hf_token) {
588
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
589
+ }
590
+ try {
591
+ var response = await this.fetch_implementation(url, {
592
+ method: "POST",
593
+ body: JSON.stringify(body),
594
+ headers: { ...headers, ...additional_headers }
595
+ });
596
+ } catch (e) {
597
+ return [{ error: BROKEN_CONNECTION_MSG }, 500];
598
+ }
599
+ let output;
600
+ let status;
601
+ try {
602
+ output = await response.json();
603
+ status = response.status;
604
+ } catch (e) {
605
+ output = { error: `Could not parse server response: ${e}` };
606
+ status = 500;
607
+ }
608
+ return [output, status];
609
+ }
610
+ async function predict(endpoint, data) {
611
+ let data_returned = false;
612
+ let status_complete = false;
613
+ let dependency;
614
+ if (!this.config) {
615
+ throw new Error("Could not resolve app config");
616
+ }
617
+ if (typeof endpoint === "number") {
618
+ dependency = this.config.dependencies[endpoint];
619
+ } else {
620
+ const trimmed_endpoint = endpoint.replace(/^\//, "");
621
+ dependency = this.config.dependencies[this.api_map[trimmed_endpoint]];
622
+ }
623
+ if (dependency == null ? void 0 : dependency.types.continuous) {
295
624
  throw new Error(
296
- `Invalid hardware type provided. Valid types are: ${hardware_types.map((v) => `"${v}"`).join(",")}.`
625
+ "Cannot call predict on this function as it may run forever. Use submit instead"
297
626
  );
298
627
  }
299
- const headers = {
300
- Authorization: `Bearer ${hf_token}`
301
- };
302
- const user = (await (await fetch(`https://huggingface.co/api/whoami-v2`, {
303
- headers
304
- })).json()).name;
305
- const space_name = app_reference.split("/")[1];
306
- const body = {
307
- repository: `${user}/${space_name}`
308
- };
309
- if (_private) {
310
- body.private = true;
628
+ return new Promise(async (resolve, reject) => {
629
+ const app = this.submit(endpoint, data || []);
630
+ let result;
631
+ app.on("data", (d) => {
632
+ if (status_complete) {
633
+ app.destroy();
634
+ resolve(d);
635
+ }
636
+ data_returned = true;
637
+ result = d;
638
+ }).on("status", (status) => {
639
+ if (status.stage === "error")
640
+ reject(status);
641
+ if (status.stage === "complete") {
642
+ status_complete = true;
643
+ if (data_returned) {
644
+ app.destroy();
645
+ resolve(result);
646
+ }
647
+ }
648
+ });
649
+ });
650
+ }
651
+ async function check_space_status(id, type, status_callback) {
652
+ let endpoint = type === "subdomain" ? `https://huggingface.co/api/spaces/by-subdomain/${id}` : `https://huggingface.co/api/spaces/${id}`;
653
+ let response;
654
+ let _status;
655
+ try {
656
+ response = await fetch(endpoint);
657
+ _status = response.status;
658
+ if (_status !== 200) {
659
+ throw new Error();
660
+ }
661
+ response = await response.json();
662
+ } catch (e) {
663
+ status_callback({
664
+ status: "error",
665
+ load_status: "error",
666
+ message: "Could not get space status",
667
+ detail: "NOT_FOUND"
668
+ });
669
+ return;
670
+ }
671
+ if (!response || _status !== 200)
672
+ return;
673
+ const {
674
+ runtime: { stage },
675
+ id: space_name
676
+ } = response;
677
+ switch (stage) {
678
+ case "STOPPED":
679
+ case "SLEEPING":
680
+ status_callback({
681
+ status: "sleeping",
682
+ load_status: "pending",
683
+ message: "Space is asleep. Waking it up...",
684
+ detail: stage
685
+ });
686
+ setTimeout(() => {
687
+ check_space_status(id, type, status_callback);
688
+ }, 1e3);
689
+ break;
690
+ case "PAUSED":
691
+ status_callback({
692
+ status: "paused",
693
+ load_status: "error",
694
+ message: "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
695
+ detail: stage,
696
+ discussions_enabled: await discussions_enabled(space_name)
697
+ });
698
+ break;
699
+ case "RUNNING":
700
+ case "RUNNING_BUILDING":
701
+ status_callback({
702
+ status: "running",
703
+ load_status: "complete",
704
+ message: "",
705
+ detail: stage
706
+ });
707
+ break;
708
+ case "BUILDING":
709
+ status_callback({
710
+ status: "building",
711
+ load_status: "pending",
712
+ message: "Space is building...",
713
+ detail: stage
714
+ });
715
+ setTimeout(() => {
716
+ check_space_status(id, type, status_callback);
717
+ }, 1e3);
718
+ break;
719
+ default:
720
+ status_callback({
721
+ status: "space_error",
722
+ load_status: "error",
723
+ message: "This space is experiencing an issue.",
724
+ detail: stage,
725
+ discussions_enabled: await discussions_enabled(space_name)
726
+ });
727
+ break;
311
728
  }
729
+ }
730
+ const RE_DISABLED_DISCUSSION = /^(?=[^]*\b[dD]iscussions{0,1}\b)(?=[^]*\b[dD]isabled\b)[^]*$/;
731
+ async function discussions_enabled(space_id) {
312
732
  try {
313
- const response = await fetch(
314
- `https://huggingface.co/api/spaces/${app_reference}/duplicate`,
733
+ const r = await fetch(
734
+ `https://huggingface.co/api/spaces/${space_id}/discussions`,
315
735
  {
316
- method: "POST",
317
- headers: { "Content-Type": "application/json", ...headers },
318
- body: JSON.stringify(body)
736
+ method: "HEAD"
319
737
  }
320
738
  );
321
- if (response.status === 409) {
322
- return client(`${user}/${space_name}`, options);
323
- }
324
- const duplicated_space = await response.json();
325
- let original_hardware;
326
- if (!hardware) {
327
- original_hardware = await get_space_hardware(app_reference, hf_token);
328
- }
329
- const requested_hardware = hardware || original_hardware || "cpu-basic";
330
- await set_space_hardware(
331
- `${user}/${space_name}`,
332
- requested_hardware,
333
- hf_token
334
- );
335
- await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
336
- return client(duplicated_space.url, options);
739
+ const error = r.headers.get("x-error-message");
740
+ if (error && RE_DISABLED_DISCUSSION.test(error))
741
+ return false;
742
+ return true;
337
743
  } catch (e) {
338
- throw new Error(e);
744
+ return false;
339
745
  }
340
746
  }
341
- function api_factory(fetch_implementation, EventSource_factory) {
342
- return { post_data: post_data2, upload_files: upload_files2, client: client2, handle_blob: handle_blob2 };
343
- async function post_data2(url, body, token, additional_headers) {
344
- const headers = { "Content-Type": "application/json" };
345
- if (token) {
346
- headers.Authorization = `Bearer ${token}`;
347
- }
348
- try {
349
- var response = await fetch_implementation(url, {
350
- method: "POST",
351
- body: JSON.stringify(body),
352
- headers: { ...headers, ...additional_headers }
353
- });
354
- } catch (e) {
355
- return [{ error: BROKEN_CONNECTION_MSG }, 500];
356
- }
357
- let output;
358
- let status;
359
- try {
360
- output = await response.json();
361
- status = response.status;
362
- } catch (e) {
363
- output = { error: `Could not parse server response: ${e}` };
364
- status = 500;
365
- }
366
- return [output, status];
747
+ async function get_space_hardware(space_id, hf_token) {
748
+ const headers = {};
749
+ if (hf_token) {
750
+ headers.Authorization = `Bearer ${hf_token}`;
367
751
  }
368
- async function upload_files2(root, files, token, upload_id) {
369
- const headers = {};
370
- if (token) {
371
- headers.Authorization = `Bearer ${token}`;
372
- }
373
- const chunkSize = 1e3;
374
- const uploadResponses = [];
375
- for (let i = 0; i < files.length; i += chunkSize) {
376
- const chunk = files.slice(i, i + chunkSize);
377
- const formData = new FormData();
378
- chunk.forEach((file) => {
379
- formData.append("files", file);
380
- });
381
- try {
382
- const upload_url = upload_id ? `${root}/upload?upload_id=${upload_id}` : `${root}/upload`;
383
- var response = await fetch_implementation(upload_url, {
384
- method: "POST",
385
- body: formData,
386
- headers
387
- });
388
- } catch (e) {
389
- return { error: BROKEN_CONNECTION_MSG };
752
+ try {
753
+ const res = await fetch(
754
+ `https://huggingface.co/api/spaces/${space_id}/runtime`,
755
+ { headers }
756
+ );
757
+ if (res.status !== 200)
758
+ throw new Error("Space hardware could not be obtained.");
759
+ const { hardware } = await res.json();
760
+ return hardware.current;
761
+ } catch (e) {
762
+ throw new Error(e.message);
763
+ }
764
+ }
765
+ async function set_space_timeout(space_id, timeout, hf_token) {
766
+ const headers = {};
767
+ if (hf_token) {
768
+ headers.Authorization = `Bearer ${hf_token}`;
769
+ }
770
+ const body = {
771
+ seconds: timeout
772
+ };
773
+ try {
774
+ const res = await fetch(
775
+ `https://huggingface.co/api/spaces/${space_id}/sleeptime`,
776
+ {
777
+ method: "POST",
778
+ headers: { "Content-Type": "application/json", ...headers },
779
+ body: JSON.stringify(body)
390
780
  }
391
- const output = await response.json();
392
- uploadResponses.push(...output);
781
+ );
782
+ if (res.status !== 200) {
783
+ throw new Error(
784
+ "Could not set sleep timeout on duplicated Space. Please visit *ADD HF LINK TO SETTINGS* to set a timeout manually to reduce billing charges."
785
+ );
393
786
  }
394
- return { files: uploadResponses };
787
+ const response = await res.json();
788
+ return response;
789
+ } catch (e) {
790
+ throw new Error(e.message);
395
791
  }
396
- async function client2(app_reference, options = {}) {
397
- return new Promise(async (res) => {
398
- const { status_callback, hf_token } = options;
399
- const return_obj = {
400
- predict,
401
- submit,
402
- view_api,
403
- component_server
404
- };
405
- if ((typeof window === "undefined" || !("WebSocket" in window)) && !global.Websocket) {
406
- const ws = await import("./wrapper-6f348d45.js");
407
- NodeBlob = (await import("node:buffer")).Blob;
408
- global.WebSocket = ws.WebSocket;
792
+ }
793
+ const hardware_types = [
794
+ "cpu-basic",
795
+ "cpu-upgrade",
796
+ "cpu-xl",
797
+ "t4-small",
798
+ "t4-medium",
799
+ "a10g-small",
800
+ "a10g-large",
801
+ "a10g-largex2",
802
+ "a10g-largex4",
803
+ "a100-large",
804
+ "zero-a10g",
805
+ "h100",
806
+ "h100x8"
807
+ ];
808
+ async function duplicate(app_reference, options) {
809
+ const { hf_token, private: _private, hardware, timeout } = options;
810
+ if (hardware && !hardware_types.includes(hardware)) {
811
+ throw new Error(
812
+ `Invalid hardware type provided. Valid types are: ${hardware_types.map((v) => `"${v}"`).join(",")}.`
813
+ );
814
+ }
815
+ const headers = {
816
+ Authorization: `Bearer ${hf_token}`,
817
+ "Content-Type": "application/json"
818
+ };
819
+ const user = (await (await fetch(`https://huggingface.co/api/whoami-v2`, {
820
+ headers
821
+ })).json()).name;
822
+ const space_name = app_reference.split("/")[1];
823
+ const body = {
824
+ repository: `${user}/${space_name}`
825
+ };
826
+ if (_private) {
827
+ body.private = true;
828
+ }
829
+ let original_hardware;
830
+ if (!hardware) {
831
+ original_hardware = await get_space_hardware(app_reference, hf_token);
832
+ }
833
+ const requested_hardware = hardware || original_hardware || "cpu-basic";
834
+ body.hardware = requested_hardware;
835
+ try {
836
+ const response = await fetch(
837
+ `https://huggingface.co/api/spaces/${app_reference}/duplicate`,
838
+ {
839
+ method: "POST",
840
+ headers,
841
+ body: JSON.stringify(body)
409
842
  }
410
- const { ws_protocol, http_protocol, host, space_id } = await process_endpoint(app_reference, hf_token);
411
- const session_hash = Math.random().toString(36).substring(2);
412
- const last_status = {};
413
- let stream_open = false;
414
- let pending_stream_messages = {};
415
- let pending_diff_streams = {};
416
- let event_stream = null;
417
- const event_callbacks = {};
418
- const unclosed_events = /* @__PURE__ */ new Set();
419
- let config;
420
- let api_map = {};
421
- let jwt = false;
422
- if (hf_token && space_id) {
423
- jwt = await get_jwt(space_id, hf_token);
843
+ );
844
+ if (response.status === 409) {
845
+ try {
846
+ const client2 = await Client.connect(`${user}/${space_name}`, options);
847
+ return client2;
848
+ } catch (error) {
849
+ console.error("Failed to connect Client instance:", error);
850
+ throw error;
424
851
  }
425
- async function config_success(_config) {
426
- config = _config;
427
- if (window.location.protocol === "https:") {
428
- config.root = config.root.replace("http://", "https://");
429
- }
430
- api_map = map_names_to_ids((_config == null ? void 0 : _config.dependencies) || []);
431
- if (config.auth_required) {
432
- return {
433
- config,
434
- ...return_obj
435
- };
436
- }
437
- try {
438
- api = await view_api(config);
439
- } catch (e) {
440
- console.error(`Could not get api details: ${e.message}`);
852
+ } else if (response.status !== 200) {
853
+ throw new Error(response.statusText);
854
+ }
855
+ const duplicated_space = await response.json();
856
+ await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
857
+ return await Client.connect(duplicated_space.url, options);
858
+ } catch (e) {
859
+ throw new Error(e);
860
+ }
861
+ }
862
+ function open_stream() {
863
+ let {
864
+ event_callbacks,
865
+ unclosed_events,
866
+ pending_stream_messages,
867
+ stream_status,
868
+ config
869
+ } = this;
870
+ if (!config) {
871
+ throw new Error("Could not resolve app config");
872
+ }
873
+ stream_status.open = true;
874
+ let event_source = null;
875
+ let params = new URLSearchParams({
876
+ session_hash: this.session_hash
877
+ }).toString();
878
+ 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());
882
+ }
883
+ event_source.onmessage = async function(event) {
884
+ let _data = JSON.parse(event.data);
885
+ if (_data.msg === "close_stream") {
886
+ close_stream(stream_status, event_source);
887
+ return;
888
+ }
889
+ const event_id = _data.event_id;
890
+ if (!event_id) {
891
+ await Promise.all(
892
+ Object.keys(event_callbacks).map(
893
+ (event_id2) => (
894
+ // @ts-ignore
895
+ event_callbacks[event_id2](_data)
896
+ )
897
+ // todo: check event_callbacks
898
+ )
899
+ );
900
+ } else if (event_callbacks[event_id] && config) {
901
+ if (_data.msg === "process_completed" && ["sse", "sse_v1", "sse_v2", "sse_v2.1"].includes(config.protocol)) {
902
+ unclosed_events.delete(event_id);
903
+ if (unclosed_events.size === 0) {
904
+ close_stream(stream_status, event_source);
441
905
  }
442
- return {
443
- config,
444
- ...return_obj
445
- };
446
906
  }
447
- let api;
448
- async function handle_space_sucess(status) {
449
- if (status_callback)
450
- status_callback(status);
451
- if (status.status === "running")
452
- try {
453
- config = await resolve_config(
454
- fetch_implementation,
455
- `${http_protocol}//${host}`,
456
- hf_token
457
- );
458
- const _config = await config_success(config);
459
- res(_config);
460
- } catch (e) {
461
- console.error(e);
462
- if (status_callback) {
463
- status_callback({
464
- status: "error",
465
- message: "Could not load this space.",
466
- load_status: "error",
467
- detail: "NOT_FOUND"
468
- });
469
- }
470
- }
907
+ let fn2 = event_callbacks[event_id];
908
+ window.setTimeout(fn2, 0, _data);
909
+ } else {
910
+ if (!pending_stream_messages[event_id]) {
911
+ pending_stream_messages[event_id] = [];
471
912
  }
472
- try {
473
- config = await resolve_config(
474
- fetch_implementation,
475
- `${http_protocol}//${host}`,
476
- hf_token
477
- );
478
- const _config = await config_success(config);
479
- const heartbeat_url = new URL(
480
- `${config.root}/heartbeat/${session_hash}`
481
- );
482
- EventSource_factory(heartbeat_url);
483
- res(_config);
484
- } catch (e) {
485
- console.error(e);
486
- if (space_id) {
487
- check_space_status(
488
- space_id,
489
- RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain",
490
- handle_space_sucess
491
- );
492
- } else {
493
- if (status_callback)
494
- status_callback({
495
- status: "error",
496
- message: "Could not load this space.",
497
- load_status: "error",
498
- detail: "NOT_FOUND"
499
- });
500
- }
913
+ pending_stream_messages[event_id].push(_data);
914
+ }
915
+ };
916
+ event_source.onerror = async function() {
917
+ await Promise.all(
918
+ 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
+ )
926
+ )
927
+ );
928
+ close_stream(stream_status, event_source);
929
+ };
930
+ }
931
+ function close_stream(stream_status, event_source) {
932
+ if (stream_status && event_source) {
933
+ stream_status.open = false;
934
+ event_source == null ? void 0 : event_source.close();
935
+ }
936
+ }
937
+ function apply_diff_stream(pending_diff_streams, event_id, data) {
938
+ let is_first_generation = !pending_diff_streams[event_id];
939
+ if (is_first_generation) {
940
+ pending_diff_streams[event_id] = [];
941
+ data.data.forEach((value, i) => {
942
+ pending_diff_streams[event_id][i] = value;
943
+ });
944
+ } else {
945
+ data.data.forEach((value, i) => {
946
+ let new_data = apply_diff(pending_diff_streams[event_id][i], value);
947
+ pending_diff_streams[event_id][i] = new_data;
948
+ data.data[i] = new_data;
949
+ });
950
+ }
951
+ }
952
+ function apply_diff(obj, diff) {
953
+ diff.forEach(([action, path, value]) => {
954
+ obj = apply_edit(obj, path, action, value);
955
+ });
956
+ return obj;
957
+ }
958
+ function apply_edit(target, path, action, value) {
959
+ if (path.length === 0) {
960
+ if (action === "replace") {
961
+ return value;
962
+ } else if (action === "append") {
963
+ return target + value;
964
+ }
965
+ throw new Error(`Unsupported action: ${action}`);
966
+ }
967
+ let current = target;
968
+ for (let i = 0; i < path.length - 1; i++) {
969
+ current = current[path[i]];
970
+ }
971
+ const last_path = path[path.length - 1];
972
+ switch (action) {
973
+ case "replace":
974
+ current[last_path] = value;
975
+ break;
976
+ case "append":
977
+ current[last_path] += value;
978
+ break;
979
+ case "add":
980
+ if (Array.isArray(current)) {
981
+ current.splice(Number(last_path), 0, value);
982
+ } else {
983
+ current[last_path] = value;
984
+ }
985
+ break;
986
+ case "delete":
987
+ if (Array.isArray(current)) {
988
+ current.splice(Number(last_path), 1);
989
+ } else {
990
+ delete current[last_path];
991
+ }
992
+ break;
993
+ default:
994
+ throw new Error(`Unknown action: ${action}`);
995
+ }
996
+ return target;
997
+ }
998
+ function submit(endpoint, data, event_data, trigger_id) {
999
+ try {
1000
+ let fire_event = function(event) {
1001
+ const narrowed_listener_map = listener_map;
1002
+ const listeners = narrowed_listener_map[event.type] || [];
1003
+ listeners == null ? void 0 : listeners.forEach((l) => l(event));
1004
+ }, on = function(eventType, listener) {
1005
+ const narrowed_listener_map = listener_map;
1006
+ const listeners = narrowed_listener_map[eventType] || [];
1007
+ narrowed_listener_map[eventType] = listeners;
1008
+ listeners == null ? void 0 : listeners.push(listener);
1009
+ return { on, off, cancel, destroy };
1010
+ }, off = function(eventType, listener) {
1011
+ const narrowed_listener_map = listener_map;
1012
+ let listeners = narrowed_listener_map[eventType] || [];
1013
+ listeners = listeners == null ? void 0 : listeners.filter((l) => l !== listener);
1014
+ narrowed_listener_map[eventType] = listeners;
1015
+ return { on, off, cancel, destroy };
1016
+ }, destroy = function() {
1017
+ var _a;
1018
+ for (const event_type in listener_map) {
1019
+ listener_map && ((_a = listener_map[event_type]) == null ? void 0 : _a.forEach((fn2) => {
1020
+ off(event_type, fn2);
1021
+ }));
501
1022
  }
502
- function predict(endpoint, data, event_data) {
503
- let data_returned = false;
504
- let status_complete = false;
505
- let dependency;
506
- if (typeof endpoint === "number") {
507
- dependency = config.dependencies[endpoint];
1023
+ };
1024
+ const { hf_token } = this.options;
1025
+ const {
1026
+ fetch_implementation,
1027
+ app_reference,
1028
+ config,
1029
+ session_hash,
1030
+ api_info,
1031
+ api_map,
1032
+ stream_status,
1033
+ pending_stream_messages,
1034
+ pending_diff_streams,
1035
+ event_callbacks,
1036
+ unclosed_events,
1037
+ post_data: post_data2
1038
+ } = this;
1039
+ if (!api_info)
1040
+ throw new Error("No API found");
1041
+ if (!config)
1042
+ throw new Error("Could not resolve app config");
1043
+ let { fn_index, endpoint_info, dependency } = get_endpoint_info(
1044
+ api_info,
1045
+ endpoint,
1046
+ api_map,
1047
+ config
1048
+ );
1049
+ let websocket;
1050
+ let event_source;
1051
+ let protocol = config.protocol ?? "ws";
1052
+ const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
1053
+ let payload;
1054
+ let event_id = null;
1055
+ let complete = false;
1056
+ const listener_map = {};
1057
+ let last_status = {};
1058
+ let url_params = typeof window !== "undefined" ? new URLSearchParams(window.location.search).toString() : "";
1059
+ async function cancel() {
1060
+ const _status = {
1061
+ stage: "complete",
1062
+ queue: false,
1063
+ time: /* @__PURE__ */ new Date()
1064
+ };
1065
+ complete = _status;
1066
+ fire_event({
1067
+ ..._status,
1068
+ type: "status",
1069
+ endpoint: _endpoint,
1070
+ fn_index
1071
+ });
1072
+ let cancel_request = {};
1073
+ if (protocol === "ws") {
1074
+ if (websocket && websocket.readyState === 0) {
1075
+ websocket.addEventListener("open", () => {
1076
+ websocket.close();
1077
+ });
508
1078
  } else {
509
- const trimmed_endpoint = endpoint.replace(/^\//, "");
510
- dependency = config.dependencies[api_map[trimmed_endpoint]];
1079
+ websocket.close();
511
1080
  }
512
- if (dependency.types.continuous) {
513
- throw new Error(
514
- "Cannot call predict on this function as it may run forever. Use submit instead"
515
- );
1081
+ cancel_request = { fn_index, session_hash };
1082
+ } else {
1083
+ event_source == null ? void 0 : event_source.close();
1084
+ cancel_request = { event_id };
1085
+ }
1086
+ try {
1087
+ if (!config) {
1088
+ throw new Error("Could not resolve app config");
516
1089
  }
517
- return new Promise((res2, rej) => {
518
- const app = submit(endpoint, data, event_data);
519
- let result;
520
- app.on("data", (d) => {
521
- if (status_complete) {
522
- app.destroy();
523
- res2(d);
524
- }
525
- data_returned = true;
526
- result = d;
527
- }).on("status", (status) => {
528
- if (status.stage === "error")
529
- rej(status);
530
- if (status.stage === "complete") {
531
- status_complete = true;
532
- if (data_returned) {
533
- app.destroy();
534
- res2(result);
535
- }
536
- }
537
- });
1090
+ await fetch_implementation(`${config.root}/reset`, {
1091
+ headers: { "Content-Type": "application/json" },
1092
+ method: "POST",
1093
+ body: JSON.stringify(cancel_request)
538
1094
  });
1095
+ } catch (e) {
1096
+ console.warn(
1097
+ "The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable."
1098
+ );
539
1099
  }
540
- function submit(endpoint, data, event_data, trigger_id = null) {
541
- let fn_index;
542
- let api_info;
543
- let dependency;
544
- if (typeof endpoint === "number") {
545
- fn_index = endpoint;
546
- api_info = api.unnamed_endpoints[fn_index];
547
- dependency = config.dependencies[endpoint];
548
- } else {
549
- const trimmed_endpoint = endpoint.replace(/^\//, "");
550
- fn_index = api_map[trimmed_endpoint];
551
- api_info = api.named_endpoints[endpoint.trim()];
552
- dependency = config.dependencies[api_map[trimmed_endpoint]];
553
- }
554
- if (typeof fn_index !== "number") {
555
- throw new Error(
556
- "There is no endpoint matching that name of fn_index matching that number."
557
- );
558
- }
559
- let websocket;
560
- let eventSource;
561
- let protocol = config.protocol ?? "ws";
562
- const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
563
- let payload;
564
- let event_id = null;
565
- let complete = false;
566
- const listener_map = {};
567
- let url_params = "";
568
- if (typeof window !== "undefined") {
569
- url_params = new URLSearchParams(window.location.search).toString();
570
- }
571
- handle_blob2(`${config.root}`, data, api_info, hf_token).then(
572
- (_payload) => {
573
- payload = {
574
- data: _payload || [],
575
- event_data,
576
- fn_index,
577
- trigger_id
578
- };
579
- if (skip_queue(fn_index, config)) {
1100
+ }
1101
+ this.handle_blob(`${config.root}`, data, endpoint_info).then(
1102
+ async (_payload) => {
1103
+ payload = {
1104
+ data: _payload || [],
1105
+ event_data,
1106
+ fn_index,
1107
+ trigger_id
1108
+ };
1109
+ if (skip_queue(fn_index, config)) {
1110
+ fire_event({
1111
+ type: "status",
1112
+ endpoint: _endpoint,
1113
+ stage: "pending",
1114
+ queue: false,
1115
+ fn_index,
1116
+ time: /* @__PURE__ */ new Date()
1117
+ });
1118
+ post_data2(
1119
+ `${config.root}/run${_endpoint.startsWith("/") ? _endpoint : `/${_endpoint}`}${url_params ? "?" + url_params : ""}`,
1120
+ {
1121
+ ...payload,
1122
+ session_hash
1123
+ }
1124
+ ).then(([output, status_code]) => {
1125
+ const data2 = output.data;
1126
+ if (status_code == 200) {
1127
+ fire_event({
1128
+ type: "data",
1129
+ endpoint: _endpoint,
1130
+ fn_index,
1131
+ data: data2,
1132
+ time: /* @__PURE__ */ new Date(),
1133
+ event_data,
1134
+ trigger_id
1135
+ });
580
1136
  fire_event({
581
1137
  type: "status",
582
1138
  endpoint: _endpoint,
583
- stage: "pending",
584
- queue: false,
585
1139
  fn_index,
1140
+ stage: "complete",
1141
+ eta: output.average_duration,
1142
+ queue: false,
586
1143
  time: /* @__PURE__ */ new Date()
587
1144
  });
588
- post_data2(
589
- `${config.root}/run${_endpoint.startsWith("/") ? _endpoint : `/${_endpoint}`}${url_params ? "?" + url_params : ""}`,
590
- {
591
- ...payload,
592
- session_hash
593
- },
594
- hf_token
595
- ).then(([output, status_code]) => {
596
- const data2 = output.data;
597
- if (status_code == 200) {
598
- fire_event({
599
- type: "data",
600
- endpoint: _endpoint,
601
- fn_index,
602
- data: data2,
603
- time: /* @__PURE__ */ new Date()
604
- });
605
- fire_event({
606
- type: "status",
607
- endpoint: _endpoint,
608
- fn_index,
609
- stage: "complete",
610
- eta: output.average_duration,
611
- queue: false,
612
- time: /* @__PURE__ */ new Date()
613
- });
614
- } else {
615
- fire_event({
616
- type: "status",
617
- stage: "error",
618
- endpoint: _endpoint,
619
- fn_index,
620
- message: output.error,
621
- queue: false,
622
- time: /* @__PURE__ */ new Date()
623
- });
624
- }
625
- }).catch((e) => {
626
- fire_event({
627
- type: "status",
628
- stage: "error",
629
- message: e.message,
630
- endpoint: _endpoint,
631
- fn_index,
632
- queue: false,
633
- time: /* @__PURE__ */ new Date()
634
- });
1145
+ } else {
1146
+ fire_event({
1147
+ type: "status",
1148
+ stage: "error",
1149
+ endpoint: _endpoint,
1150
+ fn_index,
1151
+ message: output.error,
1152
+ queue: false,
1153
+ time: /* @__PURE__ */ new Date()
635
1154
  });
636
- } else if (protocol == "ws") {
1155
+ }
1156
+ }).catch((e) => {
1157
+ fire_event({
1158
+ type: "status",
1159
+ stage: "error",
1160
+ message: e.message,
1161
+ endpoint: _endpoint,
1162
+ fn_index,
1163
+ queue: false,
1164
+ time: /* @__PURE__ */ new Date()
1165
+ });
1166
+ });
1167
+ } else if (protocol == "ws") {
1168
+ const { ws_protocol, host } = await process_endpoint(
1169
+ app_reference,
1170
+ hf_token
1171
+ );
1172
+ fire_event({
1173
+ type: "status",
1174
+ stage: "pending",
1175
+ queue: true,
1176
+ endpoint: _endpoint,
1177
+ fn_index,
1178
+ time: /* @__PURE__ */ new Date()
1179
+ });
1180
+ let url = new URL(
1181
+ `${ws_protocol}://${resolve_root(
1182
+ host,
1183
+ config.path,
1184
+ true
1185
+ )}/queue/join${url_params ? "?" + url_params : ""}`
1186
+ );
1187
+ if (this.jwt) {
1188
+ url.searchParams.set("__sign", this.jwt);
1189
+ }
1190
+ websocket = new WebSocket(url);
1191
+ websocket.onclose = (evt) => {
1192
+ if (!evt.wasClean) {
637
1193
  fire_event({
638
1194
  type: "status",
639
- stage: "pending",
1195
+ stage: "error",
1196
+ broken: true,
1197
+ message: BROKEN_CONNECTION_MSG,
640
1198
  queue: true,
641
1199
  endpoint: _endpoint,
642
1200
  fn_index,
643
1201
  time: /* @__PURE__ */ new Date()
644
1202
  });
645
- let url = new URL(`${ws_protocol}://${resolve_root(
646
- host,
647
- config.path,
648
- true
649
- )}
650
- /queue/join${url_params ? "?" + url_params : ""}`);
651
- if (jwt) {
652
- url.searchParams.set("__sign", jwt);
1203
+ }
1204
+ };
1205
+ websocket.onmessage = function(event) {
1206
+ const _data = JSON.parse(event.data);
1207
+ const { type, status, data: data2 } = handle_message(
1208
+ _data,
1209
+ last_status[fn_index]
1210
+ );
1211
+ if (type === "update" && status && !complete) {
1212
+ fire_event({
1213
+ type: "status",
1214
+ endpoint: _endpoint,
1215
+ fn_index,
1216
+ time: /* @__PURE__ */ new Date(),
1217
+ ...status
1218
+ });
1219
+ if (status.stage === "error") {
1220
+ websocket.close();
653
1221
  }
654
- websocket = new WebSocket(url);
655
- websocket.onclose = (evt) => {
656
- if (!evt.wasClean) {
657
- fire_event({
658
- type: "status",
659
- stage: "error",
660
- broken: true,
661
- message: BROKEN_CONNECTION_MSG,
662
- queue: true,
663
- endpoint: _endpoint,
664
- fn_index,
665
- time: /* @__PURE__ */ new Date()
666
- });
667
- }
668
- };
669
- websocket.onmessage = function(event) {
670
- const _data = JSON.parse(event.data);
671
- const { type, status, data: data2 } = handle_message(
672
- _data,
673
- last_status[fn_index]
674
- );
675
- if (type === "update" && status && !complete) {
676
- fire_event({
677
- type: "status",
678
- endpoint: _endpoint,
679
- fn_index,
680
- time: /* @__PURE__ */ new Date(),
681
- ...status
682
- });
683
- if (status.stage === "error") {
684
- websocket.close();
685
- }
686
- } else if (type === "hash") {
687
- websocket.send(JSON.stringify({ fn_index, session_hash }));
688
- return;
689
- } else if (type === "data") {
690
- websocket.send(JSON.stringify({ ...payload, session_hash }));
691
- } else if (type === "complete") {
692
- complete = status;
693
- } else if (type === "log") {
694
- fire_event({
695
- type: "log",
696
- log: data2.log,
697
- level: data2.level,
698
- endpoint: _endpoint,
699
- fn_index
700
- });
701
- } else if (type === "generating") {
702
- fire_event({
703
- type: "status",
704
- time: /* @__PURE__ */ new Date(),
705
- ...status,
706
- stage: status == null ? void 0 : status.stage,
707
- queue: true,
708
- endpoint: _endpoint,
709
- fn_index
710
- });
711
- }
712
- if (data2) {
713
- fire_event({
714
- type: "data",
715
- time: /* @__PURE__ */ new Date(),
716
- data: data2.data,
717
- endpoint: _endpoint,
718
- fn_index
719
- });
720
- if (complete) {
721
- fire_event({
722
- type: "status",
723
- time: /* @__PURE__ */ new Date(),
724
- ...complete,
725
- stage: status == null ? void 0 : status.stage,
726
- queue: true,
727
- endpoint: _endpoint,
728
- fn_index
729
- });
730
- websocket.close();
731
- }
732
- }
733
- };
734
- if (semiver(config.version || "2.0.0", "3.6") < 0) {
735
- addEventListener(
736
- "open",
737
- () => websocket.send(JSON.stringify({ hash: session_hash }))
738
- );
1222
+ } else if (type === "hash") {
1223
+ websocket.send(JSON.stringify({ fn_index, session_hash }));
1224
+ return;
1225
+ } else if (type === "data") {
1226
+ websocket.send(JSON.stringify({ ...payload, session_hash }));
1227
+ } else if (type === "complete") {
1228
+ complete = status;
1229
+ } else if (type === "log") {
1230
+ fire_event({
1231
+ type: "log",
1232
+ log: data2.log,
1233
+ level: data2.level,
1234
+ endpoint: _endpoint,
1235
+ fn_index
1236
+ });
1237
+ } else if (type === "generating") {
1238
+ fire_event({
1239
+ type: "status",
1240
+ time: /* @__PURE__ */ new Date(),
1241
+ ...status,
1242
+ stage: status == null ? void 0 : status.stage,
1243
+ queue: true,
1244
+ endpoint: _endpoint,
1245
+ fn_index
1246
+ });
1247
+ }
1248
+ if (data2) {
1249
+ fire_event({
1250
+ type: "data",
1251
+ time: /* @__PURE__ */ new Date(),
1252
+ data: data2.data,
1253
+ endpoint: _endpoint,
1254
+ fn_index,
1255
+ event_data,
1256
+ trigger_id
1257
+ });
1258
+ if (complete) {
1259
+ fire_event({
1260
+ type: "status",
1261
+ time: /* @__PURE__ */ new Date(),
1262
+ ...complete,
1263
+ stage: status == null ? void 0 : status.stage,
1264
+ queue: true,
1265
+ endpoint: _endpoint,
1266
+ fn_index
1267
+ });
1268
+ websocket.close();
1269
+ }
1270
+ }
1271
+ };
1272
+ if (semiver(config.version || "2.0.0", "3.6") < 0) {
1273
+ addEventListener(
1274
+ "open",
1275
+ () => websocket.send(JSON.stringify({ hash: session_hash }))
1276
+ );
1277
+ }
1278
+ } else if (protocol == "sse") {
1279
+ fire_event({
1280
+ type: "status",
1281
+ stage: "pending",
1282
+ queue: true,
1283
+ endpoint: _endpoint,
1284
+ fn_index,
1285
+ time: /* @__PURE__ */ new Date()
1286
+ });
1287
+ var params = new URLSearchParams({
1288
+ fn_index: fn_index.toString(),
1289
+ session_hash
1290
+ }).toString();
1291
+ let url = new URL(
1292
+ `${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}`
1293
+ );
1294
+ event_source = this.eventSource_factory(url);
1295
+ if (!event_source) {
1296
+ throw new Error(
1297
+ "Cannot connect to sse endpoint: " + url.toString()
1298
+ );
1299
+ }
1300
+ event_source.onmessage = async function(event) {
1301
+ const _data = JSON.parse(event.data);
1302
+ const { type, status, data: data2 } = handle_message(
1303
+ _data,
1304
+ last_status[fn_index]
1305
+ );
1306
+ if (type === "update" && status && !complete) {
1307
+ fire_event({
1308
+ type: "status",
1309
+ endpoint: _endpoint,
1310
+ fn_index,
1311
+ time: /* @__PURE__ */ new Date(),
1312
+ ...status
1313
+ });
1314
+ if (status.stage === "error") {
1315
+ event_source == null ? void 0 : event_source.close();
1316
+ }
1317
+ } else if (type === "data") {
1318
+ event_id = _data.event_id;
1319
+ let [_, status2] = await post_data2(`${config.root}/queue/data`, {
1320
+ ...payload,
1321
+ session_hash,
1322
+ event_id
1323
+ });
1324
+ if (status2 !== 200) {
1325
+ fire_event({
1326
+ type: "status",
1327
+ stage: "error",
1328
+ message: BROKEN_CONNECTION_MSG,
1329
+ queue: true,
1330
+ endpoint: _endpoint,
1331
+ fn_index,
1332
+ time: /* @__PURE__ */ new Date()
1333
+ });
1334
+ event_source == null ? void 0 : event_source.close();
739
1335
  }
740
- } else if (protocol == "sse") {
1336
+ } else if (type === "complete") {
1337
+ complete = status;
1338
+ } else if (type === "log") {
1339
+ fire_event({
1340
+ type: "log",
1341
+ log: data2.log,
1342
+ level: data2.level,
1343
+ endpoint: _endpoint,
1344
+ fn_index
1345
+ });
1346
+ } else if (type === "generating") {
741
1347
  fire_event({
742
1348
  type: "status",
743
- stage: "pending",
1349
+ time: /* @__PURE__ */ new Date(),
1350
+ ...status,
1351
+ stage: status == null ? void 0 : status.stage,
744
1352
  queue: true,
745
1353
  endpoint: _endpoint,
1354
+ fn_index
1355
+ });
1356
+ }
1357
+ if (data2) {
1358
+ fire_event({
1359
+ type: "data",
1360
+ time: /* @__PURE__ */ new Date(),
1361
+ data: data2.data,
1362
+ endpoint: _endpoint,
746
1363
  fn_index,
747
- time: /* @__PURE__ */ new Date()
1364
+ event_data,
1365
+ trigger_id
748
1366
  });
749
- var params = new URLSearchParams({
750
- fn_index: fn_index.toString(),
1367
+ if (complete) {
1368
+ fire_event({
1369
+ type: "status",
1370
+ time: /* @__PURE__ */ new Date(),
1371
+ ...complete,
1372
+ stage: status == null ? void 0 : status.stage,
1373
+ queue: true,
1374
+ endpoint: _endpoint,
1375
+ fn_index
1376
+ });
1377
+ event_source == null ? void 0 : event_source.close();
1378
+ }
1379
+ }
1380
+ };
1381
+ } else if (protocol == "sse_v1" || protocol == "sse_v2" || protocol == "sse_v2.1" || protocol == "sse_v3") {
1382
+ fire_event({
1383
+ type: "status",
1384
+ stage: "pending",
1385
+ queue: true,
1386
+ endpoint: _endpoint,
1387
+ fn_index,
1388
+ time: /* @__PURE__ */ new Date()
1389
+ });
1390
+ let hostname = window.location.hostname;
1391
+ let hfhubdev = "dev.spaces.huggingface.tech";
1392
+ const origin = hostname.includes(".dev.") ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}` : `https://huggingface.co`;
1393
+ const zerogpu_auth_promise = dependency.zerogpu && window.parent != window && config.space_id ? post_message("zerogpu-headers", origin) : Promise.resolve(null);
1394
+ const post_data_promise = zerogpu_auth_promise.then((headers) => {
1395
+ return post_data2(
1396
+ `${config.root}/queue/join?${url_params}`,
1397
+ {
1398
+ ...payload,
751
1399
  session_hash
752
- }).toString();
753
- let url = new URL(
754
- `${config.root}/queue/join?${url_params ? url_params + "&" : ""}${params}`
755
- );
756
- eventSource = EventSource_factory(url);
757
- eventSource.onmessage = async function(event) {
758
- const _data = JSON.parse(event.data);
759
- const { type, status, data: data2 } = handle_message(
760
- _data,
761
- last_status[fn_index]
762
- );
763
- if (type === "update" && status && !complete) {
764
- fire_event({
765
- type: "status",
766
- endpoint: _endpoint,
767
- fn_index,
768
- time: /* @__PURE__ */ new Date(),
769
- ...status
770
- });
771
- if (status.stage === "error") {
772
- eventSource.close();
773
- }
774
- } else if (type === "data") {
775
- event_id = _data.event_id;
776
- let [_, status2] = await post_data2(
777
- `${config.root}/queue/data`,
778
- {
779
- ...payload,
780
- session_hash,
781
- event_id
782
- },
783
- hf_token
1400
+ },
1401
+ headers
1402
+ );
1403
+ });
1404
+ post_data_promise.then(([response, status]) => {
1405
+ if (status === 503) {
1406
+ fire_event({
1407
+ type: "status",
1408
+ stage: "error",
1409
+ message: QUEUE_FULL_MSG,
1410
+ queue: true,
1411
+ endpoint: _endpoint,
1412
+ fn_index,
1413
+ time: /* @__PURE__ */ new Date()
1414
+ });
1415
+ } else if (status !== 200) {
1416
+ fire_event({
1417
+ type: "status",
1418
+ stage: "error",
1419
+ message: BROKEN_CONNECTION_MSG,
1420
+ queue: true,
1421
+ endpoint: _endpoint,
1422
+ fn_index,
1423
+ time: /* @__PURE__ */ new Date()
1424
+ });
1425
+ } else {
1426
+ event_id = response.event_id;
1427
+ let callback = async function(_data) {
1428
+ try {
1429
+ const { type, status: status2, data: data2 } = handle_message(
1430
+ _data,
1431
+ last_status[fn_index]
784
1432
  );
785
- if (status2 !== 200) {
1433
+ if (type == "heartbeat") {
1434
+ return;
1435
+ }
1436
+ if (type === "update" && status2 && !complete) {
1437
+ fire_event({
1438
+ type: "status",
1439
+ endpoint: _endpoint,
1440
+ fn_index,
1441
+ time: /* @__PURE__ */ new Date(),
1442
+ ...status2
1443
+ });
1444
+ } else if (type === "complete") {
1445
+ complete = status2;
1446
+ } else if (type == "unexpected_error") {
1447
+ console.error("Unexpected error", status2 == null ? void 0 : status2.message);
786
1448
  fire_event({
787
1449
  type: "status",
788
1450
  stage: "error",
789
- message: BROKEN_CONNECTION_MSG,
1451
+ message: (status2 == null ? void 0 : status2.message) || "An Unexpected Error Occurred!",
790
1452
  queue: true,
791
1453
  endpoint: _endpoint,
792
1454
  fn_index,
793
1455
  time: /* @__PURE__ */ new Date()
794
1456
  });
795
- eventSource.close();
796
- }
797
- } else if (type === "complete") {
798
- complete = status;
799
- } else if (type === "log") {
800
- fire_event({
801
- type: "log",
802
- log: data2.log,
803
- level: data2.level,
804
- endpoint: _endpoint,
805
- fn_index
806
- });
807
- } else if (type === "generating") {
808
- fire_event({
809
- type: "status",
810
- time: /* @__PURE__ */ new Date(),
811
- ...status,
812
- stage: status == null ? void 0 : status.stage,
813
- queue: true,
814
- endpoint: _endpoint,
815
- fn_index
816
- });
817
- }
818
- if (data2) {
819
- fire_event({
820
- type: "data",
821
- time: /* @__PURE__ */ new Date(),
822
- data: data2.data,
823
- endpoint: _endpoint,
824
- fn_index
825
- });
826
- if (complete) {
1457
+ } else if (type === "log") {
1458
+ fire_event({
1459
+ type: "log",
1460
+ log: data2.log,
1461
+ level: data2.level,
1462
+ endpoint: _endpoint,
1463
+ fn_index
1464
+ });
1465
+ return;
1466
+ } else if (type === "generating") {
827
1467
  fire_event({
828
1468
  type: "status",
829
1469
  time: /* @__PURE__ */ new Date(),
830
- ...complete,
831
- stage: status == null ? void 0 : status.stage,
1470
+ ...status2,
1471
+ stage: status2 == null ? void 0 : status2.stage,
832
1472
  queue: true,
833
1473
  endpoint: _endpoint,
834
1474
  fn_index
835
1475
  });
836
- eventSource.close();
1476
+ if (data2 && ["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) {
1477
+ apply_diff_stream(pending_diff_streams, event_id, data2);
1478
+ }
837
1479
  }
838
- }
839
- };
840
- } else if (protocol == "sse_v1" || protocol == "sse_v2" || protocol == "sse_v2.1" || protocol == "sse_v3") {
841
- fire_event({
842
- type: "status",
843
- stage: "pending",
844
- queue: true,
845
- endpoint: _endpoint,
846
- fn_index,
847
- time: /* @__PURE__ */ new Date()
848
- });
849
- let hostname = window.location.hostname;
850
- let hfhubdev = "dev.spaces.huggingface.tech";
851
- const origin = hostname.includes(".dev.") ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}` : `https://huggingface.co`;
852
- const zerogpu_auth_promise = dependency.zerogpu && window.parent != window && config.space_id ? post_message("zerogpu-headers", origin) : Promise.resolve(null);
853
- const post_data_promise = zerogpu_auth_promise.then((headers) => {
854
- return post_data2(
855
- `${config.root}/queue/join?${url_params}`,
856
- {
857
- ...payload,
858
- session_hash
859
- },
860
- hf_token,
861
- headers
862
- );
863
- });
864
- post_data_promise.then(([response, status]) => {
865
- if (status === 503) {
866
- fire_event({
867
- type: "status",
868
- stage: "error",
869
- message: QUEUE_FULL_MSG,
870
- queue: true,
871
- endpoint: _endpoint,
872
- fn_index,
873
- time: /* @__PURE__ */ new Date()
874
- });
875
- } else if (status !== 200) {
1480
+ if (data2) {
1481
+ fire_event({
1482
+ type: "data",
1483
+ time: /* @__PURE__ */ new Date(),
1484
+ data: data2.data,
1485
+ endpoint: _endpoint,
1486
+ fn_index
1487
+ });
1488
+ if (complete) {
1489
+ fire_event({
1490
+ type: "status",
1491
+ time: /* @__PURE__ */ new Date(),
1492
+ ...complete,
1493
+ stage: status2 == null ? void 0 : status2.stage,
1494
+ queue: true,
1495
+ endpoint: _endpoint,
1496
+ fn_index
1497
+ });
1498
+ }
1499
+ }
1500
+ if ((status2 == null ? void 0 : status2.stage) === "complete" || (status2 == null ? void 0 : status2.stage) === "error") {
1501
+ if (event_callbacks[event_id]) {
1502
+ delete event_callbacks[event_id];
1503
+ }
1504
+ if (event_id in pending_diff_streams) {
1505
+ delete pending_diff_streams[event_id];
1506
+ }
1507
+ }
1508
+ } catch (e) {
1509
+ console.error("Unexpected client exception", e);
876
1510
  fire_event({
877
1511
  type: "status",
878
1512
  stage: "error",
879
- message: BROKEN_CONNECTION_MSG,
1513
+ message: "An Unexpected Error Occurred!",
880
1514
  queue: true,
881
1515
  endpoint: _endpoint,
882
1516
  fn_index,
883
1517
  time: /* @__PURE__ */ new Date()
884
1518
  });
885
- } else {
886
- event_id = response.event_id;
887
- let callback = async function(_data) {
888
- try {
889
- const { type, status: status2, data: data2 } = handle_message(
890
- _data,
891
- last_status[fn_index]
892
- );
893
- if (type == "heartbeat") {
894
- return;
895
- }
896
- if (type === "update" && status2 && !complete) {
897
- fire_event({
898
- type: "status",
899
- endpoint: _endpoint,
900
- fn_index,
901
- time: /* @__PURE__ */ new Date(),
902
- ...status2
903
- });
904
- } else if (type === "complete") {
905
- complete = status2;
906
- } else if (type == "unexpected_error") {
907
- console.error("Unexpected error", status2 == null ? void 0 : status2.message);
908
- fire_event({
909
- type: "status",
910
- stage: "error",
911
- message: (status2 == null ? void 0 : status2.message) || "An Unexpected Error Occurred!",
912
- queue: true,
913
- endpoint: _endpoint,
914
- fn_index,
915
- time: /* @__PURE__ */ new Date()
916
- });
917
- } else if (type === "log") {
918
- fire_event({
919
- type: "log",
920
- log: data2.log,
921
- level: data2.level,
922
- endpoint: _endpoint,
923
- fn_index
924
- });
925
- return;
926
- } else if (type === "generating") {
927
- fire_event({
928
- type: "status",
929
- time: /* @__PURE__ */ new Date(),
930
- ...status2,
931
- stage: status2 == null ? void 0 : status2.stage,
932
- queue: true,
933
- endpoint: _endpoint,
934
- fn_index
935
- });
936
- if (data2 && ["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) {
937
- apply_diff_stream(event_id, data2);
938
- }
939
- }
940
- if (data2) {
941
- fire_event({
942
- type: "data",
943
- time: /* @__PURE__ */ new Date(),
944
- data: data2.data,
945
- endpoint: _endpoint,
946
- fn_index
947
- });
948
- if (complete) {
949
- fire_event({
950
- type: "status",
951
- time: /* @__PURE__ */ new Date(),
952
- ...complete,
953
- stage: status2 == null ? void 0 : status2.stage,
954
- queue: true,
955
- endpoint: _endpoint,
956
- fn_index
957
- });
958
- }
959
- }
960
- if ((status2 == null ? void 0 : status2.stage) === "complete" || (status2 == null ? void 0 : status2.stage) === "error") {
961
- if (event_callbacks[event_id]) {
962
- delete event_callbacks[event_id];
963
- }
964
- if (event_id in pending_diff_streams) {
965
- delete pending_diff_streams[event_id];
966
- }
967
- }
968
- } catch (e) {
969
- console.error("Unexpected client exception", e);
970
- fire_event({
971
- type: "status",
972
- stage: "error",
973
- message: "An Unexpected Error Occurred!",
974
- queue: true,
975
- endpoint: _endpoint,
976
- fn_index,
977
- time: /* @__PURE__ */ new Date()
978
- });
979
- if (["sse_v2", "sse_v2.1"].includes(protocol)) {
980
- close_stream();
981
- }
982
- }
983
- };
984
- if (event_id in pending_stream_messages) {
985
- pending_stream_messages[event_id].forEach(
986
- (msg) => callback(msg)
987
- );
988
- delete pending_stream_messages[event_id];
989
- }
990
- event_callbacks[event_id] = callback;
991
- unclosed_events.add(event_id);
992
- if (!stream_open) {
993
- open_stream();
1519
+ if (["sse_v2", "sse_v2.1"].includes(protocol)) {
1520
+ close_stream(stream_status, event_source);
1521
+ stream_status.open = false;
994
1522
  }
995
1523
  }
996
- });
1524
+ };
1525
+ if (event_id in pending_stream_messages) {
1526
+ pending_stream_messages[event_id].forEach(
1527
+ (msg) => callback(msg)
1528
+ );
1529
+ delete pending_stream_messages[event_id];
1530
+ }
1531
+ event_callbacks[event_id] = callback;
1532
+ unclosed_events.add(event_id);
1533
+ if (!stream_status.open) {
1534
+ this.open_stream();
1535
+ }
997
1536
  }
998
- }
999
- );
1000
- function apply_diff_stream(event_id2, data2) {
1001
- let is_first_generation = !pending_diff_streams[event_id2];
1002
- if (is_first_generation) {
1003
- pending_diff_streams[event_id2] = [];
1004
- data2.data.forEach((value, i) => {
1005
- pending_diff_streams[event_id2][i] = value;
1006
- });
1007
- } else {
1008
- data2.data.forEach((value, i) => {
1009
- let new_data = apply_diff(
1010
- pending_diff_streams[event_id2][i],
1011
- value
1012
- );
1013
- pending_diff_streams[event_id2][i] = new_data;
1014
- data2.data[i] = new_data;
1015
- });
1016
- }
1017
- }
1018
- function fire_event(event) {
1019
- const narrowed_listener_map = listener_map;
1020
- const listeners = narrowed_listener_map[event.type] || [];
1021
- listeners == null ? void 0 : listeners.forEach((l) => l(event));
1022
- }
1023
- function on(eventType, listener) {
1024
- const narrowed_listener_map = listener_map;
1025
- const listeners = narrowed_listener_map[eventType] || [];
1026
- narrowed_listener_map[eventType] = listeners;
1027
- listeners == null ? void 0 : listeners.push(listener);
1028
- return { on, off, cancel, destroy };
1029
- }
1030
- function off(eventType, listener) {
1031
- const narrowed_listener_map = listener_map;
1032
- let listeners = narrowed_listener_map[eventType] || [];
1033
- listeners = listeners == null ? void 0 : listeners.filter((l) => l !== listener);
1034
- narrowed_listener_map[eventType] = listeners;
1035
- return { on, off, cancel, destroy };
1036
- }
1037
- async function cancel() {
1038
- const _status = {
1039
- stage: "complete",
1040
- queue: false,
1041
- time: /* @__PURE__ */ new Date()
1042
- };
1043
- complete = _status;
1044
- fire_event({
1045
- ..._status,
1046
- type: "status",
1047
- endpoint: _endpoint,
1048
- fn_index
1049
1537
  });
1050
- let cancel_request = {};
1051
- if (protocol === "ws") {
1052
- if (websocket && websocket.readyState === 0) {
1053
- websocket.addEventListener("open", () => {
1054
- websocket.close();
1055
- });
1056
- } else {
1057
- websocket.close();
1058
- }
1059
- cancel_request = { fn_index, session_hash };
1060
- } else {
1061
- eventSource.close();
1062
- cancel_request = { event_id };
1063
- }
1064
- try {
1065
- await fetch_implementation(`${config.root}/reset`, {
1066
- headers: { "Content-Type": "application/json" },
1067
- method: "POST",
1068
- body: JSON.stringify(cancel_request)
1069
- });
1070
- } catch (e) {
1071
- console.warn(
1072
- "The `/reset` endpoint could not be called. Subsequent endpoint results may be unreliable."
1073
- );
1074
- }
1075
1538
  }
1076
- function destroy() {
1077
- for (const event_type in listener_map) {
1078
- listener_map[event_type].forEach((fn2) => {
1079
- off(event_type, fn2);
1080
- });
1081
- }
1082
- }
1083
- return {
1084
- on,
1085
- off,
1086
- cancel,
1087
- destroy
1088
- };
1089
1539
  }
1090
- function open_stream() {
1091
- stream_open = true;
1092
- let params = new URLSearchParams({
1093
- session_hash
1094
- }).toString();
1095
- let url = new URL(`${config.root}/queue/data?${params}`);
1096
- event_stream = EventSource_factory(url);
1097
- event_stream.onmessage = async function(event) {
1098
- let _data = JSON.parse(event.data);
1099
- if (_data.msg === "close_stream") {
1100
- close_stream();
1101
- return;
1102
- }
1103
- const event_id = _data.event_id;
1104
- if (!event_id) {
1105
- await Promise.all(
1106
- Object.keys(event_callbacks).map(
1107
- (event_id2) => event_callbacks[event_id2](_data)
1108
- )
1540
+ );
1541
+ return { on, off, cancel, destroy };
1542
+ } catch (error) {
1543
+ console.error("Submit function encountered an error:", error);
1544
+ throw error;
1545
+ }
1546
+ }
1547
+ function get_endpoint_info(api_info, endpoint, api_map, config) {
1548
+ let fn_index;
1549
+ let endpoint_info;
1550
+ let dependency;
1551
+ if (typeof endpoint === "number") {
1552
+ fn_index = endpoint;
1553
+ endpoint_info = api_info.unnamed_endpoints[fn_index];
1554
+ dependency = config.dependencies[endpoint];
1555
+ } else {
1556
+ const trimmed_endpoint = endpoint.replace(/^\//, "");
1557
+ fn_index = api_map[trimmed_endpoint];
1558
+ endpoint_info = api_info.named_endpoints[endpoint.trim()];
1559
+ dependency = config.dependencies[api_map[trimmed_endpoint]];
1560
+ }
1561
+ if (typeof fn_index !== "number") {
1562
+ throw new Error(
1563
+ "There is no endpoint matching that name of fn_index matching that number."
1564
+ );
1565
+ }
1566
+ return { fn_index, endpoint_info, dependency };
1567
+ }
1568
+ class NodeBlob extends Blob {
1569
+ constructor(blobParts, options) {
1570
+ super(blobParts, options);
1571
+ }
1572
+ }
1573
+ class Client {
1574
+ constructor(app_reference, options = {}) {
1575
+ __publicField(this, "app_reference");
1576
+ __publicField(this, "options");
1577
+ __publicField(this, "config");
1578
+ __publicField(this, "api_info");
1579
+ __publicField(this, "api_map", {});
1580
+ __publicField(this, "session_hash", Math.random().toString(36).substring(2));
1581
+ __publicField(this, "jwt", false);
1582
+ __publicField(this, "last_status", {});
1583
+ // streaming
1584
+ __publicField(this, "stream_status", { open: false });
1585
+ __publicField(this, "pending_stream_messages", {});
1586
+ __publicField(this, "pending_diff_streams", {});
1587
+ __publicField(this, "event_callbacks", {});
1588
+ __publicField(this, "unclosed_events", /* @__PURE__ */ new Set());
1589
+ __publicField(this, "heartbeat_event", null);
1590
+ __publicField(this, "view_api");
1591
+ __publicField(this, "upload_files");
1592
+ __publicField(this, "handle_blob");
1593
+ __publicField(this, "post_data");
1594
+ __publicField(this, "submit");
1595
+ __publicField(this, "predict");
1596
+ __publicField(this, "open_stream");
1597
+ __publicField(this, "resolve_config");
1598
+ this.app_reference = app_reference;
1599
+ this.options = options;
1600
+ this.view_api = view_api.bind(this);
1601
+ this.upload_files = upload_files.bind(this);
1602
+ this.handle_blob = handle_blob.bind(this);
1603
+ this.post_data = post_data.bind(this);
1604
+ this.submit = submit.bind(this);
1605
+ this.predict = predict.bind(this);
1606
+ this.open_stream = open_stream.bind(this);
1607
+ this.resolve_config = resolve_config.bind(this);
1608
+ }
1609
+ fetch_implementation(input, init) {
1610
+ return fetch(input, init);
1611
+ }
1612
+ eventSource_factory(url) {
1613
+ if (typeof window !== void 0 && typeof EventSource !== "undefined") {
1614
+ return new EventSource(url.toString());
1615
+ }
1616
+ return null;
1617
+ }
1618
+ async init() {
1619
+ var _a;
1620
+ if ((typeof window === "undefined" || !("WebSocket" in window)) && !global.WebSocket) {
1621
+ const ws = await import("./wrapper-CviSselG.js");
1622
+ NodeBlob = (await import("node:buffer")).Blob;
1623
+ global.WebSocket = ws.WebSocket;
1624
+ }
1625
+ try {
1626
+ await this._resolve_config().then(async ({ config }) => {
1627
+ if (config) {
1628
+ this.config = config;
1629
+ if (this.config) {
1630
+ const heartbeat_url = new URL(
1631
+ `${this.config.root}/heartbeat/${this.session_hash}`
1109
1632
  );
1110
- } else if (event_callbacks[event_id]) {
1111
- if (_data.msg === "process_completed" && ["sse", "sse_v1", "sse_v2", "sse_v2.1"].includes(config.protocol)) {
1112
- unclosed_events.delete(event_id);
1113
- if (unclosed_events.size === 0) {
1114
- close_stream();
1115
- }
1116
- }
1117
- let fn2 = event_callbacks[event_id];
1118
- window.setTimeout(fn2, 0, _data);
1119
- } else {
1120
- if (!pending_stream_messages[event_id]) {
1121
- pending_stream_messages[event_id] = [];
1633
+ this.heartbeat_event = this.eventSource_factory(heartbeat_url);
1634
+ if (this.config.space_id && this.options.hf_token) {
1635
+ this.jwt = await get_jwt(
1636
+ this.config.space_id,
1637
+ this.options.hf_token
1638
+ );
1122
1639
  }
1123
- pending_stream_messages[event_id].push(_data);
1124
1640
  }
1125
- };
1126
- event_stream.onerror = async function(event) {
1127
- await Promise.all(
1128
- Object.keys(event_callbacks).map(
1129
- (event_id) => event_callbacks[event_id]({
1130
- msg: "unexpected_error",
1131
- message: BROKEN_CONNECTION_MSG
1132
- })
1133
- )
1134
- );
1135
- close_stream();
1136
- };
1137
- }
1138
- function close_stream() {
1139
- stream_open = false;
1140
- event_stream == null ? void 0 : event_stream.close();
1141
- }
1142
- async function component_server(component_id, fn_name, data) {
1143
- var _a;
1144
- const headers = {};
1145
- let root_url;
1146
- let component = config.components.find(
1147
- (comp) => comp.id === component_id
1148
- );
1149
- if ((_a = component == null ? void 0 : component.props) == null ? void 0 : _a.root_url) {
1150
- root_url = component.props.root_url;
1151
- } else {
1152
- root_url = config.root;
1153
- }
1154
- let body;
1155
- if (data.binary) {
1156
- body = new FormData();
1157
- for (const key in data.data) {
1158
- if (key === "binary")
1159
- continue;
1160
- body.append(key, data.data[key]);
1161
- }
1162
- body.set("component_id", component_id);
1163
- body.set("fn_name", fn_name);
1164
- body.set("session_hash", session_hash);
1165
- } else {
1166
- body = JSON.stringify({
1167
- data,
1168
- component_id,
1169
- fn_name,
1170
- session_hash
1171
- });
1172
- headers["Content-Type"] = "application/json";
1173
- }
1174
- if (hf_token) {
1175
- headers.Authorization = `Bearer ${hf_token}`;
1176
- }
1177
- try {
1178
- const response = await fetch_implementation(
1179
- `${root_url}/component_server/`,
1180
- {
1181
- method: "POST",
1182
- body,
1183
- headers
1184
- }
1185
- );
1186
- if (!response.ok) {
1187
- throw new Error(
1188
- "Could not connect to component server: " + response.statusText
1189
- );
1190
- }
1191
- const output = await response.json();
1192
- return output;
1193
- } catch (e) {
1194
- console.warn(e);
1195
- }
1196
- }
1197
- async function view_api(config2) {
1198
- if (api)
1199
- return api;
1200
- const headers = { "Content-Type": "application/json" };
1201
- if (hf_token) {
1202
- headers.Authorization = `Bearer ${hf_token}`;
1203
- }
1204
- let response;
1205
- if (semiver(config2.version || "2.0.0", "3.30") < 0) {
1206
- response = await fetch_implementation(
1207
- "https://gradio-space-api-fetcher-v2.hf.space/api",
1208
- {
1209
- method: "POST",
1210
- body: JSON.stringify({
1211
- serialize: false,
1212
- config: JSON.stringify(config2)
1213
- }),
1214
- headers
1215
- }
1216
- );
1217
- } else {
1218
- response = await fetch_implementation(`${config2.root}/info`, {
1219
- headers
1220
- });
1221
- }
1222
- if (!response.ok) {
1223
- throw new Error(BROKEN_CONNECTION_MSG);
1224
- }
1225
- let api_info = await response.json();
1226
- if ("api" in api_info) {
1227
- api_info = api_info.api;
1228
- }
1229
- if (api_info.named_endpoints["/predict"] && !api_info.unnamed_endpoints["0"]) {
1230
- api_info.unnamed_endpoints[0] = api_info.named_endpoints["/predict"];
1231
- }
1232
- const x = transform_api_info(api_info, config2, api_map);
1233
- return x;
1234
- }
1235
- });
1236
- }
1237
- async function handle_blob2(endpoint, data, api_info, token) {
1238
- const blob_refs = await walk_and_store_blobs(
1239
- data,
1240
- void 0,
1241
- [],
1242
- true,
1243
- api_info
1244
- );
1245
- return Promise.all(
1246
- blob_refs.map(async ({ path, blob, type }) => {
1247
- if (blob) {
1248
- const file_url = (await upload_files2(endpoint, [blob], token)).files[0];
1249
- return { path, file_url, type, name: blob == null ? void 0 : blob.name };
1250
- }
1251
- return { path, type };
1252
- })
1253
- ).then((r) => {
1254
- r.forEach(({ path, file_url, type, name }) => {
1255
- if (type === "Gallery") {
1256
- update_object(data, file_url, path);
1257
- } else if (file_url) {
1258
- const file = new FileData({ path: file_url, orig_name: name });
1259
- update_object(data, file, path);
1260
1641
  }
1261
1642
  });
1262
- return data;
1263
- });
1264
- }
1265
- }
1266
- const { post_data, upload_files, client, handle_blob } = api_factory(
1267
- fetch,
1268
- (...args) => new EventSource(...args)
1269
- );
1270
- function get_type(type, component, serializer, signature_type) {
1271
- switch (type.type) {
1272
- case "string":
1273
- return "string";
1274
- case "boolean":
1275
- return "boolean";
1276
- case "number":
1277
- return "number";
1278
- }
1279
- if (serializer === "JSONSerializable" || serializer === "StringSerializable") {
1280
- return "any";
1281
- } else if (serializer === "ListStringSerializable") {
1282
- return "string[]";
1283
- } else if (component === "Image") {
1284
- return signature_type === "parameter" ? "Blob | File | Buffer" : "string";
1285
- } else if (serializer === "FileSerializable") {
1286
- if ((type == null ? void 0 : type.type) === "array") {
1287
- return signature_type === "parameter" ? "(Blob | File | Buffer)[]" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}[]`;
1643
+ } catch (e) {
1644
+ throw Error(`Could not resolve config: ${e}`);
1288
1645
  }
1289
- return signature_type === "parameter" ? "Blob | File | Buffer" : `{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}`;
1290
- } else if (serializer === "GallerySerializable") {
1291
- return signature_type === "parameter" ? "[(Blob | File | Buffer), (string | null)][]" : `[{ name: string; data: string; size?: number; is_file?: boolean; orig_name?: string}, (string | null))][]`;
1646
+ this.api_info = await this.view_api();
1647
+ this.api_map = map_names_to_ids(((_a = this.config) == null ? void 0 : _a.dependencies) || []);
1292
1648
  }
1293
- }
1294
- function get_description(type, serializer) {
1295
- if (serializer === "GallerySerializable") {
1296
- return "array of [file, label] tuples";
1297
- } else if (serializer === "ListStringSerializable") {
1298
- return "array of strings";
1299
- } else if (serializer === "FileSerializable") {
1300
- return "array of files or single file";
1649
+ static async connect(app_reference, options = {}) {
1650
+ const client2 = new this(app_reference, options);
1651
+ await client2.init();
1652
+ return client2;
1301
1653
  }
1302
- return type.description;
1303
- }
1304
- function transform_api_info(api_info, config, api_map) {
1305
- const new_data = {
1306
- named_endpoints: {},
1307
- unnamed_endpoints: {}
1308
- };
1309
- for (const key in api_info) {
1310
- const cat = api_info[key];
1311
- for (const endpoint in cat) {
1312
- const dep_index = config.dependencies[endpoint] ? endpoint : api_map[endpoint.replace("/", "")];
1313
- const info = cat[endpoint];
1314
- new_data[key][endpoint] = {};
1315
- new_data[key][endpoint].parameters = {};
1316
- new_data[key][endpoint].returns = {};
1317
- new_data[key][endpoint].type = config.dependencies[dep_index].types;
1318
- new_data[key][endpoint].parameters = info.parameters.map(
1319
- ({ label, component, type, serializer }) => ({
1320
- label,
1321
- component,
1322
- type: get_type(type, component, serializer, "parameter"),
1323
- description: get_description(type, serializer)
1324
- })
1325
- );
1326
- new_data[key][endpoint].returns = info.returns.map(
1327
- ({ label, component, type, serializer }) => ({
1328
- label,
1329
- component,
1330
- type: get_type(type, component, serializer, "return"),
1331
- description: get_description(type, serializer)
1332
- })
1333
- );
1334
- }
1654
+ close() {
1655
+ var _a;
1656
+ (_a = this.heartbeat_event) == null ? void 0 : _a.close();
1335
1657
  }
1336
- return new_data;
1337
- }
1338
- async function get_jwt(space, token) {
1339
- try {
1340
- const r = await fetch(`https://huggingface.co/api/spaces/${space}/jwt`, {
1341
- headers: {
1342
- Authorization: `Bearer ${token}`
1343
- }
1344
- });
1345
- const jwt = (await r.json()).token;
1346
- return jwt || false;
1347
- } catch (e) {
1348
- console.error(e);
1349
- return false;
1658
+ static async duplicate(app_reference, options = {}) {
1659
+ return duplicate(app_reference, options);
1350
1660
  }
1351
- }
1352
- function update_object(object, newValue, stack) {
1353
- while (stack.length > 1) {
1354
- object = object[stack.shift()];
1355
- }
1356
- object[stack.shift()] = newValue;
1357
- }
1358
- async function walk_and_store_blobs(param, type = void 0, path = [], root = false, api_info = void 0) {
1359
- if (Array.isArray(param)) {
1360
- let blob_refs = [];
1361
- await Promise.all(
1362
- param.map(async (v, i) => {
1363
- var _a;
1364
- let new_path = path.slice();
1365
- new_path.push(i);
1366
- const array_refs = await walk_and_store_blobs(
1367
- param[i],
1368
- root ? ((_a = api_info == null ? void 0 : api_info.parameters[i]) == null ? void 0 : _a.component) || void 0 : type,
1369
- new_path,
1370
- false,
1371
- api_info
1372
- );
1373
- blob_refs = blob_refs.concat(array_refs);
1374
- })
1661
+ async _resolve_config() {
1662
+ const { http_protocol, host, space_id } = await process_endpoint(
1663
+ this.app_reference,
1664
+ this.options.hf_token
1375
1665
  );
1376
- return blob_refs;
1377
- } else if (globalThis.Buffer && param instanceof globalThis.Buffer) {
1378
- const is_image = type === "Image";
1379
- return [
1380
- {
1381
- path,
1382
- blob: is_image ? false : new NodeBlob([param]),
1383
- type
1666
+ const { status_callback } = this.options;
1667
+ let config;
1668
+ try {
1669
+ config = await this.resolve_config(`${http_protocol}//${host}`);
1670
+ if (!config) {
1671
+ throw new Error("Could not resolve app config");
1384
1672
  }
1385
- ];
1386
- } else if (typeof param === "object") {
1387
- let blob_refs = [];
1388
- for (let key in param) {
1389
- if (param.hasOwnProperty(key)) {
1390
- let new_path = path.slice();
1391
- new_path.push(key);
1392
- blob_refs = blob_refs.concat(
1393
- await walk_and_store_blobs(
1394
- param[key],
1395
- void 0,
1396
- new_path,
1397
- false,
1398
- api_info
1399
- )
1673
+ return this.config_success(config);
1674
+ } catch (e) {
1675
+ console.error(e);
1676
+ if (space_id) {
1677
+ check_space_status(
1678
+ space_id,
1679
+ RE_SPACE_NAME.test(space_id) ? "space_name" : "subdomain",
1680
+ this.handle_space_success
1400
1681
  );
1682
+ } else {
1683
+ if (status_callback)
1684
+ status_callback({
1685
+ status: "error",
1686
+ message: "Could not load this space.",
1687
+ load_status: "error",
1688
+ detail: "NOT_FOUND"
1689
+ });
1401
1690
  }
1402
1691
  }
1403
- return blob_refs;
1404
1692
  }
1405
- return [];
1406
- }
1407
- function skip_queue(id, config) {
1408
- var _a, _b, _c, _d;
1409
- 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;
1410
- }
1411
- async function resolve_config(fetch_implementation, endpoint, token) {
1412
- const headers = {};
1413
- if (token) {
1414
- headers.Authorization = `Bearer ${token}`;
1415
- }
1416
- if (typeof window !== "undefined" && window.gradio_config && location.origin !== "http://localhost:9876" && !window.gradio_config.dev_mode) {
1417
- const path = window.gradio_config.root;
1418
- const config = window.gradio_config;
1419
- config.root = resolve_root(endpoint, config.root, false);
1420
- return { ...config, path };
1421
- } else if (endpoint) {
1422
- let response = await fetch_implementation(`${endpoint}/config`, {
1423
- headers
1424
- });
1425
- if (response.status === 200) {
1426
- const config = await response.json();
1427
- config.path = config.path ?? "";
1428
- config.root = endpoint;
1429
- return config;
1693
+ async config_success(_config) {
1694
+ this.config = _config;
1695
+ if (typeof window !== "undefined") {
1696
+ if (window.location.protocol === "https:") {
1697
+ this.config.root = this.config.root.replace("http://", "https://");
1698
+ }
1430
1699
  }
1431
- throw new Error("Could not get config.");
1432
- }
1433
- throw new Error("No config or app endpoint found");
1434
- }
1435
- async function check_space_status(id, type, status_callback) {
1436
- let endpoint = type === "subdomain" ? `https://huggingface.co/api/spaces/by-subdomain/${id}` : `https://huggingface.co/api/spaces/${id}`;
1437
- let response;
1438
- let _status;
1439
- try {
1440
- response = await fetch(endpoint);
1441
- _status = response.status;
1442
- if (_status !== 200) {
1443
- throw new Error();
1700
+ if (this.config.auth_required) {
1701
+ return this.prepare_return_obj();
1444
1702
  }
1445
- response = await response.json();
1446
- } catch (e) {
1447
- status_callback({
1448
- status: "error",
1449
- load_status: "error",
1450
- message: "Could not get space status",
1451
- detail: "NOT_FOUND"
1452
- });
1453
- return;
1454
- }
1455
- if (!response || _status !== 200)
1456
- return;
1457
- const {
1458
- runtime: { stage },
1459
- id: space_name
1460
- } = response;
1461
- switch (stage) {
1462
- case "STOPPED":
1463
- case "SLEEPING":
1464
- status_callback({
1465
- status: "sleeping",
1466
- load_status: "pending",
1467
- message: "Space is asleep. Waking it up...",
1468
- detail: stage
1469
- });
1470
- setTimeout(() => {
1471
- check_space_status(id, type, status_callback);
1472
- }, 1e3);
1473
- break;
1474
- case "PAUSED":
1475
- status_callback({
1476
- status: "paused",
1477
- load_status: "error",
1478
- message: "This space has been paused by the author. If you would like to try this demo, consider duplicating the space.",
1479
- detail: stage,
1480
- discussions_enabled: await discussions_enabled(space_name)
1481
- });
1482
- break;
1483
- case "RUNNING":
1484
- case "RUNNING_BUILDING":
1485
- status_callback({
1486
- status: "running",
1487
- load_status: "complete",
1488
- message: "",
1489
- detail: stage
1490
- });
1491
- break;
1492
- case "BUILDING":
1493
- status_callback({
1494
- status: "building",
1495
- load_status: "pending",
1496
- message: "Space is building...",
1497
- detail: stage
1498
- });
1499
- setTimeout(() => {
1500
- check_space_status(id, type, status_callback);
1501
- }, 1e3);
1502
- break;
1503
- default:
1504
- status_callback({
1505
- status: "space_error",
1506
- load_status: "error",
1507
- message: "This space is experiencing an issue.",
1508
- detail: stage,
1509
- discussions_enabled: await discussions_enabled(space_name)
1510
- });
1511
- break;
1703
+ try {
1704
+ this.api_info = await this.view_api();
1705
+ } catch (e) {
1706
+ console.error(`Could not get API details: ${e.message}`);
1707
+ }
1708
+ return this.prepare_return_obj();
1512
1709
  }
1513
- }
1514
- function handle_message(data, last_status) {
1515
- const queue = true;
1516
- switch (data.msg) {
1517
- case "send_data":
1518
- return { type: "data" };
1519
- case "send_hash":
1520
- return { type: "hash" };
1521
- case "queue_full":
1522
- return {
1523
- type: "update",
1524
- status: {
1525
- queue,
1526
- message: QUEUE_FULL_MSG,
1527
- stage: "error",
1528
- code: data.code,
1529
- success: data.success
1530
- }
1531
- };
1532
- case "heartbeat":
1533
- return {
1534
- type: "heartbeat"
1535
- };
1536
- case "unexpected_error":
1537
- return {
1538
- type: "unexpected_error",
1539
- status: {
1540
- queue,
1541
- message: data.message,
1542
- stage: "error",
1543
- success: false
1544
- }
1545
- };
1546
- case "estimation":
1547
- return {
1548
- type: "update",
1549
- status: {
1550
- queue,
1551
- stage: last_status || "pending",
1552
- code: data.code,
1553
- size: data.queue_size,
1554
- position: data.rank,
1555
- eta: data.rank_eta,
1556
- success: data.success
1710
+ async handle_space_success(status) {
1711
+ const { status_callback } = this.options;
1712
+ if (status_callback)
1713
+ status_callback(status);
1714
+ if (status.status === "running") {
1715
+ try {
1716
+ this.config = await this._resolve_config();
1717
+ if (!this.config) {
1718
+ throw new Error("Could not resolve app config");
1557
1719
  }
1558
- };
1559
- case "progress":
1560
- return {
1561
- type: "update",
1562
- status: {
1563
- queue,
1564
- stage: "pending",
1565
- code: data.code,
1566
- progress_data: data.progress_data,
1567
- success: data.success
1720
+ const _config = await this.config_success(this.config);
1721
+ return _config;
1722
+ } catch (e) {
1723
+ console.error(e);
1724
+ if (status_callback) {
1725
+ status_callback({
1726
+ status: "error",
1727
+ message: "Could not load this space.",
1728
+ load_status: "error",
1729
+ detail: "NOT_FOUND"
1730
+ });
1568
1731
  }
1569
- };
1570
- case "log":
1571
- return { type: "log", data };
1572
- case "process_generating":
1573
- return {
1574
- type: "generating",
1575
- status: {
1576
- queue,
1577
- message: !data.success ? data.output.error : null,
1578
- stage: data.success ? "generating" : "error",
1579
- code: data.code,
1580
- progress_data: data.progress_data,
1581
- eta: data.average_duration
1582
- },
1583
- data: data.success ? data.output : null
1584
- };
1585
- case "process_completed":
1586
- if ("error" in data.output) {
1587
- return {
1588
- type: "update",
1589
- status: {
1590
- queue,
1591
- message: data.output.error,
1592
- stage: "error",
1593
- code: data.code,
1594
- success: data.success
1595
- }
1596
- };
1597
1732
  }
1598
- return {
1599
- type: "complete",
1600
- status: {
1601
- queue,
1602
- message: !data.success ? data.output.error : void 0,
1603
- stage: data.success ? "complete" : "error",
1604
- code: data.code,
1605
- progress_data: data.progress_data
1606
- },
1607
- data: data.success ? data.output : null
1608
- };
1609
- case "process_starts":
1610
- return {
1611
- type: "update",
1612
- status: {
1613
- queue,
1614
- stage: "pending",
1615
- code: data.code,
1616
- size: data.rank,
1617
- position: 0,
1618
- success: data.success,
1619
- eta: data.eta
1733
+ }
1734
+ }
1735
+ async component_server(component_id, fn_name, data) {
1736
+ var _a;
1737
+ if (!this.config) {
1738
+ throw new Error("Could not resolve app config");
1739
+ }
1740
+ const headers = {};
1741
+ const { hf_token } = this.options;
1742
+ const { session_hash } = this;
1743
+ if (hf_token) {
1744
+ headers.Authorization = `Bearer ${this.options.hf_token}`;
1745
+ }
1746
+ let root_url;
1747
+ let component = this.config.components.find(
1748
+ (comp) => comp.id === component_id
1749
+ );
1750
+ if ((_a = component == null ? void 0 : component.props) == null ? void 0 : _a.root_url) {
1751
+ root_url = component.props.root_url;
1752
+ } else {
1753
+ root_url = this.config.root;
1754
+ }
1755
+ let body;
1756
+ if ("binary" in data) {
1757
+ body = new FormData();
1758
+ for (const key in data.data) {
1759
+ if (key === "binary")
1760
+ continue;
1761
+ body.append(key, data.data[key]);
1762
+ }
1763
+ body.set("component_id", component_id.toString());
1764
+ body.set("fn_name", fn_name);
1765
+ body.set("session_hash", session_hash);
1766
+ } else {
1767
+ body = JSON.stringify({
1768
+ data,
1769
+ component_id,
1770
+ fn_name,
1771
+ session_hash
1772
+ });
1773
+ headers["Content-Type"] = "application/json";
1774
+ }
1775
+ if (hf_token) {
1776
+ headers.Authorization = `Bearer ${hf_token}`;
1777
+ }
1778
+ try {
1779
+ const response = await this.fetch_implementation(
1780
+ `${root_url}/component_server/`,
1781
+ {
1782
+ method: "POST",
1783
+ body,
1784
+ headers
1620
1785
  }
1621
- };
1786
+ );
1787
+ if (!response.ok) {
1788
+ throw new Error(
1789
+ "Could not connect to component server: " + response.statusText
1790
+ );
1791
+ }
1792
+ const output = await response.json();
1793
+ return output;
1794
+ } catch (e) {
1795
+ console.warn(e);
1796
+ }
1622
1797
  }
1623
- return { type: "none", status: { stage: "error", queue } };
1798
+ prepare_return_obj() {
1799
+ return {
1800
+ config: this.config,
1801
+ predict: this.predict,
1802
+ submit: this.submit,
1803
+ view_api: this.view_api,
1804
+ component_server: this.component_server
1805
+ };
1806
+ }
1807
+ }
1808
+ async function client(app_reference, options = {}) {
1809
+ return await Client.connect(app_reference, options);
1624
1810
  }
1625
1811
  export {
1812
+ Client,
1626
1813
  FileData,
1627
- api_factory,
1628
1814
  client,
1629
1815
  duplicate,
1630
- post_data,
1816
+ predict,
1631
1817
  prepare_files,
1818
+ submit,
1632
1819
  upload,
1633
1820
  upload_files
1634
1821
  };