Skip to content

Commit acd0e22

Browse files
committed
updates
1 parent 99429f2 commit acd0e22

File tree

3 files changed

+131
-48
lines changed

3 files changed

+131
-48
lines changed

ext/web/webtransport.js

+127-48
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
22
import { primordials } from "ext:core/mod.js";
3-
import { getLocationHref } from "ext:deno_web/12_location.js";
43
import * as webidl from "ext:deno_webidl/00_webidl.js";
54
import {
65
connectQuic,
76
webtransportAccept,
87
webtransportConnect,
98
} from "ext:deno_net/03_quic.js";
9+
import { assert } from "./00_infra.js";
10+
import { DOMException } from "./01_dom_exception.js";
1011
import {
1112
getReadableStreamResourceBacking,
1213
getWritableStreamResourceBacking,
@@ -16,7 +17,7 @@ import {
1617
WritableStreamDefaultWriter,
1718
writableStreamForRid,
1819
} from "./06_streams.js";
19-
import { assert } from "./00_infra.js";
20+
import { getLocationHref } from "./12_location.js";
2021

2122
const {
2223
ArrayBufferPrototype,
@@ -97,6 +98,7 @@ const illegalConstructorKey = Symbol("illegalConstructorKey");
9798
class WebTransport {
9899
[webidl.brand] = webidl.brand;
99100
#conn;
101+
#promise;
100102
#ready;
101103
// deno-lint-ignore prefer-primordials
102104
#closed = Promise.withResolvers();
@@ -199,12 +201,14 @@ class WebTransport {
199201
},
200202
);
201203

204+
this.#promise = promise;
202205
this.#datagrams = new WebTransportDatagramDuplexStream(
203206
illegalConstructorKey,
204207
promise,
205208
);
206-
207-
this.#ready = PromisePrototypeThen(promise, () => undefined);
209+
this.#ready = PromisePrototypeThen(promise, () => undefined, (e) => {
210+
throw new WebTransportError(e.message);
211+
});
208212
}
209213

