UNPKG

@modern-js/server-core

Version:

A Progressive React Framework for modern web development.

364 lines (363 loc) • 12.9 kB
import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator"; import { _ as _class_call_check } from "@swc/helpers/_/_class_call_check"; import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator"; import { time } from "@modern-js/runtime-utils/time"; import { isArray, isFunction } from "@modern-js/utils"; import { ServerTimings } from "../../constants"; import { getLoaderCtx } from "../../helper"; import { transformResponse } from "../../utils"; import { createBaseHookContext } from "./base"; import { createAfterStreamingRenderContext, createCustomMiddlewaresCtx, getAfterMatchCtx, getAfterRenderCtx } from "./context"; var noop = function() { }; var isHtmlResponse = function(response) { var contentType = response.headers.get("content-type"); return contentType === null || contentType === void 0 ? void 0 : contentType.includes("text/html"); }; var CustomServer = /* @__PURE__ */ function() { "use strict"; function CustomServer2(hooks, pwd) { _class_call_check(this, CustomServer2); this.hooks = hooks; var webExtension = []; this.serverMiddlewarePromise = hooks.prepareWebServer.call({ pwd, config: { middleware: webExtension } }); } var _proto = CustomServer2.prototype; _proto.getHookMiddleware = function getHookMiddleware(entryName, routes) { var _this = this; return function() { var _ref = _async_to_generator(function(c, next) { var routeInfo, monitors, baseHookCtx, afterMatchCtx, getCost, cost, _afterMatchCtx_router, url, status, current, rewriteRoute, afterStreamingRenderContext, afterRenderCtx, getCost1, cost1, newBody; return _ts_generator(this, function(_state) { switch (_state.label) { case 0: routeInfo = routes.find(function(route) { return route.entryName === entryName; }); monitors = c.get("monitors"); baseHookCtx = createBaseHookContext(c); afterMatchCtx = getAfterMatchCtx(entryName, baseHookCtx); getCost = time(); return [ 4, _this.hooks.afterMatch.call(afterMatchCtx) ]; case 1: _state.sent(); cost = getCost(); cost && (monitors === null || monitors === void 0 ? void 0 : monitors.timing(ServerTimings.SERVER_HOOK_AFTER_MATCH, cost)); _afterMatchCtx_router = afterMatchCtx.router, url = _afterMatchCtx_router.url, status = _afterMatchCtx_router.status; if (url) { return [ 2, c.redirect(url, status) ]; } current = afterMatchCtx.router.current; if (current !== entryName) { rewriteRoute = routes.find(function(route) { return route.entryName === current; }); if (rewriteRoute) { c.set("matchPathname", rewriteRoute.urlPath); c.set("matchEntryName", current); } } if (c.finalized) { return [ 2, void 0 ]; } return [ 4, next() ]; case 2: _state.sent(); if (c.finalized && (!c.res.body || !isHtmlResponse(c.res) || [ 404, 500 ].includes(c.res.status))) { return [ 2, void 0 ]; } if (c.res) { c.status(c.res.status); } if (!routeInfo.isStream) return [ 3, 3 ]; afterStreamingRenderContext = createAfterStreamingRenderContext(baseHookCtx, routeInfo); c.res = transformResponse(c.res, function() { var _ref2 = _async_to_generator(function(chunk) { var context, _ref3, newChunk; return _ts_generator(this, function(_state2) { switch (_state2.label) { case 0: context = afterStreamingRenderContext(chunk); return [ 4, _this.hooks.afterStreamingRender.call(context) ]; case 1: _ref3 = _state2.sent(), newChunk = _ref3.chunk; return [ 2, newChunk ]; } }); }); return function(chunk) { return _ref2.apply(this, arguments); }; }()); return [ 3, 6 ]; case 3: return [ 4, getAfterRenderCtx(c, baseHookCtx, routeInfo) ]; case 4: afterRenderCtx = _state.sent(); getCost1 = time(); return [ 4, _this.hooks.afterRender.call(afterRenderCtx) ]; case 5: _state.sent(); cost1 = getCost1(); cost1 && (monitors === null || monitors === void 0 ? void 0 : monitors.timing(ServerTimings.SERVER_HOOK_AFTER_RENDER, cost1)); if (afterRenderCtx.response.private_overrided) { return [ 2, void 0 ]; } newBody = afterRenderCtx.template.get(); c.res = c.body(newBody); _state.label = 6; case 6: return [ 2 ]; } }); }); return function(c, next) { return _ref.apply(this, arguments); }; }(); }; _proto.getServerMiddleware = function getServerMiddleware() { var _this = this; return _async_to_generator(function() { var serverMiddleware, unstableMiddlewares; return _ts_generator(this, function(_state) { switch (_state.label) { case 0: return [ 4, _this.serverMiddlewarePromise ]; case 1: serverMiddleware = _state.sent(); if (!serverMiddleware || !isFunction(serverMiddleware) && !isArray(serverMiddleware)) { return [ 2 ]; } if (Array.isArray(serverMiddleware)) { unstableMiddlewares = getServerMidFromUnstableMid(serverMiddleware); return [ 2, unstableMiddlewares ]; } return [ 2, function() { var _ref = _async_to_generator(function(c, next) { var _c_env_node_res, _c_env_node, _c_env, monitors, locals, resArgs, customMiddlewareCtx, getCost, cost; return _ts_generator(this, function(_state2) { switch (_state2.label) { case 0: monitors = c.get("monitors"); locals = {}; resArgs = { headers: new Headers() }; customMiddlewareCtx = createCustomMiddlewaresCtx(c, locals, resArgs); getCost = time(); return [ 4, serverMiddleware(customMiddlewareCtx) ]; case 1: _state2.sent(); cost = getCost(); cost && (monitors === null || monitors === void 0 ? void 0 : monitors.timing(ServerTimings.SERVER_MIDDLEWARE, cost)); c.set("locals", locals); if (isRedirect(resArgs.headers, resArgs.status)) { return [ 2, c.redirect(resArgs.headers.get("Location") || "", resArgs.status || 302) ]; } if ((_c_env = c.env) === null || _c_env === void 0 ? void 0 : (_c_env_node = _c_env.node) === null || _c_env_node === void 0 ? void 0 : (_c_env_node_res = _c_env_node.res) === null || _c_env_node_res === void 0 ? void 0 : _c_env_node_res.headersSent) { return [ 2, void 0 ]; } if (!c.finalized) { return [ 2, next() ]; } return [ 2 ]; } }); }); return function(c, next) { return _ref.apply(this, arguments); }; }() ]; } }); })(); }; return CustomServer2; }(); function getServerMidFromUnstableMid(serverMiddleware) { return serverMiddleware.map(function(middleware) { return function() { var _ref = _async_to_generator(function(c, next) { var context; return _ts_generator(this, function(_state) { switch (_state.label) { case 0: return [ 4, createMiddlewareContextFromHono(c) ]; case 1: context = _state.sent(); return [ 2, middleware(context, next) ]; } }); }); return function(c, next) { return _ref.apply(this, arguments); }; }(); }); } function isRedirect(headers, code) { return [ 301, 302, 307, 308 ].includes(code || 0) || headers.get("Location"); } function createMiddlewareContextFromHono(c) { return _createMiddlewareContextFromHono.apply(this, arguments); } function _createMiddlewareContextFromHono() { _createMiddlewareContextFromHono = // TODO: maybe we need use hono ctx directly // TODO: after we use hono ctx, we should use `c.get('monitors')` to get monitors _async_to_generator(function(c) { var loaderContext, rawRequest, method, streamModulePath, createReadableStreamFromReadable, init; return _ts_generator(this, function(_state) { switch (_state.label) { case 0: loaderContext = getLoaderCtx(c); rawRequest = c.req.raw; method = rawRequest.method.toUpperCase(); if (!(![ "GET", "HEAD" ].includes(method) && !rawRequest.body && c.env.node.req)) return [ 3, 2 ]; streamModulePath = "../../adapters/node/polyfills/stream.js"; return [ 4, import(streamModulePath) ]; case 1: createReadableStreamFromReadable = _state.sent().createReadableStreamFromReadable; init = { body: createReadableStreamFromReadable(c.env.node.req), headers: rawRequest.headers, signal: rawRequest.signal, method: rawRequest.method }; init.duplex = "half"; c.req.raw = new Request(rawRequest.url, init); _state.label = 2; case 2: return [ 2, { get request() { return c.req.raw; }, set request(request) { c.req.raw = request; }, get response() { return c.res; }, set response(newRes) { c.res = newRes; }, get route() { return c.get("route"); }, get: function get(key) { return loaderContext.get(key); }, set: function set(key, value) { return loaderContext.set(key, value); }, status: c.status.bind(c), header: c.header.bind(c), body: c.body.bind(c), html: c.html.bind(c), redirect: c.redirect.bind(c) } ]; } }); }); return _createMiddlewareContextFromHono.apply(this, arguments); } export { CustomServer, getServerMidFromUnstableMid };