@gradio/client 0.20.0 → 1.1.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.
- package/CHANGELOG.md +201 -0
- package/README.md +21 -36
- package/dist/client.d.ts +6 -7
- package/dist/client.d.ts.map +1 -1
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/helpers/data.d.ts +15 -1
- package/dist/helpers/data.d.ts.map +1 -1
- package/dist/helpers/init_helpers.d.ts.map +1 -1
- package/dist/helpers/spaces.d.ts.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +496 -114
- package/dist/test/handlers.d.ts +1 -0
- package/dist/test/handlers.d.ts.map +1 -1
- package/dist/test/test_data.d.ts.map +1 -1
- package/dist/types.d.ts +93 -24
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/handle_blob.d.ts +2 -1
- package/dist/utils/handle_blob.d.ts.map +1 -1
- package/dist/utils/predict.d.ts +2 -2
- package/dist/utils/predict.d.ts.map +1 -1
- package/dist/utils/stream.d.ts +2 -1
- package/dist/utils/stream.d.ts.map +1 -1
- package/dist/utils/submit.d.ts +2 -2
- package/dist/utils/submit.d.ts.map +1 -1
- package/index.html +39 -0
- package/package.json +5 -2
- package/src/client.ts +40 -35
- package/src/constants.ts +4 -0
- package/src/helpers/api_info.ts +1 -1
- package/src/helpers/data.ts +124 -10
- package/src/helpers/init_helpers.ts +5 -0
- package/src/helpers/spaces.ts +2 -1
- package/src/index.ts +6 -1
- package/src/test/api_info.test.ts +0 -1
- package/src/test/data.test.ts +201 -26
- package/src/test/handlers.ts +9 -1
- package/src/test/stream.test.ts +12 -10
- package/src/test/test_data.ts +8 -5
- package/src/test/upload_files.test.ts +1 -1
- package/src/types.ts +110 -26
- package/src/utils/handle_blob.ts +91 -1
- package/src/utils/predict.ts +15 -16
- package/src/utils/stream.ts +66 -13
- package/src/utils/submit.ts +156 -63
- package/src/utils/upload_files.ts +1 -1
- package/vite.config.js +37 -24
package/src/utils/submit.ts
CHANGED
@@ -2,19 +2,16 @@
|
|
2
2
|
import type {
|
3
3
|
Status,
|
4
4
|
Payload,
|
5
|
-
|
6
|
-
ListenerMap,
|
7
|
-
SubmitReturn,
|
8
|
-
EventListener,
|
9
|
-
Event,
|
5
|
+
GradioEvent,
|
10
6
|
JsApiData,
|
11
7
|
EndpointInfo,
|
12
8
|
ApiInfo,
|
13
9
|
Config,
|
14
|
-
Dependency
|
10
|
+
Dependency,
|
11
|
+
SubmitIterable
|
15
12
|
} from "../types";
|
16
13
|
|
17
|
-
import { skip_queue, post_message } from "../helpers/data";
|
14
|
+
import { skip_queue, post_message, handle_payload } from "../helpers/data";
|
18
15
|
import { resolve_root } from "../helpers/init_helpers";
|
19
16
|
import {
|
20
17
|
handle_message,
|
@@ -31,8 +28,9 @@ export function submit(
|
|
31
28
|
endpoint: string | number,
|
32
29
|
data: unknown[] | Record<string, unknown>,
|
33
30
|
event_data?: unknown,
|
34
|
-
trigger_id?: number | null
|
35
|
-
|
31
|
+
trigger_id?: number | null,
|
32
|
+
all_events?: boolean
|
33
|
+
): SubmitIterable<GradioEvent> {
|
36
34
|
try {
|
37
35
|
const { hf_token } = this.options;
|
38
36
|
const {
|
@@ -47,9 +45,12 @@ export function submit(
|
|
47
45
|
pending_diff_streams,
|
48
46
|
event_callbacks,
|
49
47
|
unclosed_events,
|
50
|
-
post_data
|
48
|
+
post_data,
|
49
|
+
options
|
51
50
|
} = this;
|
52
51
|
|
52
|
+
const that = this;
|
53
|
+
|
53
54
|
if (!api_info) throw new Error("No API found");
|
54
55
|
if (!config) throw new Error("Could not resolve app config");
|
55
56
|
|
@@ -70,41 +71,26 @@ export function submit(
|
|
70
71
|
let payload: Payload;
|
71
72
|
let event_id: string | null = null;
|
72
73
|
let complete: Status | undefined | false = false;
|
73
|
-
const listener_map: ListenerMap<EventType> = {};
|
74
74
|
let last_status: Record<string, Status["stage"]> = {};
|
75
75
|
let url_params =
|
76
|
-
typeof window !== "undefined"
|
76
|
+
typeof window !== "undefined" && typeof document !== "undefined"
|
77
77
|
? new URLSearchParams(window.location.search).toString()
|
78
78
|
: "";
|
79
79
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
80
|
+
const events_to_publish =
|
81
|
+
options?.events?.reduce(
|
82
|
+
(acc, event) => {
|
83
|
+
acc[event] = true;
|
84
|
+
return acc;
|
85
|
+
},
|
86
|
+
{} as Record<string, boolean>
|
87
|
+
) || {};
|
86
88
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
const listeners = narrowed_listener_map[eventType] || [];
|
93
|
-
narrowed_listener_map[eventType] = listeners;
|
94
|
-
listeners?.push(listener);
|
95
|
-
|
96
|
-
return { on, off, cancel, destroy };
|
97
|
-
}
|
98
|
-
|
99
|
-
function off<K extends EventType>(
|
100
|
-
eventType: K,
|
101
|
-
listener: EventListener<K>
|
102
|
-
): SubmitReturn {
|
103
|
-
const narrowed_listener_map: ListenerMap<K> = listener_map;
|
104
|
-
let listeners = narrowed_listener_map[eventType] || [];
|
105
|
-
listeners = listeners?.filter((l) => l !== listener);
|
106
|
-
narrowed_listener_map[eventType] = listeners;
|
107
|
-
return { on, off, cancel, destroy };
|
89
|
+
// event subscription methods
|
90
|
+
function fire_event(event: GradioEvent): void {
|
91
|
+
if (all_events || events_to_publish[event.type]) {
|
92
|
+
push_event(event);
|
93
|
+
}
|
108
94
|
}
|
109
95
|
|
110
96
|
async function cancel(): Promise<void> {
|
@@ -121,6 +107,7 @@ export function submit(
|
|
121
107
|
fn_index: fn_index
|
122
108
|
});
|
123
109
|
|
110
|
+
let reset_request = {};
|
124
111
|
let cancel_request = {};
|
125
112
|
if (protocol === "ws") {
|
126
113
|
if (websocket && websocket.readyState === 0) {
|
@@ -130,10 +117,12 @@ export function submit(
|
|
130
117
|
} else {
|
131
118
|
websocket.close();
|
132
119
|
}
|
133
|
-
|
120
|
+
reset_request = { fn_index, session_hash };
|
134
121
|
} else {
|
135
|
-
|
136
|
-
|
122
|
+
close_stream(stream_status, that.abort_controller);
|
123
|
+
close();
|
124
|
+
reset_request = { event_id };
|
125
|
+
cancel_request = { event_id, session_hash, fn_index };
|
137
126
|
}
|
138
127
|
|
139
128
|
try {
|
@@ -141,10 +130,18 @@ export function submit(
|
|
141
130
|
throw new Error("Could not resolve app config");
|
142
131
|
}
|
143
132
|
|
133
|
+
if ("event_id" in cancel_request) {
|
134
|
+
await fetch(`${config.root}/cancel`, {
|
135
|
+
headers: { "Content-Type": "application/json" },
|
136
|
+
method: "POST",
|
137
|
+
body: JSON.stringify(cancel_request)
|
138
|
+
});
|
139
|
+
}
|
140
|
+
|
144
141
|
await fetch(`${config.root}/reset`, {
|
145
142
|
headers: { "Content-Type": "application/json" },
|
146
143
|
method: "POST",
|
147
|
-
body: JSON.stringify(
|
144
|
+
body: JSON.stringify(reset_request)
|
148
145
|
});
|
149
146
|
} catch (e) {
|
150
147
|
console.warn(
|
@@ -153,15 +150,6 @@ export function submit(
|
|
153
150
|
}
|
154
151
|
}
|
155
152
|
|
156
|
-
function destroy(): void {
|
157
|
-
for (const event_type in listener_map) {
|
158
|
-
listener_map &&
|
159
|
-
listener_map[event_type as "data" | "status"]?.forEach((fn) => {
|
160
|
-
off(event_type as "data" | "status", fn);
|
161
|
-
});
|
162
|
-
}
|
163
|
-
}
|
164
|
-
|
165
153
|
const resolve_heartbeat = async (config: Config): Promise<void> => {
|
166
154
|
await this._resolve_hearbeat(config);
|
167
155
|
};
|
@@ -193,8 +181,15 @@ export function submit(
|
|
193
181
|
|
194
182
|
this.handle_blob(config.root, resolved_data, endpoint_info).then(
|
195
183
|
async (_payload) => {
|
184
|
+
let input_data = handle_payload(
|
185
|
+
_payload,
|
186
|
+
dependency,
|
187
|
+
config.components,
|
188
|
+
"input",
|
189
|
+
true
|
190
|
+
);
|
196
191
|
payload = {
|
197
|
-
data:
|
192
|
+
data: input_data || [],
|
198
193
|
event_data,
|
199
194
|
fn_index,
|
200
195
|
trigger_id
|
@@ -225,7 +220,13 @@ export function submit(
|
|
225
220
|
type: "data",
|
226
221
|
endpoint: _endpoint,
|
227
222
|
fn_index,
|
228
|
-
data:
|
223
|
+
data: handle_payload(
|
224
|
+
data,
|
225
|
+
dependency,
|
226
|
+
config.components,
|
227
|
+
"output",
|
228
|
+
options.with_null_state
|
229
|
+
),
|
229
230
|
time: new Date(),
|
230
231
|
event_data,
|
231
232
|
trigger_id
|
@@ -359,7 +360,13 @@ export function submit(
|
|
359
360
|
fire_event({
|
360
361
|
type: "data",
|
361
362
|
time: new Date(),
|
362
|
-
data:
|
363
|
+
data: handle_payload(
|
364
|
+
data.data,
|
365
|
+
dependency,
|
366
|
+
config.components,
|
367
|
+
"output",
|
368
|
+
options.with_null_state
|
369
|
+
),
|
363
370
|
endpoint: _endpoint,
|
364
371
|
fn_index,
|
365
372
|
event_data,
|
@@ -411,7 +418,7 @@ export function submit(
|
|
411
418
|
url.searchParams.set("__sign", this.jwt);
|
412
419
|
}
|
413
420
|
|
414
|
-
stream =
|
421
|
+
stream = this.stream(url);
|
415
422
|
|
416
423
|
if (!stream) {
|
417
424
|
return Promise.reject(
|
@@ -437,6 +444,7 @@ export function submit(
|
|
437
444
|
});
|
438
445
|
if (status.stage === "error") {
|
439
446
|
stream?.close();
|
447
|
+
close();
|
440
448
|
}
|
441
449
|
} else if (type === "data") {
|
442
450
|
event_id = _data.event_id as string;
|
@@ -456,6 +464,7 @@ export function submit(
|
|
456
464
|
time: new Date()
|
457
465
|
});
|
458
466
|
stream?.close();
|
467
|
+
close();
|
459
468
|
}
|
460
469
|
} else if (type === "complete") {
|
461
470
|
complete = status;
|
@@ -482,7 +491,13 @@ export function submit(
|
|
482
491
|
fire_event({
|
483
492
|
type: "data",
|
484
493
|
time: new Date(),
|
485
|
-
data:
|
494
|
+
data: handle_payload(
|
495
|
+
data.data,
|
496
|
+
dependency,
|
497
|
+
config.components,
|
498
|
+
"output",
|
499
|
+
options.with_null_state
|
500
|
+
),
|
486
501
|
endpoint: _endpoint,
|
487
502
|
fn_index,
|
488
503
|
event_data,
|
@@ -500,6 +515,7 @@ export function submit(
|
|
500
515
|
fn_index
|
501
516
|
});
|
502
517
|
stream?.close();
|
518
|
+
close();
|
503
519
|
}
|
504
520
|
}
|
505
521
|
};
|
@@ -520,7 +536,10 @@ export function submit(
|
|
520
536
|
time: new Date()
|
521
537
|
});
|
522
538
|
let hostname = "";
|
523
|
-
if (
|
539
|
+
if (
|
540
|
+
typeof window !== "undefined" &&
|
541
|
+
typeof document !== "undefined"
|
542
|
+
) {
|
524
543
|
hostname = window?.location?.hostname;
|
525
544
|
}
|
526
545
|
|
@@ -530,7 +549,9 @@ export function submit(
|
|
530
549
|
: `https://huggingface.co`;
|
531
550
|
|
532
551
|
const is_iframe =
|
533
|
-
typeof window !== "undefined" &&
|
552
|
+
typeof window !== "undefined" &&
|
553
|
+
typeof document !== "undefined" &&
|
554
|
+
window.parent != window;
|
534
555
|
const is_zerogpu_space = dependency.zerogpu && config.space_id;
|
535
556
|
const zerogpu_auth_promise =
|
536
557
|
is_iframe && is_zerogpu_space
|
@@ -633,7 +654,13 @@ export function submit(
|
|
633
654
|
fire_event({
|
634
655
|
type: "data",
|
635
656
|
time: new Date(),
|
636
|
-
data:
|
657
|
+
data: handle_payload(
|
658
|
+
data.data,
|
659
|
+
dependency,
|
660
|
+
config.components,
|
661
|
+
"output",
|
662
|
+
options.with_null_state
|
663
|
+
),
|
637
664
|
endpoint: _endpoint,
|
638
665
|
fn_index
|
639
666
|
});
|
@@ -676,9 +703,10 @@ export function submit(
|
|
676
703
|
fn_index,
|
677
704
|
time: new Date()
|
678
705
|
});
|
679
|
-
if (["sse_v2", "sse_v2.1"].includes(protocol)) {
|
680
|
-
close_stream(stream_status,
|
706
|
+
if (["sse_v2", "sse_v2.1", "sse_v3"].includes(protocol)) {
|
707
|
+
close_stream(stream_status, that.abort_controller);
|
681
708
|
stream_status.open = false;
|
709
|
+
close();
|
682
710
|
}
|
683
711
|
}
|
684
712
|
};
|
@@ -701,13 +729,78 @@ export function submit(
|
|
701
729
|
}
|
702
730
|
);
|
703
731
|
|
704
|
-
|
732
|
+
let done = false;
|
733
|
+
const values: (IteratorResult<GradioEvent> | PromiseLike<never>)[] = [];
|
734
|
+
const resolvers: ((
|
735
|
+
value: IteratorResult<GradioEvent> | PromiseLike<never>
|
736
|
+
) => void)[] = [];
|
737
|
+
|
738
|
+
function close(): void {
|
739
|
+
done = true;
|
740
|
+
while (resolvers.length > 0)
|
741
|
+
(resolvers.shift() as (typeof resolvers)[0])({
|
742
|
+
value: undefined,
|
743
|
+
done: true
|
744
|
+
});
|
745
|
+
}
|
746
|
+
|
747
|
+
function push(
|
748
|
+
data: { value: GradioEvent; done: boolean } | PromiseLike<never>
|
749
|
+
): void {
|
750
|
+
if (done) return;
|
751
|
+
if (resolvers.length > 0) {
|
752
|
+
(resolvers.shift() as (typeof resolvers)[0])(data);
|
753
|
+
} else {
|
754
|
+
values.push(data);
|
755
|
+
}
|
756
|
+
}
|
757
|
+
|
758
|
+
function push_error(error: unknown): void {
|
759
|
+
push(thenable_reject(error));
|
760
|
+
close();
|
761
|
+
}
|
762
|
+
|
763
|
+
function push_event(event: GradioEvent): void {
|
764
|
+
push({ value: event, done: false });
|
765
|
+
}
|
766
|
+
|
767
|
+
function next(): Promise<IteratorResult<GradioEvent, unknown>> {
|
768
|
+
if (values.length > 0)
|
769
|
+
return Promise.resolve(values.shift() as (typeof values)[0]);
|
770
|
+
if (done) return Promise.resolve({ value: undefined, done: true });
|
771
|
+
return new Promise((resolve) => resolvers.push(resolve));
|
772
|
+
}
|
773
|
+
|
774
|
+
const iterator = {
|
775
|
+
[Symbol.asyncIterator]: () => iterator,
|
776
|
+
next,
|
777
|
+
throw: async (value: unknown) => {
|
778
|
+
push_error(value);
|
779
|
+
return next();
|
780
|
+
},
|
781
|
+
return: async () => {
|
782
|
+
close();
|
783
|
+
return next();
|
784
|
+
},
|
785
|
+
cancel
|
786
|
+
};
|
787
|
+
|
788
|
+
return iterator;
|
705
789
|
} catch (error) {
|
706
790
|
console.error("Submit function encountered an error:", error);
|
707
791
|
throw error;
|
708
792
|
}
|
709
793
|
}
|
710
794
|
|
795
|
+
function thenable_reject<T>(error: T): PromiseLike<never> {
|
796
|
+
return {
|
797
|
+
then: (
|
798
|
+
resolve: (value: never) => PromiseLike<never>,
|
799
|
+
reject: (error: T) => PromiseLike<never>
|
800
|
+
) => reject(error)
|
801
|
+
};
|
802
|
+
}
|
803
|
+
|
711
804
|
function get_endpoint_info(
|
712
805
|
api_info: ApiInfo<JsApiData>,
|
713
806
|
endpoint: string | number,
|
@@ -27,7 +27,7 @@ export async function upload_files(
|
|
27
27
|
});
|
28
28
|
try {
|
29
29
|
const upload_url = upload_id
|
30
|
-
? `${root_url}
|
30
|
+
? `${root_url}/${UPLOAD_URL}?upload_id=${upload_id}`
|
31
31
|
: `${root_url}/${UPLOAD_URL}`;
|
32
32
|
|
33
33
|
response = await this.fetch(upload_url, {
|
package/vite.config.js
CHANGED
@@ -3,30 +3,43 @@ import { svelte } from "@sveltejs/vite-plugin-svelte";
|
|
3
3
|
|
4
4
|
const TEST_MODE = process.env.TEST_MODE || "happy-dom";
|
5
5
|
|
6
|
-
export default defineConfig({
|
7
|
-
|
8
|
-
|
9
|
-
entry: "
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
export default defineConfig(({ mode }) => {
|
7
|
+
if (mode === "preview") {
|
8
|
+
return {
|
9
|
+
entry: "index.html"
|
10
|
+
};
|
11
|
+
}
|
12
|
+
return {
|
13
|
+
build: {
|
14
|
+
lib: {
|
15
|
+
entry: "src/index.ts",
|
16
|
+
formats: ["es"],
|
17
|
+
fileName: (format) => `index.${format}.js`
|
18
|
+
},
|
19
|
+
rollupOptions: {
|
20
|
+
input: "src/index.ts",
|
21
|
+
output: {
|
22
|
+
dir: "dist"
|
23
|
+
}
|
17
24
|
}
|
18
|
-
}
|
19
|
-
|
20
|
-
plugins: [svelte()],
|
25
|
+
},
|
26
|
+
plugins: [svelte()],
|
21
27
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
mode: process.env.MODE || "development",
|
29
|
+
test: {
|
30
|
+
include: ["./src/test/*.test.*"],
|
31
|
+
environment: TEST_MODE
|
32
|
+
},
|
33
|
+
ssr: {
|
34
|
+
target: "node",
|
35
|
+
format: "esm",
|
36
|
+
noExternal: [
|
37
|
+
"ws",
|
38
|
+
"semiver",
|
39
|
+
"bufferutil",
|
40
|
+
"@gradio/upload",
|
41
|
+
"fetch-event-stream"
|
42
|
+
]
|
43
|
+
}
|
44
|
+
};
|
32
45
|
});
|