interface WebTransportCloseInfo {
  closeCode?: number;
  reason?: string;
}

interface WebTransportErrorOptions {
  source?: WebTransportErrorSource;
  streamErrorCode?: number | null;
}

interface WebTransportHash {
  algorithm?: string;
  value?: BufferSource;
}

interface WebTransportOptions {
  allowPooling?: boolean;
  congestionControl?: WebTransportCongestionControl;
  requireUnreliable?: boolean;
  serverCertificateHashes?: WebTransportHash[];
}

interface WebTransportSendStreamOptions {
  sendOrder?: number;
}

/**
* Available only in secure contexts.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport)
*/
interface WebTransport {
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/closed) */
  readonly closed: Promise<WebTransportCloseInfo>;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/datagrams) */
  readonly datagrams: WebTransportDatagramDuplexStream;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/incomingBidirectionalStreams) */
  readonly incomingBidirectionalStreams: ReadableStream;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/incomingUnidirectionalStreams) */
  readonly incomingUnidirectionalStreams: ReadableStream;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/ready) */
  readonly ready: Promise<undefined>;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/close) */
  close(closeInfo?: WebTransportCloseInfo): void;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/createBidirectionalStream) */
  createBidirectionalStream(options?: WebTransportSendStreamOptions): Promise<WebTransportBidirectionalStream>;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransport/createUnidirectionalStream) */
  createUnidirectionalStream(options?: WebTransportSendStreamOptions): Promise<WritableStream>;
}

declare var WebTransport: {
  prototype: WebTransport;
  new(url: string | URL, options?: WebTransportOptions): WebTransport;
};

/**
* Available only in secure contexts.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream)
*/
interface WebTransportBidirectionalStream {
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream/readable) */
  readonly readable: ReadableStream;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportBidirectionalStream/writable) */
  readonly writable: WritableStream;
}

declare var WebTransportBidirectionalStream: {
  prototype: WebTransportBidirectionalStream;
  new(): WebTransportBidirectionalStream;
};

/**
* Available only in secure contexts.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream)
*/
interface WebTransportDatagramDuplexStream {
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/incomingHighWaterMark) */
  incomingHighWaterMark: number;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/incomingMaxAge) */
  incomingMaxAge: number | null;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/maxDatagramSize) */
  readonly maxDatagramSize: number;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/outgoingHighWaterMark) */
  outgoingHighWaterMark: number;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/outgoingMaxAge) */
  outgoingMaxAge: number | null;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/readable) */
  readonly readable: ReadableStream;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportDatagramDuplexStream/writable) */
  readonly writable: WritableStream;
}

declare var WebTransportDatagramDuplexStream: {
  prototype: WebTransportDatagramDuplexStream;
  new(): WebTransportDatagramDuplexStream;
};

/**
* Available only in secure contexts.
*
* [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError)
*/
interface WebTransportError extends DOMException {
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError/source) */
  readonly source: WebTransportErrorSource;
  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/WebTransportError/streamErrorCode) */
  readonly streamErrorCode: number | null;
}

declare var WebTransportError: {
  prototype: WebTransportError;
  new(message?: string, options?: WebTransportErrorOptions): WebTransportError;
};

type WebTransportCongestionControl = "default" | "low-latency" | "throughput";
type WebTransportErrorSource = "session" | "stream";
