UNPKG

@metamask/json-rpc-engine

Version:
70 lines 2.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.createAsyncMiddleware = void 0; /** * JsonRpcEngine only accepts callback-based middleware directly. * createAsyncMiddleware exists to enable consumers to pass in async middleware * functions. * * Async middleware have no "end" function. Instead, they "end" if they return * without calling "next". Rather than passing in explicit return handlers, * async middleware can simply await "next", and perform operations on the * response object when execution resumes. * * To accomplish this, createAsyncMiddleware passes the async middleware a * wrapped "next" function. That function calls the internal JsonRpcEngine * "next" function with a return handler that resolves a promise when called. * * The return handler will always be called. Its resolution of the promise * enables the control flow described above. * * @param asyncMiddleware - The asynchronous middleware function to wrap. * @returns The wrapped asynchronous middleware function, ready to be consumed * by JsonRpcEngine. */ function createAsyncMiddleware(asyncMiddleware) { // eslint-disable-next-line @typescript-eslint/no-misused-promises return async (request, response, next, end) => { // nextPromise is the key to the implementation // it is resolved by the return handler passed to the // "next" function let resolveNextPromise; const nextPromise = new Promise((resolve) => { resolveNextPromise = resolve; }); let returnHandlerCallback = null; let nextWasCalled = false; // This will be called by the consumer's async middleware. const asyncNext = async () => { nextWasCalled = true; // We pass a return handler to next(). When it is called by the engine, // the consumer's async middleware will resume executing. next((runReturnHandlersCallback) => { // This callback comes from JsonRpcEngine._runReturnHandlers returnHandlerCallback = runReturnHandlersCallback; resolveNextPromise(); }); return nextPromise; }; try { await asyncMiddleware(request, response, asyncNext); if (nextWasCalled) { await nextPromise; // we must wait until the return handler is called returnHandlerCallback(null); } else { end(null); } } catch (error) { if (returnHandlerCallback) { returnHandlerCallback(error); } else { end(error); } } }; } exports.createAsyncMiddleware = createAsyncMiddleware; //# sourceMappingURL=createAsyncMiddleware.cjs.map