mirror of
https://github.com/MercuryWorkshop/adrift.git
synced 2025-05-13 06:10:01 -04:00
client body chunking initial clientside impl
This commit is contained in:
parent
0ffb386048
commit
e51b5d90d4
5 changed files with 158 additions and 45 deletions
|
@ -13,5 +13,8 @@
|
||||||
"bare-client-custom": "file:../bare-client-custom",
|
"bare-client-custom": "file:../bare-client-custom",
|
||||||
"firebase": "^10.1.0",
|
"firebase": "^10.1.0",
|
||||||
"protocol": "workspace:*"
|
"protocol": "workspace:*"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^20.4.10"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,92 @@ import {
|
||||||
ReadyStateCallback,
|
ReadyStateCallback,
|
||||||
WebSocketImpl,
|
WebSocketImpl,
|
||||||
} from "bare-client-custom";
|
} from "bare-client-custom";
|
||||||
|
import { ReadableStream, TransformStream } from "node:stream/web";
|
||||||
|
import { MAX_CHUNK_SIZE } from "protocol";
|
||||||
import { Connection } from "./Connection";
|
import { Connection } from "./Connection";
|
||||||
|
|
||||||
// https://fetch.spec.whatwg.org/#statuses
|
// https://fetch.spec.whatwg.org/#statuses
|
||||||
const NULL_BODY_STATUSES = [101, 103, 204, 205, 304];
|
const NULL_BODY_STATUSES = [101, 103, 204, 205, 304];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* given a completely unknown body type, returns a stream that yields Uint8Arrays
|
||||||
|
* below MAX_CHUNK_SIZE.
|
||||||
|
*/
|
||||||
|
function createBodyStream(
|
||||||
|
body: BodyInit | null
|
||||||
|
): ReadableStream<ArrayBuffer | Uint8Array> | null {
|
||||||
|
if (body === null) return null;
|
||||||
|
|
||||||
|
const transformer = () =>
|
||||||
|
new TransformStream({
|
||||||
|
transform: async (
|
||||||
|
chunk: any,
|
||||||
|
controller: TransformStreamDefaultController<Uint8Array>
|
||||||
|
) => {
|
||||||
|
// attempt to transform a couple types into an ArrayBuffer
|
||||||
|
if (typeof chunk === "string") {
|
||||||
|
chunk = new TextEncoder().encode(chunk);
|
||||||
|
}
|
||||||
|
if (chunk instanceof Blob) {
|
||||||
|
chunk = await chunk.arrayBuffer();
|
||||||
|
}
|
||||||
|
if (ArrayBuffer.isView(chunk)) {
|
||||||
|
chunk = chunk.buffer.slice(
|
||||||
|
chunk.byteOffset,
|
||||||
|
chunk.byteOffset + chunk.byteLength
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if none of those worked, give up.
|
||||||
|
if (!(chunk instanceof ArrayBuffer)) {
|
||||||
|
console.error({ chunk });
|
||||||
|
throw new Error("Invalid type read from body stream: " + chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
let current = null;
|
||||||
|
let remaining = chunk;
|
||||||
|
do {
|
||||||
|
current = remaining.slice(0, MAX_CHUNK_SIZE);
|
||||||
|
remaining = remaining.slice(MAX_CHUNK_SIZE);
|
||||||
|
controller.enqueue(new Uint8Array(current));
|
||||||
|
} while (remaining.byteLength > 0);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (body instanceof ReadableStream) {
|
||||||
|
return body.pipeThrough(transformer());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body instanceof ArrayBuffer) {
|
||||||
|
if (body.byteLength == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let remaining = body;
|
||||||
|
return new ReadableStream({
|
||||||
|
type: "bytes",
|
||||||
|
pull: (controller) => {
|
||||||
|
if (remaining.byteLength <= 0) {
|
||||||
|
return controller.close();
|
||||||
|
}
|
||||||
|
const current = remaining.slice(0, MAX_CHUNK_SIZE);
|
||||||
|
remaining = remaining.slice(MAX_CHUNK_SIZE);
|
||||||
|
controller.enqueue(new Uint8Array(current));
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body instanceof Blob) {
|
||||||
|
// @ts-expect-error
|
||||||
|
return body.stream().pipeThrough(transformer());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body instanceof FormData) {
|
||||||
|
throw new Error("formdata todo");
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Unexpected body type: " + body);
|
||||||
|
}
|
||||||
|
|
||||||
export class AdriftBareClient extends Client {
|
export class AdriftBareClient extends Client {
|
||||||
constructor(private connection: Connection) {
|
constructor(private connection: Connection) {
|
||||||
super();
|
super();
|
||||||
|
@ -25,20 +106,15 @@ export class AdriftBareClient extends Client {
|
||||||
duplex: string | undefined,
|
duplex: string | undefined,
|
||||||
signal: AbortSignal | undefined
|
signal: AbortSignal | undefined
|
||||||
): Promise<BareResponse> {
|
): Promise<BareResponse> {
|
||||||
if (
|
const bodyStream = createBodyStream(body);
|
||||||
body !== null &&
|
let { payload, body: respRawBody } = await this.connection.httprequest(
|
||||||
typeof body !== "undefined" &&
|
{
|
||||||
typeof body !== "string"
|
method,
|
||||||
) {
|
requestHeaders,
|
||||||
console.log({ body });
|
remote,
|
||||||
throw new Error("bare-client-custom passed an unexpected body type");
|
},
|
||||||
}
|
bodyStream
|
||||||
let { payload, body: respRawBody } = await this.connection.httprequest({
|
);
|
||||||
method,
|
|
||||||
requestHeaders,
|
|
||||||
body,
|
|
||||||
remote,
|
|
||||||
});
|
|
||||||
const headers = new Headers();
|
const headers = new Headers();
|
||||||
for (const [header, values] of Object.entries(payload.headers)) {
|
for (const [header, values] of Object.entries(payload.headers)) {
|
||||||
for (const value of <string[]>values) {
|
for (const value of <string[]>values) {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { ReadableStream } from "node:stream/web";
|
||||||
import {
|
import {
|
||||||
C2SRequestType,
|
C2SRequestType,
|
||||||
C2SRequestTypes,
|
C2SRequestTypes,
|
||||||
|
@ -130,8 +131,8 @@ export class Connection {
|
||||||
|
|
||||||
async send(
|
async send(
|
||||||
requestID: number,
|
requestID: number,
|
||||||
data: ArrayBuffer | Blob,
|
type: C2SRequestType,
|
||||||
type: C2SRequestType
|
data?: ArrayBuffer | Blob
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
let header = new ArrayBuffer(2 + 1);
|
let header = new ArrayBuffer(2 + 1);
|
||||||
let view = new DataView(header);
|
let view = new DataView(header);
|
||||||
|
@ -143,21 +144,35 @@ export class Connection {
|
||||||
view.setUint8(cursor, type);
|
view.setUint8(cursor, type);
|
||||||
cursor += 1;
|
cursor += 1;
|
||||||
|
|
||||||
let buf = await new Blob([header, data]).arrayBuffer();
|
let buf = header;
|
||||||
|
if (data) {
|
||||||
|
buf = await new Blob([header, data]).arrayBuffer();
|
||||||
|
}
|
||||||
|
|
||||||
this.transport.send(buf);
|
this.transport.send(buf);
|
||||||
console.log(buf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
httprequest(
|
httprequest(
|
||||||
data: HTTPRequestPayload
|
data: HTTPRequestPayload,
|
||||||
|
body: ReadableStream<ArrayBuffer | Uint8Array> | null
|
||||||
): Promise<{ payload: HTTPResponsePayload; body: ArrayBuffer }> {
|
): Promise<{ payload: HTTPResponsePayload; body: ArrayBuffer }> {
|
||||||
let json = JSON.stringify(data);
|
let json = JSON.stringify(data);
|
||||||
|
|
||||||
return new Promise(async (resolve) => {
|
return new Promise(async (resolve) => {
|
||||||
let seq = this.nextSeq();
|
let seq = this.nextSeq();
|
||||||
this.requestCallbacks[seq] = resolve;
|
this.requestCallbacks[seq] = resolve;
|
||||||
await this.send(seq, new Blob([json]), C2SRequestTypes.HTTPRequest);
|
await this.send(seq, C2SRequestTypes.HTTPRequestStart, new Blob([json]));
|
||||||
|
|
||||||
|
if (body) {
|
||||||
|
for await (const chunk of body) {
|
||||||
|
await this.send(
|
||||||
|
seq,
|
||||||
|
C2SRequestTypes.HTTPRequestChunk,
|
||||||
|
new Uint8Array(chunk)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await this.send(seq, C2SRequestTypes.HTTPRequestEnd);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -179,8 +194,8 @@ export class Connection {
|
||||||
|
|
||||||
this.send(
|
this.send(
|
||||||
seq,
|
seq,
|
||||||
new TextEncoder().encode(payloadJSON),
|
C2SRequestTypes.WSOpen,
|
||||||
C2SRequestTypes.WSOpen
|
new TextEncoder().encode(payloadJSON)
|
||||||
).catch((e) => {
|
).catch((e) => {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
closeWithError();
|
closeWithError();
|
||||||
|
@ -206,23 +221,23 @@ export class Connection {
|
||||||
if (typeof data === "string") {
|
if (typeof data === "string") {
|
||||||
this.send(
|
this.send(
|
||||||
seq,
|
seq,
|
||||||
new TextEncoder().encode(data),
|
C2SRequestTypes.WSSendText,
|
||||||
C2SRequestTypes.WSSendText
|
new TextEncoder().encode(data)
|
||||||
).catch(cleanup);
|
).catch(cleanup);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (data instanceof ArrayBuffer) {
|
if (data instanceof ArrayBuffer) {
|
||||||
this.send(seq, data, C2SRequestTypes.WSSendBinary).catch(cleanup);
|
this.send(seq, C2SRequestTypes.WSSendBinary, data).catch(cleanup);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (ArrayBuffer.isView(data)) {
|
if (ArrayBuffer.isView(data)) {
|
||||||
this.send(
|
this.send(
|
||||||
seq,
|
seq,
|
||||||
|
C2SRequestTypes.WSSendBinary,
|
||||||
data.buffer.slice(
|
data.buffer.slice(
|
||||||
data.byteOffset,
|
data.byteOffset,
|
||||||
data.byteOffset + data.byteLength
|
data.byteOffset + data.byteLength
|
||||||
),
|
)
|
||||||
C2SRequestTypes.WSSendBinary
|
|
||||||
).catch(cleanup);
|
).catch(cleanup);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -234,8 +249,8 @@ export class Connection {
|
||||||
const payloadJSON = JSON.stringify(payload);
|
const payloadJSON = JSON.stringify(payload);
|
||||||
this.send(
|
this.send(
|
||||||
seq,
|
seq,
|
||||||
new TextEncoder().encode(payloadJSON),
|
C2SRequestTypes.WSClose,
|
||||||
C2SRequestTypes.WSClose
|
new TextEncoder().encode(payloadJSON)
|
||||||
).catch((e) => {
|
).catch((e) => {
|
||||||
// At this point there is nothing left to clean up
|
// At this point there is nothing left to clean up
|
||||||
console.error(e);
|
console.error(e);
|
||||||
|
|
32
pnpm-lock.yaml
generated
32
pnpm-lock.yaml
generated
|
@ -1,4 +1,4 @@
|
||||||
lockfileVersion: '6.1'
|
lockfileVersion: '6.0'
|
||||||
|
|
||||||
settings:
|
settings:
|
||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
|
@ -37,6 +37,9 @@ importers:
|
||||||
chalk:
|
chalk:
|
||||||
specifier: ^5.3.0
|
specifier: ^5.3.0
|
||||||
version: 5.3.0
|
version: 5.3.0
|
||||||
|
crypto-js:
|
||||||
|
specifier: ^4.1.1
|
||||||
|
version: 4.1.1
|
||||||
domhandler:
|
domhandler:
|
||||||
specifier: ^5.0.3
|
specifier: ^5.0.3
|
||||||
version: 5.0.3
|
version: 5.0.3
|
||||||
|
@ -62,6 +65,9 @@ importers:
|
||||||
specifier: ^2.6.0
|
specifier: ^2.6.0
|
||||||
version: 2.6.0
|
version: 2.6.0
|
||||||
devDependencies:
|
devDependencies:
|
||||||
|
'@types/crypto-js':
|
||||||
|
specifier: ^4.1.1
|
||||||
|
version: 4.1.1
|
||||||
'@types/mime-db':
|
'@types/mime-db':
|
||||||
specifier: ^1.43.1
|
specifier: ^1.43.1
|
||||||
version: 1.43.1
|
version: 1.43.1
|
||||||
|
@ -81,8 +87,8 @@ importers:
|
||||||
Ultraviolet:
|
Ultraviolet:
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@tomphttp/bare-client':
|
'@tomphttp/bare-client':
|
||||||
specifier: file:../bare-client-custom/
|
specifier: ^2.2.0-alpha
|
||||||
version: file:bare-client-custom
|
version: 2.2.0-alpha
|
||||||
css-tree:
|
css-tree:
|
||||||
specifier: ^2.3.1
|
specifier: ^2.3.1
|
||||||
version: 2.3.1
|
version: 2.3.1
|
||||||
|
@ -165,11 +171,15 @@ importers:
|
||||||
protocol:
|
protocol:
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
version: link:../protocol
|
version: link:../protocol
|
||||||
|
devDependencies:
|
||||||
|
'@types/node':
|
||||||
|
specifier: ^20.4.10
|
||||||
|
version: 20.4.10
|
||||||
|
|
||||||
corium:
|
corium:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/browser':
|
'@rollup/browser':
|
||||||
specifier: ^3.28.0
|
specifier: ^3.17.2
|
||||||
version: 3.28.0
|
version: 3.28.0
|
||||||
'@swc/helpers':
|
'@swc/helpers':
|
||||||
specifier: ^0.4.14
|
specifier: ^0.4.14
|
||||||
|
@ -3562,7 +3572,6 @@ packages:
|
||||||
|
|
||||||
/@tomphttp/bare-client@2.2.0-alpha:
|
/@tomphttp/bare-client@2.2.0-alpha:
|
||||||
resolution: {integrity: sha512-xhcflOpwr92tkpp8SoDhB3nK3LHMBIjx+vgow37XobQew2k0/mXSxmaU7BsDFpOIa1CcLCEsR8gWn0v7Cy9+7Q==}
|
resolution: {integrity: sha512-xhcflOpwr92tkpp8SoDhB3nK3LHMBIjx+vgow37XobQew2k0/mXSxmaU7BsDFpOIa1CcLCEsR8gWn0v7Cy9+7Q==}
|
||||||
dev: false
|
|
||||||
|
|
||||||
/@tomphttp/bare-server-node@2.0.1:
|
/@tomphttp/bare-server-node@2.0.1:
|
||||||
resolution: {integrity: sha512-L42TC/AldYRFBRZSxhkI0FC5TL8EC/NAsepNC/cWYTTiHQJ7mGg/vdTqNz8ShTYHr6LTHYkuD3/81nhX55SYtA==}
|
resolution: {integrity: sha512-L42TC/AldYRFBRZSxhkI0FC5TL8EC/NAsepNC/cWYTTiHQJ7mGg/vdTqNz8ShTYHr6LTHYkuD3/81nhX55SYtA==}
|
||||||
|
@ -3607,6 +3616,10 @@ packages:
|
||||||
'@types/node': 20.4.10
|
'@types/node': 20.4.10
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/@types/crypto-js@4.1.1:
|
||||||
|
resolution: {integrity: sha512-BG7fQKZ689HIoc5h+6D2Dgq1fABRa0RbBWKBd9SP/MVRVXROflpm5fhwyATX5duFmbStzyzyycPB8qUYKDH3NA==}
|
||||||
|
dev: true
|
||||||
|
|
||||||
/@types/css-tree@2.0.0:
|
/@types/css-tree@2.0.0:
|
||||||
resolution: {integrity: sha512-mY2sXRLBnUPMYw6mkOT+6dABeaNxAEKZz6scE9kQPNJx8fKe1fOsm8Honl7+xFYe6TKX8WNk2+7oMp2vBArJ9Q==}
|
resolution: {integrity: sha512-mY2sXRLBnUPMYw6mkOT+6dABeaNxAEKZz6scE9kQPNJx8fKe1fOsm8Honl7+xFYe6TKX8WNk2+7oMp2vBArJ9Q==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -3760,6 +3773,7 @@ packages:
|
||||||
|
|
||||||
/@types/uuid@9.0.2:
|
/@types/uuid@9.0.2:
|
||||||
resolution: {integrity: sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==}
|
resolution: {integrity: sha512-kNnC1GFBLuhImSnV7w4njQkUiJi0ZXUycu1rUaouPqiKlXkh77JKgdRnTAp1x5eBwcIwbtI+3otwzuIDEuDoxQ==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@types/webrtc@0.0.36:
|
/@types/webrtc@0.0.36:
|
||||||
resolution: {integrity: sha512-tYFarc92EluXU7XyRmWbkQXSbZIOHTdDOudFPal9u/TNTQuouWpIHV/2o9bNAdqvTJFjLJh/zflCOLWbL30tEQ==}
|
resolution: {integrity: sha512-tYFarc92EluXU7XyRmWbkQXSbZIOHTdDOudFPal9u/TNTQuouWpIHV/2o9bNAdqvTJFjLJh/zflCOLWbL30tEQ==}
|
||||||
|
@ -5185,6 +5199,10 @@ packages:
|
||||||
shebang-command: 2.0.0
|
shebang-command: 2.0.0
|
||||||
which: 2.0.2
|
which: 2.0.2
|
||||||
|
|
||||||
|
/crypto-js@4.1.1:
|
||||||
|
resolution: {integrity: sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw==}
|
||||||
|
dev: false
|
||||||
|
|
||||||
/css-tree@2.3.1:
|
/css-tree@2.3.1:
|
||||||
resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
|
resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
|
||||||
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
|
engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
|
||||||
|
@ -10106,6 +10124,7 @@ packages:
|
||||||
/uuid@9.0.0:
|
/uuid@9.0.0:
|
||||||
resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==}
|
resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
dev: false
|
||||||
|
|
||||||
/v8-compile-cache-lib@3.0.1:
|
/v8-compile-cache-lib@3.0.1:
|
||||||
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
|
||||||
|
@ -10556,15 +10575,14 @@ packages:
|
||||||
file:bare-client-custom:
|
file:bare-client-custom:
|
||||||
resolution: {directory: bare-client-custom, type: directory}
|
resolution: {directory: bare-client-custom, type: directory}
|
||||||
name: bare-client-custom
|
name: bare-client-custom
|
||||||
version: 2.2.0-alpha
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/uuid': 9.0.2
|
'@types/uuid': 9.0.2
|
||||||
uuid: 9.0.0
|
uuid: 9.0.0
|
||||||
|
dev: false
|
||||||
|
|
||||||
file:corium:
|
file:corium:
|
||||||
resolution: {directory: corium, type: directory}
|
resolution: {directory: corium, type: directory}
|
||||||
name: corium
|
name: corium
|
||||||
version: 1.0.0-alpha.2
|
|
||||||
dependencies:
|
dependencies:
|
||||||
'@rollup/browser': 3.28.0
|
'@rollup/browser': 3.28.0
|
||||||
'@swc/helpers': 0.4.14
|
'@swc/helpers': 0.4.14
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
export type ObjectValues<T> = T[keyof T];
|
export type ObjectValues<T> = T[keyof T];
|
||||||
export const C2SRequestTypes = {
|
export const C2SRequestTypes = {
|
||||||
HTTPRequest: 0,
|
HTTPRequestStart: 0,
|
||||||
WSOpen: 1,
|
HTTPRequestChunk: 1,
|
||||||
WSClose: 2,
|
HTTPRequestEnd: 2,
|
||||||
WSSendText: 3,
|
WSOpen: 3,
|
||||||
WSSendBinary: 4,
|
WSClose: 4,
|
||||||
|
WSSendText: 5,
|
||||||
|
WSSendBinary: 6,
|
||||||
} as const;
|
} as const;
|
||||||
export type C2SRequestType = ObjectValues<typeof C2SRequestTypes>;
|
export type C2SRequestType = ObjectValues<typeof C2SRequestTypes>;
|
||||||
|
|
||||||
|
@ -13,9 +15,9 @@ export const S2CRequestTypes = {
|
||||||
HTTPResponseChunk: 1,
|
HTTPResponseChunk: 1,
|
||||||
HTTPResponseEnd: 2,
|
HTTPResponseEnd: 2,
|
||||||
WSOpen: 3,
|
WSOpen: 3,
|
||||||
WSDataText: 4,
|
WSClose: 4,
|
||||||
WSDataBinary: 5,
|
WSDataText: 5,
|
||||||
WSClose: 6,
|
WSDataBinary: 6,
|
||||||
WSError: 7,
|
WSError: 7,
|
||||||
} as const;
|
} as const;
|
||||||
export type S2CRequestType = ObjectValues<typeof S2CRequestTypes>;
|
export type S2CRequestType = ObjectValues<typeof S2CRequestTypes>;
|
||||||
|
@ -25,7 +27,6 @@ export type ProtoBareHeaders = Record<string, string | string[]>;
|
||||||
export type HTTPRequestPayload = {
|
export type HTTPRequestPayload = {
|
||||||
method: string;
|
method: string;
|
||||||
requestHeaders: ProtoBareHeaders;
|
requestHeaders: ProtoBareHeaders;
|
||||||
body: string | null;
|
|
||||||
remote: URL;
|
remote: URL;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue