@gradio/client 0.17.0 → 0.19.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 (69) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +10 -6
  3. package/dist/client.d.ts +18 -7
  4. package/dist/client.d.ts.map +1 -1
  5. package/dist/constants.d.ts +8 -2
  6. package/dist/constants.d.ts.map +1 -1
  7. package/dist/helpers/api_info.d.ts +22 -0
  8. package/dist/helpers/api_info.d.ts.map +1 -1
  9. package/dist/helpers/data.d.ts +2 -2
  10. package/dist/helpers/data.d.ts.map +1 -1
  11. package/dist/helpers/init_helpers.d.ts.map +1 -1
  12. package/dist/helpers/spaces.d.ts.map +1 -1
  13. package/dist/index.d.ts +1 -1
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +275 -183
  16. package/dist/test/handlers.d.ts +3 -0
  17. package/dist/test/handlers.d.ts.map +1 -0
  18. package/dist/test/mock_eventsource.d.ts +2 -0
  19. package/dist/test/mock_eventsource.d.ts.map +1 -0
  20. package/dist/test/server.d.ts +2 -0
  21. package/dist/test/server.d.ts.map +1 -0
  22. package/dist/test/test_data.d.ts +76 -0
  23. package/dist/test/test_data.d.ts.map +1 -0
  24. package/dist/types.d.ts +23 -7
  25. package/dist/types.d.ts.map +1 -1
  26. package/dist/upload.d.ts +2 -2
  27. package/dist/upload.d.ts.map +1 -1
  28. package/dist/utils/duplicate.d.ts.map +1 -1
  29. package/dist/utils/predict.d.ts +1 -1
  30. package/dist/utils/predict.d.ts.map +1 -1
  31. package/dist/utils/stream.d.ts +2 -2
  32. package/dist/utils/stream.d.ts.map +1 -1
  33. package/dist/utils/submit.d.ts +1 -1
  34. package/dist/utils/submit.d.ts.map +1 -1
  35. package/dist/utils/upload_files.d.ts.map +1 -1
  36. package/dist/utils/view_api.d.ts.map +1 -1
  37. package/package.json +8 -2
  38. package/src/client.ts +53 -28
  39. package/src/constants.ts +9 -2
  40. package/src/helpers/api_info.ts +75 -4
  41. package/src/helpers/data.ts +46 -28
  42. package/src/helpers/init_helpers.ts +7 -11
  43. package/src/helpers/spaces.ts +8 -3
  44. package/src/index.ts +1 -1
  45. package/src/test/api_info.test.ts +567 -0
  46. package/src/test/data.test.ts +281 -0
  47. package/src/test/handlers.ts +438 -0
  48. package/src/test/init.test.ts +139 -0
  49. package/src/test/init_helpers.test.ts +94 -0
  50. package/src/test/mock_eventsource.ts +13 -0
  51. package/src/test/post_data.test.ts +45 -0
  52. package/src/test/server.ts +6 -0
  53. package/src/test/spaces.test.ts +145 -0
  54. package/src/test/stream.test.ts +79 -0
  55. package/src/test/test_data.ts +557 -0
  56. package/src/test/upload_files.test.ts +42 -0
  57. package/src/test/view_api.test.ts +53 -0
  58. package/src/types.ts +36 -17
  59. package/src/upload.ts +4 -8
  60. package/src/utils/duplicate.ts +20 -3
  61. package/src/utils/handle_blob.ts +1 -1
  62. package/src/utils/post_data.ts +1 -1
  63. package/src/utils/predict.ts +2 -2
  64. package/src/utils/stream.ts +30 -21
  65. package/src/utils/submit.ts +42 -19
  66. package/src/utils/upload_files.ts +11 -6
  67. package/src/utils/view_api.ts +4 -7
  68. package/vite.config.js +7 -0
  69. package/src/utils/client.node-test.ts +0 -173
