@@ -4,7 +4,11 @@ import type {
4
4
JSONRPCResponse ,
5
5
JSONRPCResponseResult ,
6
6
MiddlewareFactory ,
7
+ JSONValue ,
8
+ RPCRequestParams ,
9
+ RPCResponseResult ,
7
10
} from './types' ;
11
+ import type { ContextTimed } from '@matrixai/contexts' ;
8
12
import { TransformStream } from 'stream/web' ;
9
13
import { JSONParser } from '@streamparser/json' ;
10
14
import * as utils from './utils' ;
@@ -75,6 +79,96 @@ function jsonMessageToBinaryStream(): TransformStream<
75
79
} ) ;
76
80
}
77
81
82
+ function timeoutMiddlewareServer (
83
+ ctx : ContextTimed ,
84
+ _cancel : ( reason ?: any ) => void ,
85
+ _meta : Record < string , JSONValue > | undefined ,
86
+ ) {
87
+ const currentTimeout = ctx . timer . delay ;
88
+ // Flags for tracking if the first message has been processed
89
+ let forwardFirst = true ;
90
+ let reverseFirst = true ;
91
+ return {
92
+ forward : new TransformStream <
93
+ JSONRPCRequest < RPCRequestParams > ,
94
+ JSONRPCRequest < RPCRequestParams >
95
+ > ( {
96
+ transform : ( chunk , controller ) => {
97
+ controller . enqueue ( chunk ) ;
98
+ if ( forwardFirst ) {
99
+ forwardFirst = false ;
100
+ const clientTimeout = chunk . metadata ?. timeout ;
101
+
102
+ if ( clientTimeout == null ) return ;
103
+ if ( clientTimeout < currentTimeout ) ctx . timer . reset ( clientTimeout ) ;
104
+ }
105
+ } ,
106
+ } ) ,
107
+ reverse : new TransformStream <
108
+ JSONRPCResponse < RPCResponseResult > ,
109
+ JSONRPCResponse < RPCResponseResult >
110
+ > ( {
111
+ transform : ( chunk , controller ) => {
112
+ if ( reverseFirst ) {
113
+ reverseFirst = false ;
114
+ if ( 'result' in chunk ) {
115
+ if ( chunk . metadata == null ) chunk . metadata = { } ;
116
+ chunk . metadata . timeout = currentTimeout ;
117
+ }
118
+ }
119
+ controller . enqueue ( chunk ) ;
120
+ } ,
121
+ } ) ,
122
+ } ;
123
+ }
124
+
125
+ /**
126
+ * This adds its own timeout to the forward metadata and updates it's timeout
127
+ * based on the reverse metadata.
128
+ * @param ctx
129
+ * @param _cancel
130
+ * @param _meta
131
+ */
132
+ function timeoutMiddlewareClient (
133
+ ctx : ContextTimed ,
134
+ _cancel : ( reason ?: any ) => void ,
135
+ _meta : Record < string , JSONValue > | undefined ,
136
+ ) {
137
+ const currentTimeout = ctx . timer . delay ;
138
+ // Flags for tracking if the first message has been processed
139
+ let forwardFirst = true ;
140
+ let reverseFirst = true ;
141
+ return {
142
+ forward : new TransformStream < JSONRPCRequest , JSONRPCRequest > ( {
143
+ transform : ( chunk , controller ) => {
144
+ if ( forwardFirst ) {
145
+ forwardFirst = false ;
146
+ if ( chunk == null ) chunk = { jsonrpc : '2.0' , method : '' } ;
147
+ if ( chunk . metadata == null ) chunk . metadata = { } ;
148
+ ( chunk . metadata as any ) . timeout = currentTimeout ;
149
+ }
150
+ controller . enqueue ( chunk ) ;
151
+ } ,
152
+ } ) ,
153
+ reverse : new TransformStream <
154
+ JSONRPCResponse < RPCResponseResult > ,
155
+ JSONRPCResponse < RPCResponseResult >
156
+ > ( {
157
+ transform : ( chunk , controller ) => {
158
+ controller . enqueue ( chunk ) ;
159
+ if ( reverseFirst ) {
160
+ reverseFirst = false ;
161
+ if ( 'result' in chunk ) {
162
+ const clientTimeout = chunk . result ?. metadata ?. timeout ;
163
+ if ( clientTimeout == null ) return ;
164
+ if ( clientTimeout < currentTimeout ) ctx . timer . reset ( clientTimeout ) ;
165
+ }
166
+ }
167
+ } ,
168
+ } ) ,
169
+ } ;
170
+ }
171
+
78
172
/**
79
173
* This function is a factory for creating a pass-through streamPair. It is used
80
174
* as the default middleware for the middleware wrappers.
@@ -116,12 +210,14 @@ function defaultServerMiddlewareWrapper(
116
210
> ( ) ;
117
211
118
212
const middleMiddleware = middlewareFactory ( ctx , cancel , meta ) ;
213
+ const timeoutMiddleware = timeoutMiddlewareServer ( ctx , cancel , meta ) ;
119
214
120
- const forwardReadable = inputTransformStream . readable . pipeThrough (
121
- middleMiddleware . forward ,
122
- ) ; // Usual middleware here
215
+ const forwardReadable = inputTransformStream . readable
216
+ . pipeThrough ( timeoutMiddleware . forward ) // Timeout middleware here
217
+ . pipeThrough ( middleMiddleware . forward ) ; // Usual middleware here
123
218
const reverseReadable = outputTransformStream . readable
124
219
. pipeThrough ( middleMiddleware . reverse ) // Usual middleware here
220
+ . pipeThrough ( timeoutMiddleware . reverse ) // Timeout middleware here
125
221
. pipeThrough ( jsonMessageToBinaryStream ( ) ) ;
126
222
127
223
return {
@@ -172,13 +268,15 @@ const defaultClientMiddlewareWrapper = (
172
268
JSONRPCRequest
173
269
> ( ) ;
174
270
271
+ const timeoutMiddleware = timeoutMiddlewareClient ( ctx , cancel , meta ) ;
175
272
const middleMiddleware = middleware ( ctx , cancel , meta ) ;
176
273
const forwardReadable = inputTransformStream . readable
274
+ . pipeThrough ( timeoutMiddleware . forward )
177
275
. pipeThrough ( middleMiddleware . forward ) // Usual middleware here
178
276
. pipeThrough ( jsonMessageToBinaryStream ( ) ) ;
179
- const reverseReadable = outputTransformStream . readable . pipeThrough (
180
- middleMiddleware . reverse ,
181
- ) ; // Usual middleware here
277
+ const reverseReadable = outputTransformStream . readable
278
+ . pipeThrough ( middleMiddleware . reverse )
279
+ . pipeThrough ( timeoutMiddleware . reverse ) ; // Usual middleware here
182
280
183
281
return {
184
282
forward : {
0 commit comments