@nmtjs/gateway 0.15.0-beta.3 → 0.15.0-beta.5

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.
@@ -0,0 +1,88 @@
1
+ import type { Readable } from 'node:stream'
2
+
3
+ import type {
4
+ ProtocolBlobInterface,
5
+ ProtocolBlobMetadata,
6
+ } from '@nmtjs/protocol'
7
+ import { anyAbortSignal } from '@nmtjs/common'
8
+ import {
9
+ createFactoryInjectable,
10
+ createLazyInjectable,
11
+ createOptionalInjectable,
12
+ Scope,
13
+ } from '@nmtjs/core'
14
+
15
+ import type { GatewayConnection } from './connections.ts'
16
+
17
+ export const connection = createLazyInjectable<
18
+ GatewayConnection,
19
+ Scope.Connection
20
+ >(Scope.Connection, 'Gateway connection')
21
+
22
+ export const connectionId = createLazyInjectable<
23
+ GatewayConnection['id'],
24
+ Scope.Connection
25
+ >(Scope.Connection, 'Gateway connection id')
26
+
27
+ export const connectionData = createLazyInjectable<unknown, Scope.Connection>(
28
+ Scope.Connection,
29
+ "Gateway connection's data",
30
+ )
31
+
32
+ export const connectionAbortSignal = createLazyInjectable<
33
+ AbortSignal,
34
+ Scope.Connection
35
+ >(Scope.Connection, 'Connection abort signal')
36
+
37
+ export const rpcClientAbortSignal = createLazyInjectable<
38
+ AbortSignal,
39
+ Scope.Call
40
+ >(Scope.Call, 'RPC client abort signal')
41
+
42
+ export const rpcStreamAbortSignal = createLazyInjectable<
43
+ AbortSignal,
44
+ Scope.Call
45
+ >(Scope.Call, 'RPC stream abort signal')
46
+
47
+ export const rpcAbortSignal = createFactoryInjectable(
48
+ {
49
+ dependencies: {
50
+ rpcClientAbortSignal,
51
+ connectionAbortSignal,
52
+ rpcStreamAbortSignal: createOptionalInjectable(rpcStreamAbortSignal),
53
+ },
54
+ factory: (ctx) =>
55
+ anyAbortSignal(
56
+ ctx.rpcClientAbortSignal,
57
+ ctx.connectionAbortSignal,
58
+ ctx.rpcStreamAbortSignal,
59
+ ),
60
+ },
61
+ 'Any RPC abort signal',
62
+ )
63
+
64
+ export const createBlob = createLazyInjectable<
65
+ (
66
+ source:
67
+ | Readable
68
+ | globalThis.ReadableStream
69
+ | File
70
+ | Blob
71
+ | string
72
+ | ArrayBuffer
73
+ | Uint8Array,
74
+ metadata?: ProtocolBlobMetadata,
75
+ ) => ProtocolBlobInterface,
76
+ Scope.Call
77
+ >(Scope.Call, 'Create RPC blob')
78
+
79
+ export const GatewayInjectables = {
80
+ connection,
81
+ connectionId,
82
+ connectionData,
83
+ connectionAbortSignal,
84
+ rpcClientAbortSignal,
85
+ rpcStreamAbortSignal,
86
+ rpcAbortSignal,
87
+ createBlob,
88
+ }
package/src/rpcs.ts ADDED
@@ -0,0 +1,90 @@
1
+ import type { Future } from '@nmtjs/common'
2
+ import { createFuture } from '@nmtjs/common'
3
+
4
+ export class RpcManager {
5
+ // connectionId:callId -> AbortController
6
+ readonly rpcs = new Map<string, AbortController>()
7
+ // connectionId:callId -> Future<void>
8
+ readonly streams = new Map<string, Future<void>>()
9
+
10
+ set(connectionId: string, callId: number, controller: AbortController) {
11
+ const key = this.getKey(connectionId, callId)
12
+ this.rpcs.set(key, controller)
13
+ }
14
+
15
+ get(connectionId: string, callId: number) {
16
+ const key = this.getKey(connectionId, callId)
17
+ return this.rpcs.get(key)
18
+ }
19
+
20
+ delete(connectionId: string, callId: number) {
21
+ const key = this.getKey(connectionId, callId)
22
+ this.rpcs.delete(key)
23
+ }
24
+
25
+ abort(connectionId: string, callId: number) {
26
+ const key = this.getKey(connectionId, callId)
27
+ const controller = this.rpcs.get(key)
28
+ if (controller) {
29
+ controller.abort()
30
+ this.rpcs.delete(key)
31
+ this.releasePull(connectionId, callId)
32
+ }
33
+ }
34
+
35
+ awaitPull(
36
+ connectionId: string,
37
+ callId: number,
38
+ signal?: AbortSignal,
39
+ ): Promise<void> {
40
+ const key = this.getKey(connectionId, callId)
41
+ const rpc = this.rpcs.get(key)
42
+ if (!rpc) throw new Error(`RPC not found`)
43
+ const future = this.streams.get(key)
44
+ if (future) {
45
+ return future.promise
46
+ } else {
47
+ const newFuture = createFuture<void>()
48
+ if (signal)
49
+ signal.addEventListener('abort', () => newFuture.resolve(), {
50
+ once: true,
51
+ })
52
+ this.streams.set(key, newFuture)
53
+ return newFuture.promise
54
+ }
55
+ }
56
+
57
+ releasePull(connectionId: string, callId: number) {
58
+ const key = this.getKey(connectionId, callId)
59
+ const future = this.streams.get(key)
60
+ if (future) {
61
+ future.resolve()
62
+ this.streams.delete(key)
63
+ }
64
+ }
65
+
66
+ close(connectionId: string) {
67
+ // Iterate all RPCs and abort those belonging to this connection
68
+ // Optimization: Maintain a Set<callId> per connectionId
69
+ for (const [key, controller] of this.rpcs) {
70
+ if (key.startsWith(`${connectionId}:`)) {
71
+ controller.abort()
72
+ this.rpcs.delete(key)
73
+ }
74
+ }
75
+ // Also release any pending pulls for this connection
76
+ for (const key of this.streams.keys()) {
77
+ if (key.startsWith(`${connectionId}:`)) {
78
+ const future = this.streams.get(key)
79
+ if (future) {
80
+ future.resolve()
81
+ this.streams.delete(key)
82
+ }
83
+ }
84
+ }
85
+ }
86
+
87
+ private getKey(connectionId: string, callId: number) {
88
+ return `${connectionId}:${callId}`
89
+ }
90
+ }
package/src/streams.ts ADDED
@@ -0,0 +1,408 @@
1
+ import type Stream from 'node:stream'
2
+
3
+ import type {
4
+ EncodeRPCStreams,
5
+ ProtocolBlob,
6
+ ProtocolBlobMetadata,
7
+ } from '@nmtjs/protocol'
8
+ import type { ProtocolRPCEncode } from '@nmtjs/protocol/client'
9
+ import { noopFn } from '@nmtjs/common'
10
+ import {
11
+ ProtocolClientStream,
12
+ ProtocolServerStream,
13
+ } from '@nmtjs/protocol/server'
14
+
15
+ import { StreamTimeout } from './enums.ts'
16
+
17
+ export type StreamConfig = {
18
+ timeouts: {
19
+ [StreamTimeout.Pull]: number
20
+ [StreamTimeout.Consume]: number
21
+ [StreamTimeout.Finish]: number
22
+ }
23
+ }
24
+
25
+ type StreamTimeouts = Record<StreamTimeout, any>
26
+
27
+ type ClientStreamState = {
28
+ connectionId: string
29
+ callId: number
30
+ stream: ProtocolClientStream
31
+ timeouts: StreamTimeouts
32
+ }
33
+
34
+ type ServerStreamState = {
35
+ connectionId: string
36
+ callId: number
37
+ stream: ProtocolServerStream
38
+ timeouts: StreamTimeouts
39
+ }
40
+
41
+ type StreamState = ClientStreamState | ServerStreamState
42
+
43
+ /**
44
+ * @todo Clarify Pull/Consume timeout semantics - currently ambiguous whether
45
+ * Pull timeout means "client not pulling" or "server not producing" for server streams
46
+ */
47
+ export class BlobStreamsManager {
48
+ readonly clientStreams = new Map<string, ClientStreamState>()
49
+ readonly serverStreams = new Map<string, ServerStreamState>()
50
+
51
+ // Index for quick lookup by callId (connectionId:callId -> Set<streamId>)
52
+ readonly connectionClientStreams = new Map<string, Set<number>>()
53
+ readonly connectionServerStreams = new Map<string, Set<number>>()
54
+ readonly clientCallStreams = new Map<string, Set<number>>()
55
+ readonly serverCallStreams = new Map<string, Set<number>>()
56
+
57
+ readonly timeoutDurations: Record<StreamTimeout, number>
58
+
59
+ constructor(config: StreamConfig) {
60
+ this.timeoutDurations = {
61
+ [StreamTimeout.Pull]: config.timeouts[StreamTimeout.Pull],
62
+ [StreamTimeout.Consume]: config.timeouts[StreamTimeout.Consume],
63
+ [StreamTimeout.Finish]: config.timeouts[StreamTimeout.Finish],
64
+ }
65
+ }
66
+
67
+ // --- Client Streams (Upload) ---
68
+
69
+ createClientStream(
70
+ connectionId: string,
71
+ callId: number,
72
+ streamId: number,
73
+ metadata: ProtocolBlobMetadata,
74
+ options: Stream.ReadableOptions,
75
+ ) {
76
+ const stream = new ProtocolClientStream(streamId, metadata, options)
77
+ stream.on('error', noopFn)
78
+
79
+ const key = this.getKey(connectionId, streamId)
80
+ const state: ClientStreamState = {
81
+ connectionId,
82
+ callId,
83
+ stream,
84
+ timeouts: {
85
+ [StreamTimeout.Pull]: undefined,
86
+ [StreamTimeout.Consume]: undefined,
87
+ [StreamTimeout.Finish]: undefined,
88
+ },
89
+ }
90
+ this.clientStreams.set(key, state)
91
+ this.trackClientCall(connectionId, callId, streamId)
92
+ this.trackConnectionClientStream(connectionId, streamId)
93
+
94
+ this.startTimeout(state, StreamTimeout.Consume)
95
+
96
+ return stream
97
+ }
98
+
99
+ pushToClientStream(
100
+ connectionId: string,
101
+ streamId: number,
102
+ chunk: ArrayBufferView,
103
+ ) {
104
+ const key = this.getKey(connectionId, streamId)
105
+ const state = this.clientStreams.get(key)
106
+ if (state) {
107
+ state.stream.write(chunk)
108
+ this.clearTimeout(state, StreamTimeout.Consume)
109
+ this.startTimeout(state, StreamTimeout.Pull)
110
+ }
111
+ }
112
+
113
+ endClientStream(connectionId: string, streamId: number) {
114
+ const key = this.getKey(connectionId, streamId)
115
+ const state = this.clientStreams.get(key)
116
+ if (state) {
117
+ state.stream.end(null)
118
+ this.removeClientStream(connectionId, streamId)
119
+ }
120
+ }
121
+
122
+ abortClientStream(connectionId: string, streamId: number, error = 'Aborted') {
123
+ const key = this.getKey(connectionId, streamId)
124
+ const state = this.clientStreams.get(key)
125
+ if (state) {
126
+ state.stream.destroy(new Error(error))
127
+ this.removeClientStream(connectionId, streamId)
128
+ }
129
+ }
130
+
131
+ consumeClientStream(connectionId: string, callId: number, streamId: number) {
132
+ this.untrackClientCall(connectionId, callId, streamId)
133
+ }
134
+
135
+ private removeClientStream(connectionId: string, streamId: number) {
136
+ const key = this.getKey(connectionId, streamId)
137
+ const state = this.clientStreams.get(key)
138
+ if (state) {
139
+ this.clientStreams.delete(key)
140
+ this.clearTimeout(state, StreamTimeout.Finish)
141
+ this.clearTimeout(state, StreamTimeout.Pull)
142
+ this.clearTimeout(state, StreamTimeout.Consume)
143
+ this.untrackClientCall(connectionId, state.callId, streamId)
144
+ this.untrackConnectionClientStream(connectionId, streamId)
145
+ }
146
+ }
147
+
148
+ // --- Server Streams (Download) ---
149
+
150
+ getServerStreamsMetadata(connectionId: string, callId: number) {
151
+ const key = this.getCallKey(connectionId, callId)
152
+ const streamIds = this.serverCallStreams.get(key)
153
+ const streams: EncodeRPCStreams = {}
154
+
155
+ if (streamIds) {
156
+ for (const streamId of streamIds) {
157
+ const streamKey = this.getKey(connectionId, streamId)
158
+ const state = this.serverStreams.get(streamKey)
159
+ if (state) {
160
+ streams[streamId] = state.stream.metadata
161
+ }
162
+ }
163
+ }
164
+
165
+ return streams
166
+ }
167
+
168
+ createServerStream(
169
+ connectionId: string,
170
+ callId: number,
171
+ streamId: number,
172
+ blob: ProtocolBlob,
173
+ ) {
174
+ const stream = new ProtocolServerStream(streamId, blob)
175
+ const key = this.getKey(connectionId, streamId)
176
+
177
+ const state: ServerStreamState = {
178
+ connectionId,
179
+ callId,
180
+ stream,
181
+ timeouts: {
182
+ [StreamTimeout.Pull]: undefined,
183
+ [StreamTimeout.Consume]: undefined,
184
+ [StreamTimeout.Finish]: undefined,
185
+ },
186
+ }
187
+
188
+ // Prevent unhandled 'error' events, in case the user did not subscribe to them
189
+ stream.on('error', noopFn)
190
+
191
+ this.serverStreams.set(key, state)
192
+ this.trackServerCall(connectionId, callId, streamId)
193
+ this.trackConnectionServerStream(connectionId, streamId)
194
+
195
+ this.startTimeout(state, StreamTimeout.Finish)
196
+ this.startTimeout(state, StreamTimeout.Consume)
197
+
198
+ return stream
199
+ }
200
+
201
+ pullServerStream(connectionId: string, streamId: number) {
202
+ const key = this.getKey(connectionId, streamId)
203
+ const state = this.serverStreams.get(key)
204
+ if (state) {
205
+ state.stream.resume()
206
+ this.clearTimeout(state, StreamTimeout.Consume)
207
+ this.startTimeout(state, StreamTimeout.Pull)
208
+ }
209
+ }
210
+
211
+ abortServerStream(connectionId: string, streamId: number, error = 'Aborted') {
212
+ const key = this.getKey(connectionId, streamId)
213
+ const state = this.serverStreams.get(key)
214
+ if (state) {
215
+ state.stream.destroy(new Error(error))
216
+ this.removeServerStream(connectionId, streamId)
217
+ }
218
+ }
219
+
220
+ removeServerStream(connectionId: string, streamId: number) {
221
+ const key = this.getKey(connectionId, streamId)
222
+ const state = this.serverStreams.get(key)
223
+ if (state) {
224
+ this.serverStreams.delete(key)
225
+ this.clearTimeout(state, StreamTimeout.Pull)
226
+ this.clearTimeout(state, StreamTimeout.Consume)
227
+ this.clearTimeout(state, StreamTimeout.Finish)
228
+ this.untrackServerCall(connectionId, state.callId, streamId)
229
+ this.untrackConnectionServerStream(connectionId, streamId)
230
+ }
231
+ }
232
+
233
+ // --- Timeouts ---
234
+
235
+ private startTimeout(state: StreamState, type: StreamTimeout) {
236
+ this.clearTimeout(state, type)
237
+ const duration = this.timeoutDurations[type]
238
+ const timeout = setTimeout(() => {
239
+ if (state.stream instanceof ProtocolClientStream) {
240
+ this.abortClientStream(
241
+ state.connectionId,
242
+ state.stream.id,
243
+ `${type} timeout`,
244
+ )
245
+ } else {
246
+ this.abortServerStream(
247
+ state.connectionId,
248
+ state.stream.id,
249
+ `${type} timeout`,
250
+ )
251
+ }
252
+ state.timeouts[type] = undefined
253
+ }, duration)
254
+ state.timeouts[type] = timeout
255
+ }
256
+
257
+ private clearTimeout(state: StreamState, type: StreamTimeout) {
258
+ const timeout = state.timeouts[type]
259
+ if (timeout) {
260
+ clearTimeout(timeout)
261
+ state.timeouts[type] = undefined
262
+ }
263
+ }
264
+
265
+ // --- Helpers ---
266
+
267
+ private getKey(connectionId: string, streamId: number) {
268
+ return `${connectionId}:${streamId}`
269
+ }
270
+
271
+ private getCallKey(connectionId: string, callId: number) {
272
+ return `${connectionId}:${callId}`
273
+ }
274
+
275
+ private trackClientCall(
276
+ connectionId: string,
277
+ callId: number,
278
+ streamId: number,
279
+ ) {
280
+ const key = this.getCallKey(connectionId, callId)
281
+ let set = this.clientCallStreams.get(key)
282
+ if (!set) {
283
+ set = new Set()
284
+ this.clientCallStreams.set(key, set)
285
+ }
286
+ set.add(streamId)
287
+ }
288
+
289
+ private untrackClientCall(
290
+ connectionId: string,
291
+ callId: number,
292
+ streamId: number,
293
+ ) {
294
+ const key = this.getCallKey(connectionId, callId)
295
+ const set = this.clientCallStreams.get(key)
296
+ if (set) {
297
+ set.delete(streamId)
298
+ if (set.size === 0) {
299
+ this.clientCallStreams.delete(key)
300
+ }
301
+ }
302
+ }
303
+
304
+ private trackServerCall(
305
+ connectionId: string,
306
+ callId: number,
307
+ streamId: number,
308
+ ) {
309
+ const key = this.getCallKey(connectionId, callId)
310
+ let set = this.serverCallStreams.get(key)
311
+ if (!set) {
312
+ set = new Set()
313
+ this.serverCallStreams.set(key, set)
314
+ }
315
+ set.add(streamId)
316
+ }
317
+
318
+ private untrackServerCall(
319
+ connectionId: string,
320
+ callId: number,
321
+ streamId: number,
322
+ ) {
323
+ const key = this.getCallKey(connectionId, callId)
324
+ const set = this.serverCallStreams.get(key)
325
+ if (set) {
326
+ set.delete(streamId)
327
+ if (set.size === 0) {
328
+ this.serverCallStreams.delete(key)
329
+ }
330
+ }
331
+ }
332
+
333
+ private trackConnectionClientStream(connectionId: string, streamId: number) {
334
+ let set = this.connectionClientStreams.get(connectionId)
335
+ if (!set) {
336
+ set = new Set()
337
+ this.connectionClientStreams.set(connectionId, set)
338
+ }
339
+ set.add(streamId)
340
+ }
341
+
342
+ private untrackConnectionClientStream(
343
+ connectionId: string,
344
+ streamId: number,
345
+ ) {
346
+ const set = this.connectionClientStreams.get(connectionId)
347
+ if (set) {
348
+ set.delete(streamId)
349
+ if (set.size === 0) {
350
+ this.connectionClientStreams.delete(connectionId)
351
+ }
352
+ }
353
+ }
354
+
355
+ private trackConnectionServerStream(connectionId: string, streamId: number) {
356
+ let set = this.connectionServerStreams.get(connectionId)
357
+ if (!set) {
358
+ set = new Set()
359
+ this.connectionServerStreams.set(connectionId, set)
360
+ }
361
+ set.add(streamId)
362
+ }
363
+
364
+ private untrackConnectionServerStream(
365
+ connectionId: string,
366
+ streamId: number,
367
+ ) {
368
+ const set = this.connectionServerStreams.get(connectionId)
369
+ if (set) {
370
+ set.delete(streamId)
371
+ if (set.size === 0) {
372
+ this.connectionServerStreams.delete(connectionId)
373
+ }
374
+ }
375
+ }
376
+
377
+ // --- Cleanup ---
378
+
379
+ abortClientCallStreams(
380
+ connectionId: string,
381
+ callId: number,
382
+ reason = 'Call aborted',
383
+ ) {
384
+ const key = this.getCallKey(connectionId, callId)
385
+ const clientStreamIds = this.clientCallStreams.get(key)
386
+ if (clientStreamIds) {
387
+ for (const streamId of [...clientStreamIds]) {
388
+ this.abortClientStream(connectionId, streamId, reason)
389
+ }
390
+ }
391
+ }
392
+
393
+ cleanupConnection(connectionId: string) {
394
+ const clientStreamIds = this.connectionClientStreams.get(connectionId)
395
+ if (clientStreamIds) {
396
+ for (const streamId of [...clientStreamIds]) {
397
+ this.abortClientStream(connectionId, streamId, 'Connection closed')
398
+ }
399
+ }
400
+
401
+ const serverStreamIds = this.connectionServerStreams.get(connectionId)
402
+ if (serverStreamIds) {
403
+ for (const streamId of [...serverStreamIds]) {
404
+ this.abortServerStream(connectionId, streamId, 'Connection closed')
405
+ }
406
+ }
407
+ }
408
+ }
@@ -0,0 +1,95 @@
1
+ import type { Async } from '@nmtjs/common'
2
+ import type { Injection, LazyInjectable, Scope } from '@nmtjs/core'
3
+ import type { ConnectionType, ProtocolVersion } from '@nmtjs/protocol'
4
+ import type { ProtocolFormats } from '@nmtjs/protocol/server'
5
+
6
+ import type { GatewayConnection } from './connections.ts'
7
+ import type { ProxyableTransportType } from './enums.ts'
8
+ import type { GatewayRpc } from './types.ts'
9
+
10
+ export interface TransportConnection {
11
+ connectionId: string
12
+ type: ConnectionType
13
+ }
14
+
15
+ export interface TransportOnConnectOptions<
16
+ Type extends ConnectionType = ConnectionType,
17
+ > {
18
+ type: Type extends ConnectionType.Bidirectional
19
+ ? Type
20
+ : ConnectionType.Unidirectional
21
+ protocolVersion: ProtocolVersion
22
+ accept: string | null
23
+ contentType: string | null
24
+ data: unknown
25
+ }
26
+
27
+ export interface TransportOnMessageOptions {
28
+ connectionId: string
29
+ data: ArrayBuffer
30
+ }
31
+
32
+ export type TransportWorkerParams<
33
+ Type extends ConnectionType = ConnectionType,
34
+ > = {
35
+ formats: ProtocolFormats
36
+ onConnect: (
37
+ options: TransportOnConnectOptions<Type>,
38
+ ...injections: Injection[]
39
+ ) => Promise<GatewayConnection & AsyncDisposable>
40
+ onDisconnect: (connectionId: GatewayConnection['id']) => Promise<void>
41
+ onMessage: (
42
+ options: TransportOnMessageOptions,
43
+ ...injections: Injection[]
44
+ ) => Promise<void>
45
+ onRpc: (
46
+ connection: GatewayConnection,
47
+ rpc: GatewayRpc,
48
+ signal: AbortSignal,
49
+ ...injections: Injection[]
50
+ ) => Promise<unknown>
51
+ }
52
+
53
+ export interface TransportWorkerStartOptions<
54
+ Type extends ConnectionType = ConnectionType,
55
+ > extends TransportWorkerParams<Type> {
56
+ // for extra props in the future
57
+ }
58
+
59
+ export interface TransportWorker<Type extends ConnectionType = ConnectionType> {
60
+ start: (params: TransportWorkerParams<Type>) => Async<string>
61
+ stop: (params: Pick<TransportWorkerParams<Type>, 'formats'>) => Async<void>
62
+ send?: Type extends 'unidirectional'
63
+ ? never
64
+ : (connectionId: string, buffer: ArrayBufferView) => boolean | null
65
+ }
66
+
67
+ export interface Transport<
68
+ Type extends ConnectionType = ConnectionType,
69
+ TransportOptions = any,
70
+ Injections extends {
71
+ [key: string]: LazyInjectable<any, Scope.Connection | Scope.Call>
72
+ } = { [key: string]: LazyInjectable<any, Scope.Connection | Scope.Call> },
73
+ Proxyable extends ProxyableTransportType | undefined =
74
+ | ProxyableTransportType
75
+ | undefined,
76
+ > {
77
+ proxyable: Proxyable
78
+ injectables?: Injections
79
+ factory: (options: TransportOptions) => Async<TransportWorker<Type>>
80
+ }
81
+
82
+ export function createTransport<
83
+ Type extends ConnectionType = ConnectionType,
84
+ TransportOptions = any,
85
+ Injections extends {
86
+ [key: string]: LazyInjectable<any, Scope.Connection | Scope.Call>
87
+ } = { [key: string]: LazyInjectable<any, Scope.Connection | Scope.Call> },
88
+ Proxyable extends ProxyableTransportType | undefined =
89
+ | ProxyableTransportType
90
+ | undefined,
91
+ >(
92
+ config: Transport<Type, TransportOptions, Injections, Proxyable>,
93
+ ): Transport<Type, TransportOptions, Injections, Proxyable> {
94
+ return config
95
+ }
package/src/types.ts ADDED
@@ -0,0 +1,24 @@
1
+ import type { AnyInjectable, Container, Logger, Scope } from '@nmtjs/core'
2
+ import type { MessageContext as ProtocolMessageContext } from '@nmtjs/protocol/server'
3
+
4
+ import type { GatewayApiCallOptions } from './api.ts'
5
+
6
+ export type ConnectionIdentityType = string
7
+ export type ConnectionIdentity = AnyInjectable<
8
+ ConnectionIdentityType,
9
+ Scope.Global
10
+ >
11
+
12
+ export interface GatewayRpc {
13
+ callId: number
14
+ procedure: string
15
+ payload: unknown
16
+ metadata?: GatewayApiCallOptions['metadata']
17
+ }
18
+
19
+ export interface GatewayRpcContext extends ProtocolMessageContext, GatewayRpc {
20
+ container: Container
21
+ signal: AbortSignal
22
+ logger: Logger
23
+ [Symbol.asyncDispose](): Promise<void>
24
+ }