(asyncMiddleware: AsyncJRPCMiddleware<T, U>)
| 193 | * @deprecated Use {@link JRPCMiddlewareV2} directly — V2 middleware is async by default. |
| 194 | */ |
| 195 | export function createAsyncMiddleware<T extends JRPCParams, U>(asyncMiddleware: AsyncJRPCMiddleware<T, U>): JRPCMiddleware<T, U> { |
| 196 | return async (req, res, next, end) => { |
| 197 | // nextPromise is the key to the implementation |
| 198 | // it is resolved by the return handler passed to the |
| 199 | // "next" function |
| 200 | let resolveNextPromise: () => void; |
| 201 | const nextPromise = new Promise<void>((resolve) => { |
| 202 | resolveNextPromise = resolve; |
| 203 | }); |
| 204 | |
| 205 | let returnHandlerCallback: unknown = null; |
| 206 | let nextWasCalled = false; |
| 207 | |
| 208 | // This will be called by the consumer's async middleware. |
| 209 | const asyncNext = async () => { |
| 210 | nextWasCalled = true; |
| 211 | |
| 212 | // We pass a return handler to next(). When it is called by the engine, |
| 213 | // the consumer's async middleware will resume executing. |
| 214 | |
| 215 | next((runReturnHandlersCallback) => { |
| 216 | // This callback comes from JRPCEngine._runReturnHandlers |
| 217 | returnHandlerCallback = runReturnHandlersCallback; |
| 218 | resolveNextPromise(); |
| 219 | }); |
| 220 | await nextPromise; |
| 221 | }; |
| 222 | |
| 223 | try { |
| 224 | await asyncMiddleware(req, res, asyncNext); |
| 225 | |
| 226 | if (nextWasCalled) { |
| 227 | await nextPromise; // we must wait until the return handler is called |
| 228 | (returnHandlerCallback as ReturnHandlerCallback)(null); |
| 229 | } else { |
| 230 | end(null); |
| 231 | } |
| 232 | } catch (err: unknown) { |
| 233 | const error = err as Error; |
| 234 | if (returnHandlerCallback) { |
| 235 | (returnHandlerCallback as ReturnHandlerCallback)(error); |
| 236 | } else { |
| 237 | end(error); |
| 238 | } |
| 239 | } |
| 240 | }; |
| 241 | } |
no outgoing calls
no test coverage detected