@nmtjs/http-client 0.15.3 → 0.16.0-beta.10
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/dist/http-stream-parser.js.map +1 -1
- package/dist/index.d.ts +26 -13
- package/dist/index.js +51 -38
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/src/index.ts +70 -71
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http-stream-parser.js","sourceRoot":"","sources":["../src/http-stream-parser.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,gBAAgB;IACnB,OAAO,GAAG,EAAE,CAAA;IAEpB,IAAI,CAAC,KAAa,EAAE,IAA4B
|
|
1
|
+
{"version":3,"file":"http-stream-parser.js","sourceRoot":"","sources":["../src/http-stream-parser.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ClientTransportFactory, TransportCallContext, TransportCallOptions, TransportRpcParams, UnidirectionalTransport } from '@nmtjs/client';
|
|
2
2
|
import type { ProtocolVersion } from '@nmtjs/protocol';
|
|
3
3
|
import type { BaseClientFormat } from '@nmtjs/protocol/client';
|
|
4
4
|
import { ConnectionType } from '@nmtjs/protocol';
|
|
@@ -14,7 +14,7 @@ export type HttpClientTransportOptions = {
|
|
|
14
14
|
fetch?: typeof fetch;
|
|
15
15
|
decodeBase64?: DecodeBase64Function;
|
|
16
16
|
};
|
|
17
|
-
export declare class HttpTransportClient implements
|
|
17
|
+
export declare class HttpTransportClient implements UnidirectionalTransport {
|
|
18
18
|
protected readonly format: BaseClientFormat;
|
|
19
19
|
protected readonly protocol: ProtocolVersion;
|
|
20
20
|
protected options: HttpClientTransportOptions;
|
|
@@ -22,24 +22,34 @@ export declare class HttpTransportClient implements ClientTransport<ConnectionTy
|
|
|
22
22
|
decodeBase64: DecodeBase64Function;
|
|
23
23
|
constructor(format: BaseClientFormat, protocol: ProtocolVersion, options: HttpClientTransportOptions);
|
|
24
24
|
private getFetch;
|
|
25
|
-
url({ procedure, application
|
|
25
|
+
url({ procedure, application }: {
|
|
26
26
|
procedure: string;
|
|
27
27
|
application?: string;
|
|
28
|
-
payload?: unknown;
|
|
29
28
|
}): URL;
|
|
30
|
-
call(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
29
|
+
call(context: TransportCallContext, rpc: TransportRpcParams, options: TransportCallOptions): Promise<{
|
|
30
|
+
type: 'error';
|
|
31
|
+
error: Uint8Array<ArrayBuffer>;
|
|
32
|
+
status: number;
|
|
33
|
+
statusText: string;
|
|
34
|
+
stream?: undefined;
|
|
35
|
+
metadata?: undefined;
|
|
36
|
+
source?: undefined;
|
|
37
|
+
result?: undefined;
|
|
38
|
+
} | {
|
|
39
|
+
error?: undefined;
|
|
40
|
+
status?: undefined;
|
|
41
|
+
statusText?: undefined;
|
|
42
|
+
type: 'rpc_stream';
|
|
36
43
|
stream: ReadableStream<ArrayBufferView<ArrayBufferLike>>;
|
|
37
44
|
metadata?: undefined;
|
|
38
45
|
source?: undefined;
|
|
39
46
|
result?: undefined;
|
|
40
47
|
} | {
|
|
48
|
+
error?: undefined;
|
|
49
|
+
status?: undefined;
|
|
50
|
+
statusText?: undefined;
|
|
41
51
|
stream?: undefined;
|
|
42
|
-
type:
|
|
52
|
+
type: 'blob';
|
|
43
53
|
metadata: {
|
|
44
54
|
type: string;
|
|
45
55
|
size: number | undefined;
|
|
@@ -48,13 +58,16 @@ export declare class HttpTransportClient implements ClientTransport<ConnectionTy
|
|
|
48
58
|
source: ReadableStream<Uint8Array<ArrayBuffer>>;
|
|
49
59
|
result?: undefined;
|
|
50
60
|
} | {
|
|
61
|
+
error?: undefined;
|
|
62
|
+
status?: undefined;
|
|
63
|
+
statusText?: undefined;
|
|
51
64
|
stream?: undefined;
|
|
52
65
|
metadata?: undefined;
|
|
53
66
|
source?: undefined;
|
|
54
|
-
type:
|
|
67
|
+
type: 'rpc';
|
|
55
68
|
result: Uint8Array<ArrayBuffer>;
|
|
56
69
|
}>;
|
|
57
70
|
}
|
|
58
|
-
export type HttpTransportFactory = ClientTransportFactory<
|
|
71
|
+
export type HttpTransportFactory = ClientTransportFactory<HttpTransportClient, HttpClientTransportOptions>;
|
|
59
72
|
export declare const HttpTransportFactory: HttpTransportFactory;
|
|
60
73
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ConnectionType, ErrorCode
|
|
1
|
+
import { ConnectionType, ErrorCode } from '@nmtjs/protocol';
|
|
2
2
|
import { ProtocolError } from '@nmtjs/protocol/client';
|
|
3
3
|
import { HttpStreamParser } from './http-stream-parser.js';
|
|
4
4
|
const createDecodeBase64 = (customFn) => {
|
|
@@ -19,6 +19,30 @@ const createDecodeBase64 = (customFn) => {
|
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
21
|
const NEEMATA_BLOB_HEADER = 'X-Neemata-Blob';
|
|
22
|
+
const MAX_KEEPALIVE_BODY_BYTES = 64 * 1024;
|
|
23
|
+
const getBodyByteLength = (body) => {
|
|
24
|
+
if (typeof body === 'string') {
|
|
25
|
+
return new TextEncoder().encode(body).byteLength;
|
|
26
|
+
}
|
|
27
|
+
if (ArrayBuffer.isView(body)) {
|
|
28
|
+
return body.byteLength;
|
|
29
|
+
}
|
|
30
|
+
if (body instanceof ArrayBuffer) {
|
|
31
|
+
return body.byteLength;
|
|
32
|
+
}
|
|
33
|
+
if (typeof Blob !== 'undefined' && body instanceof Blob) {
|
|
34
|
+
return body.size;
|
|
35
|
+
}
|
|
36
|
+
if (typeof URLSearchParams !== 'undefined' &&
|
|
37
|
+
body instanceof URLSearchParams) {
|
|
38
|
+
return new TextEncoder().encode(body.toString()).byteLength;
|
|
39
|
+
}
|
|
40
|
+
return undefined;
|
|
41
|
+
};
|
|
42
|
+
const shouldUseKeepalive = (body) => {
|
|
43
|
+
const byteLength = getBodyByteLength(body);
|
|
44
|
+
return byteLength !== undefined && byteLength <= MAX_KEEPALIVE_BODY_BYTES;
|
|
45
|
+
};
|
|
22
46
|
export class HttpTransportClient {
|
|
23
47
|
format;
|
|
24
48
|
protocol;
|
|
@@ -39,51 +63,45 @@ export class HttpTransportClient {
|
|
|
39
63
|
}
|
|
40
64
|
return implementation;
|
|
41
65
|
}
|
|
42
|
-
url({ procedure, application
|
|
66
|
+
url({ procedure, application }) {
|
|
43
67
|
const base = application ? `/${application}/${procedure}` : `/${procedure}`;
|
|
44
68
|
const url = new URL(base, this.options.url);
|
|
45
|
-
if (payload)
|
|
46
|
-
url.searchParams.set('payload', JSON.stringify(payload));
|
|
47
69
|
return url;
|
|
48
70
|
}
|
|
49
|
-
async call(
|
|
71
|
+
async call(context, rpc, options) {
|
|
50
72
|
const { procedure, payload } = rpc;
|
|
51
73
|
const requestHeaders = new Headers();
|
|
52
74
|
const fetchImpl = this.getFetch();
|
|
53
|
-
const url = this.url({ application:
|
|
54
|
-
if (
|
|
55
|
-
requestHeaders.set('Authorization',
|
|
56
|
-
requestHeaders.set('Accept',
|
|
75
|
+
const url = this.url({ application: context.application, procedure });
|
|
76
|
+
if (context.auth)
|
|
77
|
+
requestHeaders.set('Authorization', context.auth);
|
|
78
|
+
requestHeaders.set('Accept', context.contentType);
|
|
57
79
|
let body;
|
|
58
|
-
if (
|
|
59
|
-
requestHeaders.set('Content-Type',
|
|
80
|
+
if (rpc.blob) {
|
|
81
|
+
requestHeaders.set('Content-Type', rpc.blob.metadata.type);
|
|
60
82
|
requestHeaders.set(NEEMATA_BLOB_HEADER, 'true');
|
|
83
|
+
body = rpc.blob.source;
|
|
61
84
|
}
|
|
62
85
|
else {
|
|
63
|
-
requestHeaders.set('Content-Type',
|
|
64
|
-
|
|
65
|
-
body = buffer;
|
|
86
|
+
requestHeaders.set('Content-Type', context.contentType);
|
|
87
|
+
body = new Uint8Array(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
66
88
|
}
|
|
67
|
-
if (options.
|
|
89
|
+
if (options.streamResponse) {
|
|
68
90
|
const response = await fetchImpl(url.toString(), {
|
|
69
91
|
body,
|
|
70
92
|
method: 'POST',
|
|
71
93
|
headers: requestHeaders,
|
|
72
94
|
signal: options.signal,
|
|
73
95
|
credentials: 'include',
|
|
74
|
-
keepalive: true,
|
|
96
|
+
...(shouldUseKeepalive(body) ? { keepalive: true } : {}),
|
|
75
97
|
});
|
|
76
98
|
if (!response.ok) {
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
if (cause instanceof ProtocolError)
|
|
84
|
-
throw cause;
|
|
85
|
-
throw new ProtocolError(ErrorCode.ClientRequestError, `HTTP ${response.status}: ${response.statusText}`);
|
|
86
|
-
}
|
|
99
|
+
return {
|
|
100
|
+
type: 'error',
|
|
101
|
+
error: await response.bytes().catch(() => new Uint8Array(0)),
|
|
102
|
+
status: response.status,
|
|
103
|
+
statusText: response.statusText,
|
|
104
|
+
};
|
|
87
105
|
}
|
|
88
106
|
if (!response.body) {
|
|
89
107
|
throw new ProtocolError(ErrorCode.ClientRequestError, 'Empty stream response body');
|
|
@@ -135,7 +153,7 @@ export class HttpTransportClient {
|
|
|
135
153
|
headers: requestHeaders,
|
|
136
154
|
signal: options.signal,
|
|
137
155
|
credentials: 'include',
|
|
138
|
-
keepalive: true,
|
|
156
|
+
...(shouldUseKeepalive(body) ? { keepalive: true } : {}),
|
|
139
157
|
});
|
|
140
158
|
if (response.ok) {
|
|
141
159
|
const isBlob = !!response.headers.get(NEEMATA_BLOB_HEADER);
|
|
@@ -161,17 +179,12 @@ export class HttpTransportClient {
|
|
|
161
179
|
}
|
|
162
180
|
}
|
|
163
181
|
else {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
if (cause instanceof ProtocolError)
|
|
171
|
-
throw cause;
|
|
172
|
-
// If decoding fails, throw generic error with status info
|
|
173
|
-
throw new ProtocolError(ErrorCode.ClientRequestError, `HTTP ${response.status}: ${response.statusText}`);
|
|
174
|
-
}
|
|
182
|
+
return {
|
|
183
|
+
type: 'error',
|
|
184
|
+
error: await response.bytes().catch(() => new Uint8Array(0)),
|
|
185
|
+
status: response.status,
|
|
186
|
+
statusText: response.statusText,
|
|
187
|
+
};
|
|
175
188
|
}
|
|
176
189
|
}
|
|
177
190
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -10,14 +10,14 @@
|
|
|
10
10
|
}
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@nmtjs/
|
|
14
|
-
"@nmtjs/
|
|
15
|
-
"@nmtjs/
|
|
13
|
+
"@nmtjs/protocol": "0.16.0-beta.10",
|
|
14
|
+
"@nmtjs/client": "0.16.0-beta.10",
|
|
15
|
+
"@nmtjs/common": "0.16.0-beta.10"
|
|
16
16
|
},
|
|
17
17
|
"peerDependencies": {
|
|
18
|
-
"@nmtjs/common": "0.
|
|
19
|
-
"@nmtjs/protocol": "0.
|
|
20
|
-
"@nmtjs/client": "0.
|
|
18
|
+
"@nmtjs/common": "0.16.0-beta.10",
|
|
19
|
+
"@nmtjs/protocol": "0.16.0-beta.10",
|
|
20
|
+
"@nmtjs/client": "0.16.0-beta.10"
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
23
|
"dist",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
"LICENSE.md",
|
|
26
26
|
"README.md"
|
|
27
27
|
],
|
|
28
|
-
"version": "0.
|
|
28
|
+
"version": "0.16.0-beta.10",
|
|
29
29
|
"scripts": {
|
|
30
30
|
"clean-build": "rm -rf ./dist"
|
|
31
31
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
ClientTransport,
|
|
3
2
|
ClientTransportFactory,
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
TransportCallContext,
|
|
4
|
+
TransportCallOptions,
|
|
5
|
+
TransportRpcParams,
|
|
6
|
+
UnidirectionalTransport,
|
|
6
7
|
} from '@nmtjs/client'
|
|
7
8
|
import type { ProtocolVersion } from '@nmtjs/protocol'
|
|
8
9
|
import type { BaseClientFormat } from '@nmtjs/protocol/client'
|
|
9
|
-
import { ConnectionType, ErrorCode
|
|
10
|
+
import { ConnectionType, ErrorCode } from '@nmtjs/protocol'
|
|
10
11
|
import { ProtocolError } from '@nmtjs/protocol/client'
|
|
11
12
|
|
|
12
13
|
import { HttpStreamParser } from './http-stream-parser.ts'
|
|
@@ -33,6 +34,39 @@ const createDecodeBase64 = (
|
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
const NEEMATA_BLOB_HEADER = 'X-Neemata-Blob'
|
|
37
|
+
const MAX_KEEPALIVE_BODY_BYTES = 64 * 1024
|
|
38
|
+
|
|
39
|
+
const getBodyByteLength = (body: unknown): number | undefined => {
|
|
40
|
+
if (typeof body === 'string') {
|
|
41
|
+
return new TextEncoder().encode(body).byteLength
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (ArrayBuffer.isView(body)) {
|
|
45
|
+
return body.byteLength
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (body instanceof ArrayBuffer) {
|
|
49
|
+
return body.byteLength
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof Blob !== 'undefined' && body instanceof Blob) {
|
|
53
|
+
return body.size
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (
|
|
57
|
+
typeof URLSearchParams !== 'undefined' &&
|
|
58
|
+
body instanceof URLSearchParams
|
|
59
|
+
) {
|
|
60
|
+
return new TextEncoder().encode(body.toString()).byteLength
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return undefined
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const shouldUseKeepalive = (body: unknown): boolean => {
|
|
67
|
+
const byteLength = getBodyByteLength(body)
|
|
68
|
+
return byteLength !== undefined && byteLength <= MAX_KEEPALIVE_BODY_BYTES
|
|
69
|
+
}
|
|
36
70
|
|
|
37
71
|
export type HttpClientTransportOptions = {
|
|
38
72
|
/**
|
|
@@ -46,9 +80,7 @@ export type HttpClientTransportOptions = {
|
|
|
46
80
|
decodeBase64?: DecodeBase64Function
|
|
47
81
|
}
|
|
48
82
|
|
|
49
|
-
export class HttpTransportClient
|
|
50
|
-
implements ClientTransport<ConnectionType.Unidirectional>
|
|
51
|
-
{
|
|
83
|
+
export class HttpTransportClient implements UnidirectionalTransport {
|
|
52
84
|
type: ConnectionType.Unidirectional = ConnectionType.Unidirectional
|
|
53
85
|
decodeBase64: DecodeBase64Function
|
|
54
86
|
|
|
@@ -71,75 +103,57 @@ export class HttpTransportClient
|
|
|
71
103
|
return implementation
|
|
72
104
|
}
|
|
73
105
|
|
|
74
|
-
url({
|
|
75
|
-
procedure,
|
|
76
|
-
application,
|
|
77
|
-
payload,
|
|
78
|
-
}: {
|
|
79
|
-
procedure: string
|
|
80
|
-
application?: string
|
|
81
|
-
payload?: unknown
|
|
82
|
-
}) {
|
|
106
|
+
url({ procedure, application }: { procedure: string; application?: string }) {
|
|
83
107
|
const base = application ? `/${application}/${procedure}` : `/${procedure}`
|
|
84
108
|
const url = new URL(base, this.options.url)
|
|
85
|
-
if (payload) url.searchParams.set('payload', JSON.stringify(payload))
|
|
86
109
|
return url
|
|
87
110
|
}
|
|
88
111
|
|
|
89
112
|
async call(
|
|
90
|
-
|
|
91
|
-
rpc:
|
|
92
|
-
options:
|
|
113
|
+
context: TransportCallContext,
|
|
114
|
+
rpc: TransportRpcParams,
|
|
115
|
+
options: TransportCallOptions,
|
|
93
116
|
) {
|
|
94
117
|
const { procedure, payload } = rpc
|
|
95
118
|
const requestHeaders = new Headers()
|
|
96
119
|
const fetchImpl = this.getFetch()
|
|
97
120
|
|
|
98
|
-
const url = this.url({ application:
|
|
121
|
+
const url = this.url({ application: context.application, procedure })
|
|
99
122
|
|
|
100
|
-
if (
|
|
101
|
-
requestHeaders.set('Accept',
|
|
123
|
+
if (context.auth) requestHeaders.set('Authorization', context.auth)
|
|
124
|
+
requestHeaders.set('Accept', context.contentType)
|
|
102
125
|
|
|
103
126
|
let body: any
|
|
104
127
|
|
|
105
|
-
if (
|
|
106
|
-
requestHeaders.set('Content-Type',
|
|
128
|
+
if (rpc.blob) {
|
|
129
|
+
requestHeaders.set('Content-Type', rpc.blob.metadata.type)
|
|
107
130
|
requestHeaders.set(NEEMATA_BLOB_HEADER, 'true')
|
|
131
|
+
body = rpc.blob.source
|
|
108
132
|
} else {
|
|
109
|
-
requestHeaders.set('Content-Type',
|
|
110
|
-
|
|
111
|
-
|
|
133
|
+
requestHeaders.set('Content-Type', context.contentType)
|
|
134
|
+
body = new Uint8Array(
|
|
135
|
+
payload.buffer,
|
|
136
|
+
payload.byteOffset,
|
|
137
|
+
payload.byteLength,
|
|
138
|
+
)
|
|
112
139
|
}
|
|
113
140
|
|
|
114
|
-
if (options.
|
|
141
|
+
if (options.streamResponse) {
|
|
115
142
|
const response = await fetchImpl(url.toString(), {
|
|
116
143
|
body,
|
|
117
144
|
method: 'POST',
|
|
118
145
|
headers: requestHeaders,
|
|
119
146
|
signal: options.signal,
|
|
120
147
|
credentials: 'include',
|
|
121
|
-
keepalive: true,
|
|
148
|
+
...(shouldUseKeepalive(body) ? { keepalive: true } : {}),
|
|
122
149
|
})
|
|
123
150
|
|
|
124
151
|
if (!response.ok) {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
data?: unknown
|
|
131
|
-
}
|
|
132
|
-
throw new ProtocolError(
|
|
133
|
-
error.code || ErrorCode.ClientRequestError,
|
|
134
|
-
error.message || response.statusText,
|
|
135
|
-
error.data,
|
|
136
|
-
)
|
|
137
|
-
} catch (cause) {
|
|
138
|
-
if (cause instanceof ProtocolError) throw cause
|
|
139
|
-
throw new ProtocolError(
|
|
140
|
-
ErrorCode.ClientRequestError,
|
|
141
|
-
`HTTP ${response.status}: ${response.statusText}`,
|
|
142
|
-
)
|
|
152
|
+
return {
|
|
153
|
+
type: 'error' as const,
|
|
154
|
+
error: await response.bytes().catch(() => new Uint8Array(0)),
|
|
155
|
+
status: response.status,
|
|
156
|
+
statusText: response.statusText,
|
|
143
157
|
}
|
|
144
158
|
}
|
|
145
159
|
|
|
@@ -196,7 +210,7 @@ export class HttpTransportClient
|
|
|
196
210
|
headers: requestHeaders,
|
|
197
211
|
signal: options.signal,
|
|
198
212
|
credentials: 'include',
|
|
199
|
-
keepalive: true,
|
|
213
|
+
...(shouldUseKeepalive(body) ? { keepalive: true } : {}),
|
|
200
214
|
})
|
|
201
215
|
|
|
202
216
|
if (response.ok) {
|
|
@@ -222,25 +236,11 @@ export class HttpTransportClient
|
|
|
222
236
|
return { type: 'rpc' as const, result: await response.bytes() }
|
|
223
237
|
}
|
|
224
238
|
} else {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
data?: unknown
|
|
231
|
-
}
|
|
232
|
-
throw new ProtocolError(
|
|
233
|
-
error.code || ErrorCode.ClientRequestError,
|
|
234
|
-
error.message || response.statusText,
|
|
235
|
-
error.data,
|
|
236
|
-
)
|
|
237
|
-
} catch (cause) {
|
|
238
|
-
if (cause instanceof ProtocolError) throw cause
|
|
239
|
-
// If decoding fails, throw generic error with status info
|
|
240
|
-
throw new ProtocolError(
|
|
241
|
-
ErrorCode.ClientRequestError,
|
|
242
|
-
`HTTP ${response.status}: ${response.statusText}`,
|
|
243
|
-
)
|
|
239
|
+
return {
|
|
240
|
+
type: 'error' as const,
|
|
241
|
+
error: await response.bytes().catch(() => new Uint8Array(0)),
|
|
242
|
+
status: response.status,
|
|
243
|
+
statusText: response.statusText,
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
246
|
}
|
|
@@ -248,9 +248,8 @@ export class HttpTransportClient
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
export type HttpTransportFactory = ClientTransportFactory<
|
|
251
|
-
|
|
252
|
-
HttpClientTransportOptions
|
|
253
|
-
HttpTransportClient
|
|
251
|
+
HttpTransportClient,
|
|
252
|
+
HttpClientTransportOptions
|
|
254
253
|
>
|
|
255
254
|
|
|
256
255
|
export const HttpTransportFactory: HttpTransportFactory = (params, options) => {
|