210214
getStats() {
@@ -261,6 +265,11 @@ class WebTransport {
261265
"Failed to execute 'close' on 'WebTransport'",
262266
"Argument 1",
263267
);
268+
if (!this.#conn) {
269+
throw new WebTransportError("WebTransport is not connected", {
270+
source: "session",
271+
});
272+
}
264273
this.#conn.close({
265274
closeCode: closeInfo.closeCode,
266275
reason: closeInfo.reason,
@@ -280,7 +289,8 @@ class WebTransport {
280289
"Argument 1",
281290
);
282291

283-
const bidi = await this.#conn.createBidirectionalStream({
292+
const { conn } = await this.#promise;
293+
const bidi = await conn.createBidirectionalStream({
284294
waitUntilAvailable: options.waitUntilAvailable,
285295
});
286296

@@ -303,28 +313,34 @@ class WebTransport {
303313

304314
get incomingBidirectionalStreams() {
305315
webidl.assertBranded(this, WebTransportPrototype);
306-
307316
if (!this.#incomingBidirectionalStreams) {
308-
this.#incomingBidirectionalStreams = this.#conn
309-
.incomingBidirectionalStreams.pipeThrough(
310-
new TransformStream({
311-
transform: async (bidi, controller) => {
312-
const reader = bidi.readable.getReader({ mode: "byob" });
313-
const { value } = await reader.read(
314-
new Uint8Array(this.#headerBi.length),
317+
const readerPromise = PromisePrototypeThen(
318+
this.#promise,
319+
({ conn }) => conn.incomingBidirectionalStreams.getReader(),
320+
);
321+
this.#incomingBidirectionalStreams = new ReadableStream({
322+
pull: async (controller) => {
323+
const reader = await readerPromise;
324+
const { value: bidi, done } = await reader.read();
325+
if (done) {
326+
controller.close();
327+
} else {
328+
const reader = bidi.readable.getReader({ mode: "byob" });
329+
const { value } = await reader.read(
330+
new Uint8Array(this.#headerBi.length),
331+
);
332+
reader.releaseLock();
333+
if (value && equal(value, this.#headerBi)) {
334+
controller.enqueue(
335+
new WebTransportBidirectionalStream(
336+
illegalConstructorKey,
337+
bidi,
338+
),
315339
);
316-
reader.releaseLock();
317-
if (value && equal(value, this.#headerBi)) {
318-
controller.enqueue(
319-
new WebTransportBidirectionalStream(
320-
illegalConstructorKey,
321-
bidi,
322-
),
323-
);
324-
}
325-
},
326-
}),
327-
);
340+
}
341+
}
342+
},
343+
});
328344
}
329345
return this.#incomingBidirectionalStreams;
330346
}
@@ -337,7 +353,8 @@ class WebTransport {
337353
"Argument 1",
338354
);
339355

340-
const stream = await this.#conn.createUnidirectionalStream({
356+
const { conn } = await this.#promise;
357+
const stream = await conn.createUnidirectionalStream({
341358
waitUntilAvailable: options.waitUntilAvailable,
342359
});
343360

@@ -359,24 +376,32 @@ class WebTransport {
359376
webidl.assertBranded(this, WebTransportPrototype);
360377

361378
if (!this.#incomingUnidirectionalStreams) {
362-
this.#incomingUnidirectionalStreams = this.#conn
363-
.incomingUnidirectionalStreams.pipeThrough(
364-
new TransformStream({
365-
transform: async (stream, controller) => {
366-
const reader = stream.getReader({ mode: "byob" });
367-
const { value } = await reader.read(
368-
new Uint8Array(this.#headerUni.length),
379+
const readerPromise = PromisePrototypeThen(
380+
this.#promise,
381+
({ conn }) => conn.incomingUnidirectionalStreams.getReader(),
382+
);
383+
this.#incomingUnidirectionalStreams = new ReadableStream({
384+
pull: async (controller) => {
385+
const reader = await readerPromise;
386+
const { value: stream, done } = await reader.read();
387+
if (done) {
388+
controller.close();
389+
} else {
390+
const reader = stream.getReader({ mode: "byob" });
391+
const { value } = await reader.read(
392+
new Uint8Array(this.#headerUni.length),
393+
);
394+
reader.releaseLock();
395+
if (value && equal(value, this.#headerUni)) {
396+
controller.enqueue(
397+
readableStream(stream),
369398
);
370-
reader.releaseLock();
371-
if (value && equal(value, this.#headerUni)) {
372-
controller.enqueue(
373-
readableStream(stream),
374-
);
375-
}
376-
},
377-
}),
378-
);
399+
}
400+
}
401+
},
402+
});
379403
}
404+
380405
return this.#incomingUnidirectionalStreams;
381406
}
382407

@@ -390,7 +415,7 @@ class WebTransport {
390415
return false;
391416
}
392417
}
393-
418+
webidl.configureInterface(WebTransport);
394419
const WebTransportPrototype = WebTransport.prototype;
395420

396421
async function upgradeWebTransport(conn) {
@@ -456,7 +481,7 @@ class WebTransportBidirectionalStream {
456481
return this.#writable;
457482
}
458483
}
459-
484+
webidl.configureInterface(WebTransportBidirectionalStream);
460485
const WebTransportBidirectionalStreamPrototype =
461486
WebTransportBidirectionalStream.prototype;
462487

@@ -515,7 +540,7 @@ class WebTransportSendStream extends WritableStream {
515540
return new WebTransportWriter(this);
516541
}
517542
}
518-
543+
webidl.configureInterface(WebTransportSendStream);
519544
const WebTransportSendStreamPrototype = WebTransportSendStream.prototype;
520545

521546
class WebTransportReceiveStream extends ReadableStream {
@@ -538,14 +563,15 @@ class WebTransportReceiveStream extends ReadableStream {
538563
});
539564
}
540565
}
541-
566+
webidl.configureInterface(WebTransportReceiveStream);
542567
const WebTransportReceiveStreamPrototype = WebTransportReceiveStream.prototype;
543568

544569
class WebTransportWriter extends WritableStreamDefaultWriter {
545570
[webidl.brand] = webidl.brand;
546571

547572
// atomicWrite() {}
548573
}
574+
webidl.configureInterface(WebTransportWriter);
549575

550576
class WebTransportDatagramDuplexStream {
551577
[webidl.brand] = webidl.brand;
@@ -807,7 +833,7 @@ class WebTransportDatagramDuplexStream {
807833
return this.#writable;
808834
}
809835
}
810-
836+
webidl.configureInterface(WebTransportDatagramDuplexStream);
811837
const WebTransportDatagramDuplexStreamPrototype =
812838
WebTransportDatagramDuplexStream.prototype;
813839

@@ -827,9 +853,40 @@ class WebTransportSendGroup {
827853
});
828854
}
829855
}
830-
856+
webidl.configureInterface(WebTransportSendGroup);
831857
const WebTransportSendGroupPrototype = WebTransportSendGroup.prototype;
832858

859+
class WebTransportError extends DOMException {
860+
#source;
861+
#streamErrorCode;
862+
863+
constructor(message = "", init = { __proto__: null }) {
864+
super(message, "WebTransportError");
865+
this[webidl.brand] = webidl.brand;
866+
867+
init = webidl.converters["WebTransportErrorOptions"](
868+
init,
869+
"Failed to construct 'WebTransportError'",
870+
"Argument 2",
871+
);
872+
873+
this.#source = init.source;
874+
this.#streamErrorCode = init.streamErrorCode;
875+
}
876+
877+
get source() {
878+
webidl.assertBranded(this, WebTransportErrorPrototype);
879+
return this.#source;
880+
}
881+
882+
get streamErrorCode() {
883+
webidl.assertBranded(this, WebTransportErrorPrototype);
884+
return this.#streamErrorCode;
885+
}
886+
}
887+
webidl.configureInterface(WebTransportError);
888+
const WebTransportErrorPrototype = WebTransportError.prototype;
889+
833890
webidl.converters.WebTransportSendGroup = webidl.createInterfaceConverter(
834891
"WebTransportSendGroup",
835892
WebTransportSendGroupPrototype,
@@ -933,11 +990,33 @@ webidl.converters.WebTransportOptions = webidl
933990
},
934991
]);
935992

