@ldtr/nestjs-webtransport 0.0.2 → 0.0.3
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/index.cjs +77 -46
- package/package.json +5 -3
- package/dist/index.d.mts +0 -87
- package/dist/index.mjs +0 -423
package/dist/index.cjs
CHANGED
|
@@ -170,8 +170,21 @@ var WtStreamWO = class extends AbstractWtStream {
|
|
|
170
170
|
}
|
|
171
171
|
};
|
|
172
172
|
//#endregion
|
|
173
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/decorateMetadata.js
|
|
174
|
+
function __decorateMetadata(k, v) {
|
|
175
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
176
|
+
}
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region \0@oxc-project+runtime@0.135.0/helpers/esm/decorate.js
|
|
179
|
+
function __decorate(decorators, target, key, desc) {
|
|
180
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
181
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
182
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
183
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
184
|
+
}
|
|
185
|
+
//#endregion
|
|
173
186
|
//#region src/lib/explorers/webtransport-gateway.explorer.ts
|
|
174
|
-
|
|
187
|
+
let WebTransportGatewayExplorer = class WebTransportGatewayExplorer {
|
|
175
188
|
discoveryService;
|
|
176
189
|
constructor(discoveryService) {
|
|
177
190
|
this.discoveryService = discoveryService;
|
|
@@ -196,9 +209,10 @@ var WebTransportGatewayExplorer = @((0, _nestjs_common.Injectable)()) class {
|
|
|
196
209
|
return gatewaysByNameByPath;
|
|
197
210
|
}
|
|
198
211
|
};
|
|
212
|
+
WebTransportGatewayExplorer = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [typeof _nestjs_core.DiscoveryService === "undefined" ? Object : _nestjs_core.DiscoveryService])], WebTransportGatewayExplorer);
|
|
199
213
|
//#endregion
|
|
200
214
|
//#region src/lib/explorers/webtransport-server.explorer.ts
|
|
201
|
-
|
|
215
|
+
let WebTransportServerExplorer = class WebTransportServerExplorer {
|
|
202
216
|
discoveryService;
|
|
203
217
|
constructor(discoveryService) {
|
|
204
218
|
this.discoveryService = discoveryService;
|
|
@@ -217,45 +231,14 @@ var WebTransportServerExplorer = @((0, _nestjs_common.Injectable)()) class {
|
|
|
217
231
|
return serversByName;
|
|
218
232
|
}
|
|
219
233
|
};
|
|
220
|
-
|
|
221
|
-
//#region src/lib/bootstraps/web-transport-bootstrapper.ts
|
|
222
|
-
var WebTransportBootstrapper = @((0, _nestjs_common.Injectable)()) class WebTransportBootstrapper {
|
|
223
|
-
serverFactory;
|
|
224
|
-
webTransportExplorer;
|
|
225
|
-
logger = new _nestjs_common.Logger(WebTransportBootstrapper.name);
|
|
226
|
-
h3ServersWithInfo = [];
|
|
227
|
-
constructor(serverFactory, webTransportExplorer) {
|
|
228
|
-
this.serverFactory = serverFactory;
|
|
229
|
-
this.webTransportExplorer = webTransportExplorer;
|
|
230
|
-
}
|
|
231
|
-
async onApplicationBootstrap() {
|
|
232
|
-
const serverBindings = this.webTransportExplorer.discover();
|
|
233
|
-
this.h3ServersWithInfo = await this.serverFactory.createH3Servers(serverBindings);
|
|
234
|
-
await Promise.all(this.h3ServersWithInfo.map(async ({ options, name, h3Server }) => {
|
|
235
|
-
try {
|
|
236
|
-
h3Server.startServer();
|
|
237
|
-
await h3Server.ready;
|
|
238
|
-
this.logger.log(`WebTransport server "${name}" is ready on ${options.host}:${options.port}`);
|
|
239
|
-
} catch (e) {
|
|
240
|
-
this.logger.error(`Failed to start WebTransport server "${name}" on ${options.host}:${options.port}`);
|
|
241
|
-
throw e;
|
|
242
|
-
}
|
|
243
|
-
}));
|
|
244
|
-
}
|
|
245
|
-
async onApplicationShutdown() {
|
|
246
|
-
await Promise.all(this.h3ServersWithInfo.map(async ({ name, h3Server }) => {
|
|
247
|
-
h3Server.stopServer();
|
|
248
|
-
await h3Server.closed;
|
|
249
|
-
this.logger.log(`WebTransport server "${name}" stopped`);
|
|
250
|
-
}));
|
|
251
|
-
}
|
|
252
|
-
};
|
|
234
|
+
WebTransportServerExplorer = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [typeof _nestjs_core.DiscoveryService === "undefined" ? Object : _nestjs_core.DiscoveryService])], WebTransportServerExplorer);
|
|
253
235
|
//#endregion
|
|
254
236
|
//#region src/lib/explorers/web-transport.explorer.ts
|
|
255
|
-
var
|
|
237
|
+
var _WebTransportExplorer;
|
|
238
|
+
let WebTransportExplorer = _WebTransportExplorer = class WebTransportExplorer {
|
|
256
239
|
webTransportServerExplorer;
|
|
257
240
|
webTransportGatewayExplorer;
|
|
258
|
-
logger = new _nestjs_common.Logger(
|
|
241
|
+
logger = new _nestjs_common.Logger(_WebTransportExplorer.name);
|
|
259
242
|
constructor(webTransportServerExplorer, webTransportGatewayExplorer) {
|
|
260
243
|
this.webTransportServerExplorer = webTransportServerExplorer;
|
|
261
244
|
this.webTransportGatewayExplorer = webTransportGatewayExplorer;
|
|
@@ -276,6 +259,7 @@ var WebTransportExplorer = @((0, _nestjs_common.Injectable)()) class WebTranspor
|
|
|
276
259
|
return serverBindings;
|
|
277
260
|
}
|
|
278
261
|
};
|
|
262
|
+
WebTransportExplorer = _WebTransportExplorer = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [typeof WebTransportServerExplorer === "undefined" ? Object : WebTransportServerExplorer, typeof WebTransportGatewayExplorer === "undefined" ? Object : WebTransportGatewayExplorer])], WebTransportExplorer);
|
|
279
263
|
//#endregion
|
|
280
264
|
//#region src/lib/bootstraps/consumers/abstract-stream.consumer.ts
|
|
281
265
|
var AbstractStreamConsumer = class {
|
|
@@ -289,8 +273,9 @@ var AbstractStreamConsumer = class {
|
|
|
289
273
|
};
|
|
290
274
|
//#endregion
|
|
291
275
|
//#region src/lib/bootstraps/consumers/stream-ro.consumer.ts
|
|
292
|
-
var
|
|
293
|
-
|
|
276
|
+
var _StreamROConsumer;
|
|
277
|
+
let StreamROConsumer = _StreamROConsumer = class StreamROConsumer extends AbstractStreamConsumer {
|
|
278
|
+
logger = new _nestjs_common.Logger(_StreamROConsumer.name);
|
|
294
279
|
generateStream(session) {
|
|
295
280
|
return generateUStream(session);
|
|
296
281
|
}
|
|
@@ -301,10 +286,12 @@ var StreamROConsumer = @((0, _nestjs_common.Injectable)()) class StreamROConsume
|
|
|
301
286
|
fireAndForget(() => gateway.onStreamRO?.(stream), this.logger);
|
|
302
287
|
}
|
|
303
288
|
};
|
|
289
|
+
StreamROConsumer = _StreamROConsumer = __decorate([(0, _nestjs_common.Injectable)()], StreamROConsumer);
|
|
304
290
|
//#endregion
|
|
305
291
|
//#region src/lib/bootstraps/consumers/stream-rw.consumer.ts
|
|
306
|
-
var
|
|
307
|
-
|
|
292
|
+
var _StreamRWConsumer;
|
|
293
|
+
let StreamRWConsumer = _StreamRWConsumer = class StreamRWConsumer extends AbstractStreamConsumer {
|
|
294
|
+
logger = new _nestjs_common.Logger(_StreamRWConsumer.name);
|
|
308
295
|
generateStream(session) {
|
|
309
296
|
return generateBStream(session);
|
|
310
297
|
}
|
|
@@ -315,6 +302,7 @@ var StreamRWConsumer = @((0, _nestjs_common.Injectable)()) class StreamRWConsume
|
|
|
315
302
|
fireAndForget(() => gateway.onStreamRW?.(stream), this.logger);
|
|
316
303
|
}
|
|
317
304
|
};
|
|
305
|
+
StreamRWConsumer = _StreamRWConsumer = __decorate([(0, _nestjs_common.Injectable)()], StreamRWConsumer);
|
|
318
306
|
//#endregion
|
|
319
307
|
//#region src/lib/classes/wt-session.ts
|
|
320
308
|
var WtSession = class {
|
|
@@ -333,6 +321,7 @@ var WtSession = class {
|
|
|
333
321
|
};
|
|
334
322
|
//#endregion
|
|
335
323
|
//#region src/lib/bootstraps/server-factory.ts
|
|
324
|
+
var _ServerFactory;
|
|
336
325
|
let webtransport;
|
|
337
326
|
const getLib = eval(`import('@fails-components/webtransport')`).then((module) => {
|
|
338
327
|
webtransport = module;
|
|
@@ -349,10 +338,10 @@ function createHandshakeResponse(request, host, status) {
|
|
|
349
338
|
status
|
|
350
339
|
};
|
|
351
340
|
}
|
|
352
|
-
|
|
341
|
+
let ServerFactory = _ServerFactory = class ServerFactory {
|
|
353
342
|
streamRWConsumer;
|
|
354
343
|
streamROConsumer;
|
|
355
|
-
logger = new _nestjs_common.Logger(
|
|
344
|
+
logger = new _nestjs_common.Logger(_ServerFactory.name);
|
|
356
345
|
constructor(streamRWConsumer, streamROConsumer) {
|
|
357
346
|
this.streamRWConsumer = streamRWConsumer;
|
|
358
347
|
this.streamROConsumer = streamROConsumer;
|
|
@@ -406,9 +395,46 @@ var ServerFactory = @((0, _nestjs_common.Injectable)()) class ServerFactory {
|
|
|
406
395
|
this.streamROConsumer.consume(gateway, webTransportSession, session).catch((error) => this.logger.error(error));
|
|
407
396
|
}
|
|
408
397
|
};
|
|
398
|
+
ServerFactory = _ServerFactory = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [typeof StreamRWConsumer === "undefined" ? Object : StreamRWConsumer, typeof StreamROConsumer === "undefined" ? Object : StreamROConsumer])], ServerFactory);
|
|
399
|
+
//#endregion
|
|
400
|
+
//#region src/lib/bootstraps/web-transport-bootstrapper.ts
|
|
401
|
+
var _WebTransportBootstrapper;
|
|
402
|
+
let WebTransportBootstrapper = _WebTransportBootstrapper = class WebTransportBootstrapper {
|
|
403
|
+
serverFactory;
|
|
404
|
+
webTransportExplorer;
|
|
405
|
+
logger = new _nestjs_common.Logger(_WebTransportBootstrapper.name);
|
|
406
|
+
h3ServersWithInfo = [];
|
|
407
|
+
constructor(serverFactory, webTransportExplorer) {
|
|
408
|
+
this.serverFactory = serverFactory;
|
|
409
|
+
this.webTransportExplorer = webTransportExplorer;
|
|
410
|
+
}
|
|
411
|
+
async onApplicationBootstrap() {
|
|
412
|
+
const serverBindings = this.webTransportExplorer.discover();
|
|
413
|
+
this.h3ServersWithInfo = await this.serverFactory.createH3Servers(serverBindings);
|
|
414
|
+
await Promise.all(this.h3ServersWithInfo.map(async ({ options, name, h3Server }) => {
|
|
415
|
+
try {
|
|
416
|
+
h3Server.startServer();
|
|
417
|
+
await h3Server.ready;
|
|
418
|
+
this.logger.log(`WebTransport server "${name}" is ready on ${options.host}:${options.port}`);
|
|
419
|
+
} catch (e) {
|
|
420
|
+
this.logger.error(`Failed to start WebTransport server "${name}" on ${options.host}:${options.port}`);
|
|
421
|
+
throw e;
|
|
422
|
+
}
|
|
423
|
+
}));
|
|
424
|
+
}
|
|
425
|
+
async onApplicationShutdown() {
|
|
426
|
+
await Promise.all(this.h3ServersWithInfo.map(async ({ name, h3Server }) => {
|
|
427
|
+
h3Server.stopServer();
|
|
428
|
+
await h3Server.closed;
|
|
429
|
+
this.logger.log(`WebTransport server "${name}" stopped`);
|
|
430
|
+
}));
|
|
431
|
+
}
|
|
432
|
+
};
|
|
433
|
+
WebTransportBootstrapper = _WebTransportBootstrapper = __decorate([(0, _nestjs_common.Injectable)(), __decorateMetadata("design:paramtypes", [typeof ServerFactory === "undefined" ? Object : ServerFactory, typeof WebTransportExplorer === "undefined" ? Object : WebTransportExplorer])], WebTransportBootstrapper);
|
|
409
434
|
//#endregion
|
|
410
435
|
//#region src/lib/webtransport.module.ts
|
|
411
|
-
|
|
436
|
+
let WebTransportModule = class WebTransportModule {};
|
|
437
|
+
WebTransportModule = __decorate([(0, _nestjs_common.Module)({
|
|
412
438
|
imports: [_nestjs_core.DiscoveryModule],
|
|
413
439
|
providers: [
|
|
414
440
|
ServerFactory,
|
|
@@ -419,10 +445,15 @@ var WebTransportModule = @((0, _nestjs_common.Module)({
|
|
|
419
445
|
WebTransportServerExplorer,
|
|
420
446
|
WebTransportGatewayExplorer
|
|
421
447
|
]
|
|
422
|
-
}))
|
|
448
|
+
})], WebTransportModule);
|
|
423
449
|
//#endregion
|
|
424
450
|
exports.WebTransportGateway = WebTransportGateway;
|
|
425
|
-
exports
|
|
451
|
+
Object.defineProperty(exports, "WebTransportModule", {
|
|
452
|
+
enumerable: true,
|
|
453
|
+
get: function() {
|
|
454
|
+
return WebTransportModule;
|
|
455
|
+
}
|
|
456
|
+
});
|
|
426
457
|
exports.WebTransportServer = WebTransportServer;
|
|
427
458
|
exports.WtSession = WtSession;
|
|
428
459
|
exports.WtStreamRO = WtStreamRO;
|
package/package.json
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ldtr/nestjs-webtransport",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "NestJS module for creating WebTransport servers and gateways.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"files": [
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
7
9
|
"main": "./dist/index.cjs",
|
|
8
10
|
"types": "./dist/index.d.cts",
|
|
9
11
|
"exports": {
|
|
@@ -40,4 +42,4 @@
|
|
|
40
42
|
"module",
|
|
41
43
|
"typescript"
|
|
42
44
|
]
|
|
43
|
-
}
|
|
45
|
+
}
|
package/dist/index.d.mts
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { DiscoveryService } from "@nestjs/core";
|
|
2
|
-
import { HttpServerInit, HttpServerInit as HttpServerInit$1, WebTransportBidirectionalStream, WebTransportReceiveStream, WebTransportSendStream, WebTransportSession } from "@fails-components/webtransport";
|
|
3
|
-
|
|
4
|
-
//#region src/lib/decorators/webtransport-gateway.decorator.d.ts
|
|
5
|
-
type WebTransportGatewayOptions = {
|
|
6
|
-
readonly path: string;
|
|
7
|
-
readonly server: string;
|
|
8
|
-
};
|
|
9
|
-
declare function WebTransportGateway(options: WebTransportGatewayOptions): ClassDecorator;
|
|
10
|
-
//#endregion
|
|
11
|
-
//#region src/lib/decorators/webtransport-server.decorator.d.ts
|
|
12
|
-
interface WebTransportServerOptions {
|
|
13
|
-
readonly name: string;
|
|
14
|
-
}
|
|
15
|
-
declare function WebTransportServer(options: WebTransportServerOptions): ClassDecorator;
|
|
16
|
-
//#endregion
|
|
17
|
-
//#region src/lib/explorers/webtransport-server.explorer.d.ts
|
|
18
|
-
type WebTransportServerOptionsFactory = {
|
|
19
|
-
options(): HttpServerInit$1 | Promise<HttpServerInit$1>;
|
|
20
|
-
};
|
|
21
|
-
//#endregion
|
|
22
|
-
//#region src/lib/classes/wt-session.d.ts
|
|
23
|
-
declare class WtSession {
|
|
24
|
-
private readonly webTransportSession;
|
|
25
|
-
constructor(webTransportSession: WebTransportSession);
|
|
26
|
-
createStreamWO(): Promise<WtStreamWO>;
|
|
27
|
-
createStreamRW(): Promise<WtStreamRW>;
|
|
28
|
-
}
|
|
29
|
-
//#endregion
|
|
30
|
-
//#region src/lib/classes/wt-stream.d.ts
|
|
31
|
-
declare abstract class AbstractWtStream<TWebStream> {
|
|
32
|
-
readonly session: WtSession;
|
|
33
|
-
protected readonly webTransportStream: TWebStream;
|
|
34
|
-
protected constructor(session: WtSession, webTransportStream: TWebStream);
|
|
35
|
-
}
|
|
36
|
-
interface WtReadableStream {
|
|
37
|
-
read(): AsyncIterableIterator<Uint8Array>;
|
|
38
|
-
closeReadable(): Promise<void>;
|
|
39
|
-
}
|
|
40
|
-
interface WtWritableStream {
|
|
41
|
-
write(data: Uint8Array): Promise<void>;
|
|
42
|
-
closeWritable(): Promise<void>;
|
|
43
|
-
}
|
|
44
|
-
declare class WtStreamRW extends AbstractWtStream<WebTransportBidirectionalStream> implements WtReadableStream, WtWritableStream {
|
|
45
|
-
private readonly readableStreamHandler;
|
|
46
|
-
private readonly writableStreamHandler;
|
|
47
|
-
constructor(session: WtSession, webTransportStream: WebTransportBidirectionalStream);
|
|
48
|
-
read(): AsyncIterableIterator<Uint8Array>;
|
|
49
|
-
write(data: Uint8Array): Promise<void>;
|
|
50
|
-
closeReadable(): Promise<void>;
|
|
51
|
-
closeWritable(): Promise<void>;
|
|
52
|
-
close(): Promise<void>;
|
|
53
|
-
}
|
|
54
|
-
declare class WtStreamRO extends AbstractWtStream<WebTransportReceiveStream> implements WtReadableStream {
|
|
55
|
-
private readonly readableStreamHandler;
|
|
56
|
-
constructor(session: WtSession, webTransportStream: WebTransportReceiveStream);
|
|
57
|
-
read(): AsyncIterableIterator<Uint8Array>;
|
|
58
|
-
closeReadable(): Promise<void>;
|
|
59
|
-
}
|
|
60
|
-
declare class WtStreamWO extends AbstractWtStream<WebTransportSendStream> implements WtWritableStream {
|
|
61
|
-
private readonly writableStreamHandler;
|
|
62
|
-
constructor(session: WtSession, webTransportStream: WebTransportSendStream);
|
|
63
|
-
write(data: Uint8Array): Promise<void>;
|
|
64
|
-
closeWritable(): Promise<void>;
|
|
65
|
-
}
|
|
66
|
-
//#endregion
|
|
67
|
-
//#region src/lib/bootstraps/types.d.ts
|
|
68
|
-
type WebTransportRequestHeader = {
|
|
69
|
-
readonly ':path': string;
|
|
70
|
-
};
|
|
71
|
-
type WebTransportRequest = {
|
|
72
|
-
readonly header: WebTransportRequestHeader;
|
|
73
|
-
};
|
|
74
|
-
//#endregion
|
|
75
|
-
//#region src/lib/explorers/webtransport-gateway.explorer.d.ts
|
|
76
|
-
type WebTransportGatewayLifecycle = {
|
|
77
|
-
allowRequest?(request: WebTransportRequest): void | Promise<void>;
|
|
78
|
-
onSession?(session: WtSession): void | Promise<void>;
|
|
79
|
-
onSessionClosed?(session: WtSession): void | Promise<void>;
|
|
80
|
-
onStreamRW?(stream: WtStreamRW): void | Promise<void>;
|
|
81
|
-
onStreamRO?(stream: WtStreamRO): void | Promise<void>;
|
|
82
|
-
};
|
|
83
|
-
//#endregion
|
|
84
|
-
//#region src/lib/webtransport.module.d.ts
|
|
85
|
-
declare class WebTransportModule {}
|
|
86
|
-
//#endregion
|
|
87
|
-
export { type HttpServerInit, WebTransportGateway, type WebTransportGatewayLifecycle, type WebTransportGatewayOptions, WebTransportModule, WebTransportServer, type WebTransportServerOptions, type WebTransportServerOptionsFactory, WtSession, WtStreamRO, WtStreamRW, WtStreamWO };
|
package/dist/index.mjs
DELETED
|
@@ -1,423 +0,0 @@
|
|
|
1
|
-
import { HttpException, Injectable, Logger, Module, applyDecorators } from "@nestjs/common";
|
|
2
|
-
import { DiscoveryModule, DiscoveryService } from "@nestjs/core";
|
|
3
|
-
//#region src/lib/decorators/webtransport-gateway.decorator.ts
|
|
4
|
-
const DiscoverableWebTransportGateway = DiscoveryService.createDecorator();
|
|
5
|
-
function WebTransportGateway(options) {
|
|
6
|
-
return applyDecorators(Injectable(), DiscoverableWebTransportGateway(options));
|
|
7
|
-
}
|
|
8
|
-
//#endregion
|
|
9
|
-
//#region src/lib/decorators/webtransport-server.decorator.ts
|
|
10
|
-
const DiscoverableWebTransportServer = DiscoveryService.createDecorator();
|
|
11
|
-
function WebTransportServer(options) {
|
|
12
|
-
return applyDecorators(Injectable(), DiscoverableWebTransportServer(options));
|
|
13
|
-
}
|
|
14
|
-
//#endregion
|
|
15
|
-
//#region src/lib/bootstraps/helpers.ts
|
|
16
|
-
async function* generateSession(stream) {
|
|
17
|
-
const reader = stream.getReader();
|
|
18
|
-
try {
|
|
19
|
-
while (true) {
|
|
20
|
-
const { done, value } = await reader.read();
|
|
21
|
-
if (done) break;
|
|
22
|
-
yield value;
|
|
23
|
-
}
|
|
24
|
-
} finally {
|
|
25
|
-
reader.releaseLock();
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
async function* generateBStream(session) {
|
|
29
|
-
const reader = session.incomingBidirectionalStreams.getReader();
|
|
30
|
-
try {
|
|
31
|
-
while (true) {
|
|
32
|
-
const { done, value } = await reader.read();
|
|
33
|
-
if (done) break;
|
|
34
|
-
yield value;
|
|
35
|
-
}
|
|
36
|
-
} finally {
|
|
37
|
-
reader.releaseLock();
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
async function* generateUStream(session) {
|
|
41
|
-
const reader = session.incomingUnidirectionalStreams.getReader();
|
|
42
|
-
try {
|
|
43
|
-
while (true) {
|
|
44
|
-
const { done, value } = await reader.read();
|
|
45
|
-
if (done) break;
|
|
46
|
-
yield value;
|
|
47
|
-
}
|
|
48
|
-
} finally {
|
|
49
|
-
reader.releaseLock();
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
async function* generateChunks(reader) {
|
|
53
|
-
try {
|
|
54
|
-
while (true) {
|
|
55
|
-
const { done, value } = await reader.read();
|
|
56
|
-
if (done) break;
|
|
57
|
-
yield value;
|
|
58
|
-
}
|
|
59
|
-
} finally {
|
|
60
|
-
reader.releaseLock();
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
function fireAndForget(task, logger) {
|
|
64
|
-
if (!task) return;
|
|
65
|
-
try {
|
|
66
|
-
Promise.resolve(task()).catch((error) => {
|
|
67
|
-
logger?.error(error);
|
|
68
|
-
});
|
|
69
|
-
} catch (error) {
|
|
70
|
-
logger?.error(error);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
//#endregion
|
|
74
|
-
//#region src/lib/classes/wt-stream.ts
|
|
75
|
-
var AbstractStreamHandler = class {
|
|
76
|
-
closed = false;
|
|
77
|
-
async close() {
|
|
78
|
-
if (this.closed) return;
|
|
79
|
-
this.closed = true;
|
|
80
|
-
await this.localClose();
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
var ReadableStreamHandler = class extends AbstractStreamHandler {
|
|
84
|
-
reader;
|
|
85
|
-
chunks;
|
|
86
|
-
constructor(reader) {
|
|
87
|
-
super();
|
|
88
|
-
this.reader = reader;
|
|
89
|
-
this.chunks = generateChunks(this.reader);
|
|
90
|
-
}
|
|
91
|
-
read() {
|
|
92
|
-
if (this.closed) throw new Error("Can't read stream");
|
|
93
|
-
return this.chunks;
|
|
94
|
-
}
|
|
95
|
-
async localClose() {
|
|
96
|
-
await this.reader.cancel();
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
var WritableStreamHandler = class extends AbstractStreamHandler {
|
|
100
|
-
writer;
|
|
101
|
-
constructor(writer) {
|
|
102
|
-
super();
|
|
103
|
-
this.writer = writer;
|
|
104
|
-
}
|
|
105
|
-
async write(chunk) {
|
|
106
|
-
if (this.closed) throw new Error("Can't write stream");
|
|
107
|
-
await this.writer.write(chunk);
|
|
108
|
-
}
|
|
109
|
-
async localClose() {
|
|
110
|
-
await this.writer.close();
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
var AbstractWtStream = class {
|
|
114
|
-
session;
|
|
115
|
-
webTransportStream;
|
|
116
|
-
constructor(session, webTransportStream) {
|
|
117
|
-
this.session = session;
|
|
118
|
-
this.webTransportStream = webTransportStream;
|
|
119
|
-
}
|
|
120
|
-
};
|
|
121
|
-
var WtStreamRW = class extends AbstractWtStream {
|
|
122
|
-
readableStreamHandler;
|
|
123
|
-
writableStreamHandler;
|
|
124
|
-
constructor(session, webTransportStream) {
|
|
125
|
-
super(session, webTransportStream);
|
|
126
|
-
this.readableStreamHandler = new ReadableStreamHandler(webTransportStream.readable.getReader());
|
|
127
|
-
this.writableStreamHandler = new WritableStreamHandler(webTransportStream.writable.getWriter());
|
|
128
|
-
}
|
|
129
|
-
read() {
|
|
130
|
-
return this.readableStreamHandler.read();
|
|
131
|
-
}
|
|
132
|
-
async write(data) {
|
|
133
|
-
await this.writableStreamHandler.write(data);
|
|
134
|
-
}
|
|
135
|
-
async closeReadable() {
|
|
136
|
-
await this.readableStreamHandler.close();
|
|
137
|
-
}
|
|
138
|
-
async closeWritable() {
|
|
139
|
-
await this.writableStreamHandler.close();
|
|
140
|
-
}
|
|
141
|
-
async close() {
|
|
142
|
-
await Promise.all([this.closeReadable(), this.closeWritable()]);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
var WtStreamRO = class extends AbstractWtStream {
|
|
146
|
-
readableStreamHandler;
|
|
147
|
-
constructor(session, webTransportStream) {
|
|
148
|
-
super(session, webTransportStream);
|
|
149
|
-
this.readableStreamHandler = new ReadableStreamHandler(webTransportStream.getReader());
|
|
150
|
-
}
|
|
151
|
-
read() {
|
|
152
|
-
return this.readableStreamHandler.read();
|
|
153
|
-
}
|
|
154
|
-
async closeReadable() {
|
|
155
|
-
await this.readableStreamHandler.close();
|
|
156
|
-
}
|
|
157
|
-
};
|
|
158
|
-
var WtStreamWO = class extends AbstractWtStream {
|
|
159
|
-
writableStreamHandler;
|
|
160
|
-
constructor(session, webTransportStream) {
|
|
161
|
-
super(session, webTransportStream);
|
|
162
|
-
this.writableStreamHandler = new WritableStreamHandler(webTransportStream.getWriter());
|
|
163
|
-
}
|
|
164
|
-
async write(data) {
|
|
165
|
-
await this.writableStreamHandler.write(data);
|
|
166
|
-
}
|
|
167
|
-
async closeWritable() {
|
|
168
|
-
await this.writableStreamHandler.close();
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
//#endregion
|
|
172
|
-
//#region src/lib/explorers/webtransport-gateway.explorer.ts
|
|
173
|
-
var WebTransportGatewayExplorer = @Injectable() class {
|
|
174
|
-
discoveryService;
|
|
175
|
-
constructor(discoveryService) {
|
|
176
|
-
this.discoveryService = discoveryService;
|
|
177
|
-
}
|
|
178
|
-
discover(serverNames) {
|
|
179
|
-
const gatewaysByNameByPath = /* @__PURE__ */ new Map();
|
|
180
|
-
const wrappers = this.discoveryService.getProviders({ metadataKey: DiscoverableWebTransportGateway.KEY });
|
|
181
|
-
for (const wrapper of wrappers) {
|
|
182
|
-
const metadata = this.discoveryService.getMetadataByDecorator(DiscoverableWebTransportGateway, wrapper);
|
|
183
|
-
if (!metadata || !wrapper.metatype) continue;
|
|
184
|
-
const { server } = metadata;
|
|
185
|
-
let { path } = metadata;
|
|
186
|
-
if (!path.startsWith("/")) path = "/" + path;
|
|
187
|
-
const gateway = wrapper.instance;
|
|
188
|
-
if (!gatewaysByNameByPath.has(server)) {
|
|
189
|
-
if (!serverNames.includes(server)) throw new Error(`@WebTransportGateway() server name doesn't exist: ${server}`);
|
|
190
|
-
gatewaysByNameByPath.set(server, /* @__PURE__ */ new Map());
|
|
191
|
-
}
|
|
192
|
-
if (gatewaysByNameByPath.get(server).has(path)) throw new Error(`Duplicate @WebTransportGateway() path: ${path}`);
|
|
193
|
-
gatewaysByNameByPath.get(server).set(path, gateway);
|
|
194
|
-
}
|
|
195
|
-
return gatewaysByNameByPath;
|
|
196
|
-
}
|
|
197
|
-
};
|
|
198
|
-
//#endregion
|
|
199
|
-
//#region src/lib/explorers/webtransport-server.explorer.ts
|
|
200
|
-
var WebTransportServerExplorer = @Injectable() class {
|
|
201
|
-
discoveryService;
|
|
202
|
-
constructor(discoveryService) {
|
|
203
|
-
this.discoveryService = discoveryService;
|
|
204
|
-
}
|
|
205
|
-
discover() {
|
|
206
|
-
const serversByName = /* @__PURE__ */ new Map();
|
|
207
|
-
const wrappers = this.discoveryService.getProviders({ metadataKey: DiscoverableWebTransportServer.KEY });
|
|
208
|
-
for (const wrapper of wrappers) {
|
|
209
|
-
const metadata = this.discoveryService.getMetadataByDecorator(DiscoverableWebTransportServer, wrapper);
|
|
210
|
-
if (!metadata || !wrapper.metatype) continue;
|
|
211
|
-
const { name } = metadata;
|
|
212
|
-
if (serversByName.has(name)) throw new Error(`Duplicate @WebTransportServer() name: ${name}`);
|
|
213
|
-
const server = wrapper.instance;
|
|
214
|
-
serversByName.set(name, server);
|
|
215
|
-
}
|
|
216
|
-
return serversByName;
|
|
217
|
-
}
|
|
218
|
-
};
|
|
219
|
-
//#endregion
|
|
220
|
-
//#region src/lib/bootstraps/web-transport-bootstrapper.ts
|
|
221
|
-
var WebTransportBootstrapper = @Injectable() class WebTransportBootstrapper {
|
|
222
|
-
serverFactory;
|
|
223
|
-
webTransportExplorer;
|
|
224
|
-
logger = new Logger(WebTransportBootstrapper.name);
|
|
225
|
-
h3ServersWithInfo = [];
|
|
226
|
-
constructor(serverFactory, webTransportExplorer) {
|
|
227
|
-
this.serverFactory = serverFactory;
|
|
228
|
-
this.webTransportExplorer = webTransportExplorer;
|
|
229
|
-
}
|
|
230
|
-
async onApplicationBootstrap() {
|
|
231
|
-
const serverBindings = this.webTransportExplorer.discover();
|
|
232
|
-
this.h3ServersWithInfo = await this.serverFactory.createH3Servers(serverBindings);
|
|
233
|
-
await Promise.all(this.h3ServersWithInfo.map(async ({ options, name, h3Server }) => {
|
|
234
|
-
try {
|
|
235
|
-
h3Server.startServer();
|
|
236
|
-
await h3Server.ready;
|
|
237
|
-
this.logger.log(`WebTransport server "${name}" is ready on ${options.host}:${options.port}`);
|
|
238
|
-
} catch (e) {
|
|
239
|
-
this.logger.error(`Failed to start WebTransport server "${name}" on ${options.host}:${options.port}`);
|
|
240
|
-
throw e;
|
|
241
|
-
}
|
|
242
|
-
}));
|
|
243
|
-
}
|
|
244
|
-
async onApplicationShutdown() {
|
|
245
|
-
await Promise.all(this.h3ServersWithInfo.map(async ({ name, h3Server }) => {
|
|
246
|
-
h3Server.stopServer();
|
|
247
|
-
await h3Server.closed;
|
|
248
|
-
this.logger.log(`WebTransport server "${name}" stopped`);
|
|
249
|
-
}));
|
|
250
|
-
}
|
|
251
|
-
};
|
|
252
|
-
//#endregion
|
|
253
|
-
//#region src/lib/explorers/web-transport.explorer.ts
|
|
254
|
-
var WebTransportExplorer = @Injectable() class WebTransportExplorer {
|
|
255
|
-
webTransportServerExplorer;
|
|
256
|
-
webTransportGatewayExplorer;
|
|
257
|
-
logger = new Logger(WebTransportExplorer.name);
|
|
258
|
-
constructor(webTransportServerExplorer, webTransportGatewayExplorer) {
|
|
259
|
-
this.webTransportServerExplorer = webTransportServerExplorer;
|
|
260
|
-
this.webTransportGatewayExplorer = webTransportGatewayExplorer;
|
|
261
|
-
}
|
|
262
|
-
discover() {
|
|
263
|
-
const serversByName = this.webTransportServerExplorer.discover();
|
|
264
|
-
const gatewaysByNameByPath = this.webTransportGatewayExplorer.discover(Array.from(serversByName.keys()));
|
|
265
|
-
const serverBindings = [];
|
|
266
|
-
serversByName.forEach((server, name) => {
|
|
267
|
-
const gatewaysByPath = gatewaysByNameByPath.get(name);
|
|
268
|
-
if (gatewaysByPath === void 0) this.logger.warn(`WebTransport server "${name}" has no gateways, skipping`);
|
|
269
|
-
else serverBindings.push({
|
|
270
|
-
server,
|
|
271
|
-
name,
|
|
272
|
-
gatewaysByPath
|
|
273
|
-
});
|
|
274
|
-
});
|
|
275
|
-
return serverBindings;
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
|
-
//#endregion
|
|
279
|
-
//#region src/lib/bootstraps/consumers/abstract-stream.consumer.ts
|
|
280
|
-
var AbstractStreamConsumer = class {
|
|
281
|
-
async consume(gateway, webTransportSession, session) {
|
|
282
|
-
for await (const webTransportStream of this.generateStream(webTransportSession)) this.handleStream(gateway, session, webTransportStream);
|
|
283
|
-
}
|
|
284
|
-
handleStream(gateway, session, webTransportStream) {
|
|
285
|
-
const stream = this.createStream(session, webTransportStream);
|
|
286
|
-
this.consumeHook(gateway, stream);
|
|
287
|
-
}
|
|
288
|
-
};
|
|
289
|
-
//#endregion
|
|
290
|
-
//#region src/lib/bootstraps/consumers/stream-ro.consumer.ts
|
|
291
|
-
var StreamROConsumer = @Injectable() class StreamROConsumer extends AbstractStreamConsumer {
|
|
292
|
-
logger = new Logger(StreamROConsumer.name);
|
|
293
|
-
generateStream(session) {
|
|
294
|
-
return generateUStream(session);
|
|
295
|
-
}
|
|
296
|
-
createStream(session, webTransportStream) {
|
|
297
|
-
return new WtStreamRO(session, webTransportStream);
|
|
298
|
-
}
|
|
299
|
-
consumeHook(gateway, stream) {
|
|
300
|
-
fireAndForget(() => gateway.onStreamRO?.(stream), this.logger);
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
//#endregion
|
|
304
|
-
//#region src/lib/bootstraps/consumers/stream-rw.consumer.ts
|
|
305
|
-
var StreamRWConsumer = @Injectable() class StreamRWConsumer extends AbstractStreamConsumer {
|
|
306
|
-
logger = new Logger(StreamRWConsumer.name);
|
|
307
|
-
generateStream(session) {
|
|
308
|
-
return generateBStream(session);
|
|
309
|
-
}
|
|
310
|
-
createStream(session, webTransportStream) {
|
|
311
|
-
return new WtStreamRW(session, webTransportStream);
|
|
312
|
-
}
|
|
313
|
-
consumeHook(gateway, stream) {
|
|
314
|
-
fireAndForget(() => gateway.onStreamRW?.(stream), this.logger);
|
|
315
|
-
}
|
|
316
|
-
};
|
|
317
|
-
//#endregion
|
|
318
|
-
//#region src/lib/classes/wt-session.ts
|
|
319
|
-
var WtSession = class {
|
|
320
|
-
webTransportSession;
|
|
321
|
-
constructor(webTransportSession) {
|
|
322
|
-
this.webTransportSession = webTransportSession;
|
|
323
|
-
}
|
|
324
|
-
async createStreamWO() {
|
|
325
|
-
const stream = await this.webTransportSession.createUnidirectionalStream();
|
|
326
|
-
return new WtStreamWO(this, stream);
|
|
327
|
-
}
|
|
328
|
-
async createStreamRW() {
|
|
329
|
-
const stream = await this.webTransportSession.createBidirectionalStream();
|
|
330
|
-
return new WtStreamRW(this, stream);
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
//#endregion
|
|
334
|
-
//#region src/lib/bootstraps/server-factory.ts
|
|
335
|
-
let webtransport;
|
|
336
|
-
const getLib = eval(`import('@fails-components/webtransport')`).then((module) => {
|
|
337
|
-
webtransport = module;
|
|
338
|
-
});
|
|
339
|
-
function createHandshakeResponse(request, host, status) {
|
|
340
|
-
const url = new URL(request.header[":path"], `https://${host}`);
|
|
341
|
-
return {
|
|
342
|
-
...request,
|
|
343
|
-
path: url.pathname,
|
|
344
|
-
header: {
|
|
345
|
-
...request.header,
|
|
346
|
-
":path": url.pathname
|
|
347
|
-
},
|
|
348
|
-
status
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
var ServerFactory = @Injectable() class ServerFactory {
|
|
352
|
-
streamRWConsumer;
|
|
353
|
-
streamROConsumer;
|
|
354
|
-
logger = new Logger(ServerFactory.name);
|
|
355
|
-
constructor(streamRWConsumer, streamROConsumer) {
|
|
356
|
-
this.streamRWConsumer = streamRWConsumer;
|
|
357
|
-
this.streamROConsumer = streamROConsumer;
|
|
358
|
-
}
|
|
359
|
-
async createH3Servers(serverBindings) {
|
|
360
|
-
await getLib;
|
|
361
|
-
const h3ServersWithInfo = [];
|
|
362
|
-
for (const { server, name, gatewaysByPath } of serverBindings) {
|
|
363
|
-
const options = await server.options();
|
|
364
|
-
const h3Server = this.createH3Server(options, gatewaysByPath);
|
|
365
|
-
h3ServersWithInfo.push({
|
|
366
|
-
options,
|
|
367
|
-
h3Server,
|
|
368
|
-
name
|
|
369
|
-
});
|
|
370
|
-
}
|
|
371
|
-
return h3ServersWithInfo;
|
|
372
|
-
}
|
|
373
|
-
createH3Server(options, gatewaysByPath) {
|
|
374
|
-
const h3Server = new webtransport.Http3Server(options);
|
|
375
|
-
h3Server.setRequestCallback(async (request) => {
|
|
376
|
-
const status = await this.getRequestStatus(request, gatewaysByPath);
|
|
377
|
-
return createHandshakeResponse(request, options.host, status);
|
|
378
|
-
});
|
|
379
|
-
for (const [path, gateway] of gatewaysByPath.entries()) this.consumeSession(gateway, h3Server, path).catch((error) => this.logger.error(error));
|
|
380
|
-
return h3Server;
|
|
381
|
-
}
|
|
382
|
-
async getRequestStatus(request, gatewaysByPath) {
|
|
383
|
-
const { pathname } = new URL(request.header[":path"], "https://0.0.0.0");
|
|
384
|
-
const gateway = gatewaysByPath.get(pathname);
|
|
385
|
-
if (gateway === void 0) return 404;
|
|
386
|
-
try {
|
|
387
|
-
await gateway.allowRequest?.(request);
|
|
388
|
-
return 200;
|
|
389
|
-
} catch (e) {
|
|
390
|
-
if (e instanceof HttpException) return e.getStatus();
|
|
391
|
-
return 400;
|
|
392
|
-
}
|
|
393
|
-
}
|
|
394
|
-
async consumeSession(gateway, h3Server, path) {
|
|
395
|
-
const stream = h3Server.sessionStream(path);
|
|
396
|
-
for await (const session of generateSession(stream)) this.handleSession(gateway, session);
|
|
397
|
-
}
|
|
398
|
-
handleSession(gateway, webTransportSession) {
|
|
399
|
-
const session = new WtSession(webTransportSession);
|
|
400
|
-
fireAndForget(() => gateway.onSession?.(session), this.logger);
|
|
401
|
-
webTransportSession.closed.catch((error) => this.logger.error(error)).finally(() => {
|
|
402
|
-
fireAndForget(() => gateway.onSessionClosed?.(session), this.logger);
|
|
403
|
-
});
|
|
404
|
-
this.streamRWConsumer.consume(gateway, webTransportSession, session).catch((error) => this.logger.error(error));
|
|
405
|
-
this.streamROConsumer.consume(gateway, webTransportSession, session).catch((error) => this.logger.error(error));
|
|
406
|
-
}
|
|
407
|
-
};
|
|
408
|
-
//#endregion
|
|
409
|
-
//#region src/lib/webtransport.module.ts
|
|
410
|
-
var WebTransportModule = @Module({
|
|
411
|
-
imports: [DiscoveryModule],
|
|
412
|
-
providers: [
|
|
413
|
-
ServerFactory,
|
|
414
|
-
StreamRWConsumer,
|
|
415
|
-
StreamROConsumer,
|
|
416
|
-
WebTransportExplorer,
|
|
417
|
-
WebTransportBootstrapper,
|
|
418
|
-
WebTransportServerExplorer,
|
|
419
|
-
WebTransportGatewayExplorer
|
|
420
|
-
]
|
|
421
|
-
}) class {};
|
|
422
|
-
//#endregion
|
|
423
|
-
export { WebTransportGateway, WebTransportModule, WebTransportServer, WtSession, WtStreamRO, WtStreamRW, WtStreamWO };
|