package/src/types.ts CHANGED
@@ -4,6 +4,9 @@ import { hardware_types } from "./helpers/spaces";
4
4
 
5
5
  export interface ApiData {
6
6
  label: string;
7
+ parameter_name: string;
8
+ parameter_default?: any;
9
+ parameter_has_default?: boolean;
7
10
  type: {
8
11
  type: any;
9
12
  description: string;
@@ -16,6 +19,9 @@ export interface ApiData {
16
19
 
17
20
  export interface JsApiData {
18
21
  label: string;
22
+ parameter_name: string;
23
+ parameter_default?: any;
24
+ parameter_has_default?: boolean;
19
25
  type: string;
20
26
  description: string;
21
27
  component: string;
@@ -38,10 +44,25 @@ export interface ApiInfo<T extends ApiData | JsApiData> {
38
44
  export interface BlobRef {
39
45
  path: string[];
40
46
  type: string | undefined;
41
- blob: Blob | false;
47
+ blob: Blob | File | false;
42
48
  }
43
49
 
44
- export type ParamType = string | Buffer | Record<string, any> | any[];
50
+ export type DataType = string | Buffer | Record<string, any> | any[];
51
+
52
+ // Function Signature Types
53
+
54
+ export type SubmitFunction = (
55
+ endpoint: string | number,
56
+ data: unknown[] | Record<string, unknown>,
57
+ event_data?: unknown,
58
+ trigger_id?: number | null
59
+ ) => SubmitReturn;
60
+
61
+ export type PredictFunction = (
62
+ endpoint: string | number,
63
+ data: unknown[] | Record<string, unknown>,
64
+ event_data?: unknown
65
+ ) => Promise<SubmitReturn>;
45
66
 
46
67
  // Event and Submission Types
47
68
 
@@ -50,27 +71,16 @@ type event = <K extends EventType>(
50
71
  listener: EventListener<K>
51
72
  ) => SubmitReturn;
52
73
 
53
- type predict = (
54
- endpoint: string | number,
55
- data?: unknown[],
56
- event_data?: unknown
57
- ) => Promise<unknown>;
58
-
59
74
  export type client_return = {
60
75
  config: Config | undefined;
61
- predict: predict;
62
- submit: (
63
- endpoint: string | number,
64
- data: unknown[],
65
- event_data?: unknown,
66
- trigger_id?: number | null
67
- ) => SubmitReturn;
76
+ predict: PredictFunction;
77
+ submit: SubmitFunction;
68
78
  component_server: (
69
79
  component_id: number,
70
80
  fn_name: string,
71
81
  data: unknown[]
72
82
  ) => any;
73
- view_api: (fetch_implementation: typeof fetch) => Promise<ApiInfo<JsApiData>>;
83
+ view_api: (_fetch: typeof fetch) => Promise<ApiInfo<JsApiData>>;
74
84
  };
75
85
 
76
86
  export type SubmitReturn = {
@@ -116,6 +126,7 @@ export type SpaceStatusCallback = (a: SpaceStatus) => void;
116
126
  export interface Config {
117
127
  auth_required: boolean;
118
128
  analytics_enabled: boolean;
129
+ connect_heartbeat: boolean;
119
130
  auth_message: string;
120
131
  components: any[];
121
132
  css: string | null;
@@ -219,12 +230,13 @@ export interface FileData {
219
230
 
220
231
  // Event and Listener Types
221
232
 
222
- export type EventType = "data" | "status" | "log";
233
+ export type EventType = "data" | "status" | "log" | "render";
223
234
 
224
235
  export interface EventMap {
225
236
  data: Payload;
226
237
  status: Status;
227
238
  log: LogMessage;
239
+ render: RenderMessage;
228
240
  }
229
241
 
230
242
  export type Event<K extends EventType> = {
@@ -238,6 +250,13 @@ export interface LogMessage {
238
250
  log: string;
239
251
  level: "warning" | "info";
240
252
  }
253
+ export interface RenderMessage {
254
+ fn_index: number;
255
+ data: {
256
+ components: any[];
257
+ layout: any;
258
+ };
259
+ }
241
260
 
242
261
  export interface Status {
243
262
  queue: boolean;
package/src/upload.ts CHANGED
@@ -1,16 +1,12 @@
1
1
  import type { UploadResponse } from "./types";
2
- import { upload_files } from ".";
2
+ import type { Client } from "./client";
3
3
 
4
4
  export async function upload(
5
+ this: Client,
5
6
  file_data: FileData[],
6
7
  root_url: string,
7
8
  upload_id?: string,
8
- max_file_size?: number,
9
- upload_fn: (
10
- root_url: string,
11
- files: (Blob | File)[],
12
- upload_id?: string
13
- ) => Promise<UploadResponse> = upload_files
9
+ max_file_size?: number
14
10
  ): Promise<(FileData | null)[] | null> {
15
11
  let files = (Array.isArray(file_data) ? file_data : [file_data]).map(
16
12
  (file_data) => file_data.blob!
@@ -28,7 +24,7 @@ export async function upload(
28
24
  }
29
25
 
30
26
  return await Promise.all(
31
- await upload_fn(root_url, files, upload_id).then(
27
+ await this.upload_files(root_url, files, upload_id).then(
32
28
  async (response: { files?: string[]; error?: string }) => {
33
29
  if (response.error) {
34
30
  throw new Error(response.error);
@@ -5,6 +5,7 @@ import {
5
5
  } from "../helpers/spaces";
6
6
  import type { DuplicateOptions } from "../types";
7
7
  import { Client } from "../client";
8
+ import { SPACE_METADATA_ERROR_MSG } from "../constants";
8
9
 
9
10
  export async function duplicate(
10
11
  app_reference: string,
@@ -47,8 +48,12 @@ export async function duplicate(
47
48
 
48
49
  let original_hardware;
49
50
 
50
- if (!hardware) {
51
- original_hardware = await get_space_hardware(app_reference, hf_token);
51
+ try {
52
+ if (!hardware) {
53
+ original_hardware = await get_space_hardware(app_reference, hf_token);
54
+ }
55
+ } catch (e) {
56
+ throw Error(SPACE_METADATA_ERROR_MSG + (e as Error).message);
52
57
  }
53
58
 
54
59
  const requested_hardware = hardware || original_hardware || "cpu-basic";
@@ -80,8 +85,20 @@ export async function duplicate(
80
85
  const duplicated_space = await response.json();
81
86
 
82
87
  await set_space_timeout(`${user}/${space_name}`, timeout || 300, hf_token);
83
- return await Client.connect(duplicated_space.url, options);
88
+
89
+ return await Client.connect(
90
+ get_space_reference(duplicated_space.url),
91
+ options
92
+ );
84
93
  } catch (e: any) {
85
94
  throw new Error(e);
86
95
  }
87
96
  }
97
+
98
+ function get_space_reference(url: string): any {
99
+ const regex = /https:\/\/huggingface.co\/spaces\/([^/]+\/[^/]+)/;
100
+ const match = url.match(regex);
101
+ if (match) {
102
+ return match[1];
103
+ }
104
+ }
@@ -29,7 +29,7 @@ export async function handle_blob(
29
29
  path,
30
30
  file_url,
31
31
  type,
32
- name: blob?.name
32
+ name: blob instanceof File ? blob?.name : undefined
33
33
  };
34
34
  })
35
35
  );
@@ -16,7 +16,7 @@ export async function post_data(
16
16
  headers.Authorization = `Bearer ${this.options.hf_token}`;
17
17
  }
18
18
  try {
19
- var response = await this.fetch_implementation(url, {
19
+ var response = await this.fetch(url, {
20
20
  method: "POST",
21
21
  body: JSON.stringify(body),
22
22
  headers: { ...headers, ...additional_headers }
@@ -4,7 +4,7 @@ import type { Dependency, SubmitReturn } from "../types";
4
4
  export async function predict(
5
5
  this: Client,
6
6
  endpoint: string | number,
7
- data?: unknown[]
7
+ data: unknown[] | Record<string, unknown>
8
8
  ): Promise<SubmitReturn> {
9
9
  let data_returned = false;
10
10
  let status_complete = false;
@@ -28,7 +28,7 @@ export async function predict(
28
28
  }
29
29
 
30
30
  return new Promise(async (resolve, reject) => {
31
- const app = this.submit(endpoint, data || []);
31
+ const app = this.submit(endpoint, data);
32
32
  let result: unknown;
33
33
 
34
34
  app
@@ -1,13 +1,14 @@
1
1
  import { BROKEN_CONNECTION_MSG } from "../constants";
2
2
  import type { Client } from "../client";
3
3
 
4
- export function open_stream(this: Client): void {
4
+ export async function open_stream(this: Client): Promise<void> {
5
5
  let {
6
6
  event_callbacks,
7
7
  unclosed_events,
8
8
  pending_stream_messages,
9
9
  stream_status,
10
- config
10
+ config,
11
+ jwt
11
12
  } = this;
12
13
 
13
14
  if (!config) {
@@ -16,31 +17,35 @@ export function open_stream(this: Client): void {
16
17
 
17
18
  stream_status.open = true;
18
19
 
19
- let event_source: EventSource | null = null;
20
+ let stream: EventSource | null = null;
20
21
  let params = new URLSearchParams({
21
22
  session_hash: this.session_hash
22
23
  }).toString();
23
24
 
24
25
  let url = new URL(`${config.root}/queue/data?${params}`);
25
- event_source = this.eventSource_factory(url);
26
26
 
27
- if (!event_source) {
28
- throw new Error("Cannot connect to sse endpoint: " + url.toString());
27
+ if (jwt) {
28
+ url.searchParams.set("__sign", jwt);
29
29
  }
30
30
 
31
- event_source.onmessage = async function (event) {
31
+ stream = await this.stream(url);
32
+
33
+ if (!stream) {
34
+ console.warn("Cannot connect to SSE endpoint: " + url.toString());
35
+ return;
36
+ }
37
+
38
+ stream.onmessage = async function (event: MessageEvent) {
32
39
  let _data = JSON.parse(event.data);
33
40
  if (_data.msg === "close_stream") {
34
- close_stream(stream_status, event_source);
41
+ close_stream(stream_status, stream);
35
42
  return;
36
43
  }
37
44
  const event_id = _data.event_id;
38
45
  if (!event_id) {
39
46
  await Promise.all(
40
- Object.keys(event_callbacks).map(
41
- (event_id) =>
42
- // @ts-ignore
43
- event_callbacks[event_id](_data) // todo: check event_callbacks
47
+ Object.keys(event_callbacks).map((event_id) =>
48
+ event_callbacks[event_id](_data)
44
49
  )
45
50
  );
46
51
  } else if (event_callbacks[event_id] && config) {
@@ -50,11 +55,16 @@ export function open_stream(this: Client): void {
50
55
  ) {
51
56
  unclosed_events.delete(event_id);
52
57
  if (unclosed_events.size === 0) {
53
- close_stream(stream_status, event_source);
58
+ close_stream(stream_status, stream);
54
59
  }
55
60
  }
56
- let fn = event_callbacks[event_id];
57
- window.setTimeout(fn, 0, _data); // need to do this to put the event on the end of the event loop, so the browser can refresh between callbacks and not freeze in case of quick generations. See https://github.com/gradio-app/gradio/pull/7055
61
+ let fn: (data: any) => void = event_callbacks[event_id];
62
+
63
+ if (typeof window !== "undefined") {
64
+ window.setTimeout(fn, 0, _data); // need to do this to put the event on the end of the event loop, so the browser can refresh between callbacks and not freeze in case of quick generations. See https://github.com/gradio-app/gradio/pull/7055
65
+ } else {
66
+ setImmediate(fn, _data);
67
+ }
58
68
  } else {
59
69
  if (!pending_stream_messages[event_id]) {
60
70
  pending_stream_messages[event_id] = [];
@@ -62,27 +72,26 @@ export function open_stream(this: Client): void {
62
72
  pending_stream_messages[event_id].push(_data);
63
73
  }
64
74
  };
65
- event_source.onerror = async function () {
75
+ stream.onerror = async function () {
66
76
  await Promise.all(
67
77
  Object.keys(event_callbacks).map((event_id) =>
68
- // @ts-ignore
69
78
  event_callbacks[event_id]({
70
79
  msg: "unexpected_error",
71
80
  message: BROKEN_CONNECTION_MSG
72
81
  })
73
82
  )
74
83
  );
75
- close_stream(stream_status, event_source);
84
+ close_stream(stream_status, stream);
76
85
  };
77
86
  }
78
87
 
79
88
  export function close_stream(
80
89
  stream_status: { open: boolean },
81
- event_source: EventSource | null
90
+ stream: EventSource | null
82
91
  ): void {
83
- if (stream_status && event_source) {
92
+ if (stream_status && stream) {
84
93
  stream_status.open = false;
85
- event_source?.close();
94
+ stream?.close();
86
95
  }
87
96
  }
88
97
 
@@ -16,7 +16,12 @@ import type {
16
16
 
17
17
  import { skip_queue, post_message } from "../helpers/data";
18
18
  import { resolve_root } from "../helpers/init_helpers";
19
- import { handle_message, process_endpoint } from "../helpers/api_info";
19
+ import {
20
+ handle_message,
21
+ map_data_to_params,
22
+ process_endpoint
23
+ } from "../helpers/api_info";
24
+ import semiver from "semiver";
20
25
  import { BROKEN_CONNECTION_MSG, QUEUE_FULL_MSG } from "../constants";
21
26
  import { apply_diff_stream, close_stream } from "./stream";
22
27
  import { Client } from "../client";
@@ -24,14 +29,14 @@ import { Client } from "../client";
24
29
  export function submit(
25
30
  this: Client,
26
31
  endpoint: string | number,
27
- data: unknown[],
32
+ data: unknown[] | Record<string, unknown>,
28
33
  event_data?: unknown,
29
34
  trigger_id?: number | null
30
35
  ): SubmitReturn {
31
36
  try {
32
37
  const { hf_token } = this.options;
33
38
  const {
34
- fetch_implementation,
39
+ fetch,
35
40
  app_reference,
36
41
  config,
37
42
  session_hash,
@@ -55,8 +60,10 @@ export function submit(
55
60
  config
56
61
  );
57
62
 
63
+ let resolved_data = map_data_to_params(data, api_info);
64
+
58
65
  let websocket: WebSocket;
59
- let event_source: EventSource | null;
66
+ let stream: EventSource | null;
60
67
  let protocol = config.protocol ?? "ws";
61
68
 
62
69
  const _endpoint = typeof endpoint === "number" ? "/predict" : endpoint;
@@ -125,7 +132,7 @@ export function submit(
125
132
  }
126
133
  cancel_request = { fn_index, session_hash };
127
134
  } else {
128
- event_source?.close();
135
+ stream?.close();
129
136
  cancel_request = { event_id };
130
137
  }
131
138
 
@@ -134,7 +141,7 @@ export function submit(
134
141
  throw new Error("Could not resolve app config");
135
142
  }
136
143
 
137
- await fetch_implementation(`${config.root}/reset`, {
144
+ await fetch(`${config.root}/reset`, {
138
145
  headers: { "Content-Type": "application/json" },
139
146
  method: "POST",
140
147
  body: JSON.stringify(cancel_request)
@@ -155,7 +162,7 @@ export function submit(
155
162
  }
156
163
  }
157
164
 
158
- this.handle_blob(`${config.root}`, data, endpoint_info).then(
165
+ this.handle_blob(config.root, resolved_data, endpoint_info).then(
159
166
  async (_payload) => {
160
167
  payload = {
161
168
  data: _payload || [],
@@ -368,15 +375,19 @@ export function submit(
368
375
  }${params}`
369
376
  );
370
377
 
371
- event_source = this.eventSource_factory(url);
378
+ if (this.jwt) {
379
+ url.searchParams.set("__sign", this.jwt);
380
+ }
381
+
382
+ stream = await this.stream(url);
372
383
 
373
- if (!event_source) {
374
- throw new Error(
375
- "Cannot connect to sse endpoint: " + url.toString()
384
+ if (!stream) {
385
+ return Promise.reject(
386
+ new Error("Cannot connect to SSE endpoint: " + url.toString())
376
387
  );
377
388
  }
378
389
 
379
- event_source.onmessage = async function (event) {
390
+ stream.onmessage = async function (event: MessageEvent) {
380
391
  const _data = JSON.parse(event.data);
381
392
  const { type, status, data } = handle_message(
382
393
  _data,
@@ -393,7 +404,7 @@ export function submit(
393
404
  ...status
394
405
  });
395
406
  if (status.stage === "error") {
396
- event_source?.close();
407
+ stream?.close();
397
408
  }
398
409
  } else if (type === "data") {
399
410
  event_id = _data.event_id as string;
@@ -412,7 +423,7 @@ export function submit(
412
423
  fn_index,
413
424
  time: new Date()
414
425
  });
415
- event_source?.close();
426
+ stream?.close();
416
427
  }
417
428
  } else if (type === "complete") {
418
429
  complete = status;
@@ -456,7 +467,7 @@ export function submit(
456
467
  endpoint: _endpoint,
457
468
  fn_index
458
469
  });
459
- event_source?.close();
470
+ stream?.close();
460
471
  }
461
472
  }
462
473
  };
@@ -476,7 +487,11 @@ export function submit(
476
487
  fn_index,
477
488
  time: new Date()
478
489
  });
479
- let hostname = window.location.hostname;
490
+ let hostname = "";
491
+ if (typeof window !== "undefined") {
492
+ hostname = window?.location?.hostname;
493
+ }
494
+
480
495
  let hfhubdev = "dev.spaces.huggingface.tech";
481
496
  const origin = hostname.includes(".dev.")
482
497
  ? `https://moon-${hostname.split(".")[1]}.${hfhubdev}`
@@ -495,7 +510,7 @@ export function submit(
495
510
  headers
496
511
  );
497
512
  });
498
- post_data_promise.then(([response, status]: any) => {
513
+ post_data_promise.then(async ([response, status]: any) => {
499
514
  if (status === 503) {
500
515
  fire_event({
501
516
  type: "status",
@@ -586,6 +601,14 @@ export function submit(
586
601
  endpoint: _endpoint,
587
602
  fn_index
588
603
  });
604
+ if (data.render_config) {
605
+ fire_event({
606
+ type: "render",
607
+ data: data.render_config,
608
+ endpoint: _endpoint,
609
+ fn_index
610
+ });
611
+ }
589
612
 
590
613
  if (complete) {
591
614
  fire_event({
@@ -623,7 +646,7 @@ export function submit(
623
646
  time: new Date()
624
647
  });
625
648
  if (["sse_v2", "sse_v2.1"].includes(protocol)) {
626
- close_stream(stream_status, event_source);
649
+ close_stream(stream_status, stream);
627
650
  stream_status.open = false;
628
651
  }
629
652
  }
@@ -639,7 +662,7 @@ export function submit(
639
662
  event_callbacks[event_id] = callback;
640
663
  unclosed_events.add(event_id);
641
664
  if (!stream_status.open) {
642
- this.open_stream();
665
+ await this.open_stream();
643
666
  }
644
667
  }
645
668
  });
@@ -1,5 +1,5 @@
1
1
  import type { Client } from "..";
2
- import { BROKEN_CONNECTION_MSG } from "../constants";
2
+ import { BROKEN_CONNECTION_MSG, UPLOAD_URL } from "../constants";
3
3
  import type { UploadResponse } from "../types";
4
4
 
5
5
  export async function upload_files(
@@ -11,11 +11,14 @@ export async function upload_files(
11
11
  const headers: {
12
12
  Authorization?: string;
13
13
  } = {};
14
- if (this.options.hf_token) {
14
+ if (this?.options?.hf_token) {
15
15
  headers.Authorization = `Bearer ${this.options.hf_token}`;
16
16
  }
17
+
17
18
  const chunkSize = 1000;
18
19
  const uploadResponses = [];
20
+ let response: Response;
21
+
19
22
  for (let i = 0; i < files.length; i += chunkSize) {
20
23
  const chunk = files.slice(i, i + chunkSize);
21
24
  const formData = new FormData();
@@ -25,17 +28,19 @@ export async function upload_files(
25
28
  try {
26
29
  const upload_url = upload_id
27
30
  ? `${root_url}/upload?upload_id=${upload_id}`
28
- : `${root_url}/upload`;
29
- var response = await this.fetch_implementation(upload_url, {
31
+ : `${root_url}/${UPLOAD_URL}`;
32
+
33
+ response = await this.fetch(upload_url, {
30
34
  method: "POST",
31
35
  body: formData,
32
36
  headers
33
37
  });
34
38
  } catch (e) {
35
- return { error: BROKEN_CONNECTION_MSG };
39
+ throw new Error(BROKEN_CONNECTION_MSG + (e as Error).message);
36
40
  }
37
41
  if (!response.ok) {
38
- return { error: await response.text() };
42
+ const error_text = await response.text();
43
+ return { error: `HTTP ${response.status}: ${error_text}` };
39
44
  }
40
45
  const output: UploadResponse["files"] = await response.json();
41
46
  if (output) {
@@ -28,7 +28,7 @@ export async function view_api(this: Client): Promise<any> {
28
28
  let response: Response;
29
29
 
30
30
  if (semiver(config?.version || "2.0.0", "3.30") < 0) {
31
- response = await this.fetch_implementation(SPACE_FETCHER_URL, {
31
+ response = await this.fetch(SPACE_FETCHER_URL, {
32
32
  method: "POST",
33
33
  body: JSON.stringify({
34
34
  serialize: false,
@@ -37,12 +37,9 @@ export async function view_api(this: Client): Promise<any> {
37
37
  headers
38
38
  });
39
39
  } else {
40
- response = await this.fetch_implementation(
41
- `${config?.root}/${API_INFO_URL}`,
42
- {
43
- headers
44
- }
45
- );
40
+ response = await this.fetch(`${config?.root}/${API_INFO_URL}`, {
41
+ headers
42
+ });
46
43
  }
47
44
 
48
45
  if (!response.ok) {
package/vite.config.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import { defineConfig } from "vite";
2
2
  import { svelte } from "@sveltejs/vite-plugin-svelte";
3
3
 
4
+ const TEST_MODE = process.env.TEST_MODE || "happy-dom";
5
+
4
6
  export default defineConfig({
5
7
  build: {
6
8
  lib: {
@@ -17,6 +19,11 @@ export default defineConfig({
17
19
  },
18
20
  plugins: [svelte()],
19
21
 
22
+ mode: process.env.MODE || "development",
23
+ test: {
24
+ include: ["./src/test/*.test.*"],
25
+ environment: TEST_MODE
26
+ },
20
27
  ssr: {
21
28
  target: "node",
22
29
  format: "esm",