993+
webidl.converters.WebTransportErrorSource = webidl.createEnumConverter(
994+
"WebTransportErrorSource",
995+
["stream", "session"],
996+
);
997+
998+
webidl.converters.WebTransportErrorOptions = webidl.createDictionaryConverter(
999+
"WebTransportErrorOptions",
1000+
[
1001+
{
1002+
key: "source",
1003+
converter: webidl.converters.WebTransportErrorSource,
1004+
defaultValue: "stream",
1005+
},
1006+
{
1007+
key: "streamErrorCode",
1008+
converter: webidl.converters["unsigned long?"],
1009+
defaultValue: null,
1010+
},
1011+
],
1012+
);
1013+
9361014
export {
9371015
upgradeWebTransport,
9381016
WebTransport,
9391017
WebTransportBidirectionalStream,
9401018
WebTransportDatagramDuplexStream,
1019+
WebTransportError,
9411020
WebTransportReceiveStream,
9421021
WebTransportSendGroup,
9431022
WebTransportSendStream,

ext/webidl/00_webidl.js

+3
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,9 @@ converters["unsigned short?"] = createNullableConverter(
330330

331331
converters.long = createIntegerConversion(32, { unsigned: false });
332332
converters["unsigned long"] = createIntegerConversion(32, { unsigned: true });
333+
converters["unsigned long?"] = createNullableConverter(
334+
converters["unsigned long"],
335+
);
333336

334337
converters["long long"] = createLongLongConversion(64, { unsigned: false });
335338
converters["unsigned long long"] = createLongLongConversion(64, {

runtime/js/98_global_scope_shared.js

+1
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ unstableForWindowOrWorkerGlobalScope[unstableIds.net] = {
315315
WebTransportSendStream: core.propNonEnumerable(
316316
webtransport.WebTransportSendStream,
317317
),
318+
WebTransportError: core.propNonEnumerable(webtransport.WebTransportError),
318319
};
319320

320321
unstableForWindowOrWorkerGlobalScope[unstableIds.webgpu] = {};

0 commit comments

Comments
 (0)