Skip to content

Commit

Permalink
Feat: new server middleware & through dataLoader & server middleware (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
GiveMe-A-Name committed May 16, 2024
1 parent 69f1b82 commit fe6299e
Show file tree
Hide file tree
Showing 37 changed files with 602 additions and 66 deletions.
3 changes: 3 additions & 0 deletions packages/runtime/plugin-runtime/src/exports/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ export type {
CacheControl,
CacheOptionProvider,
CacheOption,
UnstableMiddlewareContext,
UnstableMiddleware,
UnstableNext,
} from '@modern-js/types';

export const hook = (
Expand Down
14 changes: 4 additions & 10 deletions packages/runtime/plugin-runtime/src/router/runtime/plugin.node.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import {
import hoistNonReactStatics from 'hoist-non-react-statics';
import { createRoutesFromElements } from '@modern-js/runtime-utils/router';
import {
createRequestContext,
reporterCtx,
createRequestContext,
} from '@modern-js/runtime-utils/node';
import { time } from '@modern-js/runtime-utils/time';
import { LOADER_REPORTER_NAME } from '@modern-js/utils/universal/constants';
Expand All @@ -28,20 +28,12 @@ function createFetchRequest(req: SSRServerContext['request']): Request {

const controller = new AbortController();

// req.on('close', () => {
// controller.abort();
// });

const init = {
method: req.method,
headers: createFetchHeaders(req.headers),
signal: controller.signal,
};

// if (req.method !== 'GET' && req.method !== 'HEAD') {
// init.body = req.body;
// }

return new Request(url.href, init);
}

Expand Down Expand Up @@ -90,7 +82,9 @@ export const routerPlugin = ({
const _basename =
baseUrl === '/' ? urlJoin(baseUrl, basename) : baseUrl;
const { reporter, serverTiming } = context.ssrContext!;
const requestContext = createRequestContext();
const requestContext = createRequestContext(
context.ssrContext?.loaderContext,
);
requestContext.set(reporterCtx, reporter);

let routes = createRoutes
Expand Down
9 changes: 6 additions & 3 deletions packages/runtime/plugin-runtime/src/router/runtime/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,13 @@ interface DataFunctionArgs<D = any> {
context?: D;
}

export type LoaderFunctionArgs = DataFunctionArgs<RequestContext>;
export type LoaderFunctionArgs<P extends Record<string, unknown> = any> =
DataFunctionArgs<RequestContext<P>>;

declare type DataFunctionValue = Response | NonNullable<unknown> | null;

export type LoaderFunction = (
args: LoaderFunctionArgs,
export type LoaderFunction = <
P extends Record<string, unknown> = Record<string, unknown>,
>(
args: LoaderFunctionArgs<P>,
) => Promise<DataFunctionValue> | DataFunctionValue;
1 change: 1 addition & 0 deletions packages/server/core/src/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export {
bindRenderHandler,
logHandler,
processedBy,
getLoaderCtx,
} from './middlewares';
export type { BindRenderHandleOptions } from './middlewares';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import {
ModernResponse,
} from '@modern-js/types';
import { getCookie } from 'hono/cookie';
import type { Context, HonoRequest, ServerEnv } from '../../../core/server';
import { getHost } from '../../utils';
import type { Context, HonoRequest, ServerEnv } from '../../../core/server';

export type ResArgs = {
status?: number;
Expand Down
85 changes: 76 additions & 9 deletions packages/server/core/src/base/middlewares/customServer/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { ServerRoute } from '@modern-js/types';
import {
ServerRoute,
UnstableMiddlewareContext,
UnstableMiddleware,
} from '@modern-js/types';
import { time } from '@modern-js/runtime-utils/time';
import { ServerBase } from '../../serverBase';
import { ServerHookRunner } from '../../../core/plugin';
import { Middleware, ServerEnv } from '../../../core/server';
import { Context, Middleware, ServerEnv } from '../../../core/server';
import { transformResponse } from '../../utils';
import { ServerReportTimings } from '../../constants';
import type { ServerNodeEnv } from '../../adapters/node/hono';
import { getLoaderCtx } from './loader';
import {
getAfterMatchCtx,
getAfterRenderCtx,
Expand All @@ -14,6 +19,8 @@ import {
} from './context';
import { ResArgs, createBaseHookContext } from './base';

export { getLoaderCtx } from './loader';

// eslint-disable-next-line @typescript-eslint/no-empty-function
const noop = () => {};

Expand Down Expand Up @@ -48,7 +55,7 @@ export class CustomServer {
middleware: webExtension,
},
},
{ onLast: () => null },
{ onLast: () => [] },
);
}

Expand Down Expand Up @@ -156,14 +163,24 @@ export class CustomServer {
};
}

getServerMiddleware(): Middleware<ServerNodeEnv & ServerEnv> {
async getServerMiddleware(): Promise<
| Middleware<ServerNodeEnv & ServerEnv>
| Array<Middleware<ServerNodeEnv & ServerEnv>>
| undefined
> {
const serverMiddleware = await this.serverMiddlewarePromise;

if (!serverMiddleware) {
return;
}

if (Array.isArray(serverMiddleware)) {
// eslint-disable-next-line consistent-return
return getUnstableMiddlewares(serverMiddleware);
}

// eslint-disable-next-line consistent-return
return async (c, next) => {
const serverMiddleware = await this.serverMiddlewarePromise;
if (!serverMiddleware) {
return next();
}

const reporter = c.get('reporter');

const locals: Record<string, any> = {};
Expand Down Expand Up @@ -207,3 +224,53 @@ export class CustomServer {
function isRedirect(headers: Headers, code?: number) {
return [301, 302, 307, 308].includes(code || 0) || headers.get('Location');
}

function getUnstableMiddlewares(
serverMiddleware: UnstableMiddleware[],
): Array<Middleware<ServerNodeEnv & ServerEnv>> {
return serverMiddleware.map(middleware => {
return async (c, next) => {
const context = createMiddlewareContextFromHono(c);

return middleware(context, next);
};
});
}

function createMiddlewareContextFromHono(
c: Context,
): UnstableMiddlewareContext {
const loaderContext = getLoaderCtx(c);

return {
get request() {
return c.req.raw;
},

get response() {
return c.res;
},

set response(newRes) {
c.res = newRes;
},

get(key) {
return loaderContext.get(key as string);
},

set(key, value) {
return loaderContext.set(key as string, 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),
};
}
23 changes: 23 additions & 0 deletions packages/server/core/src/base/middlewares/customServer/loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { Context } from '../../../core/server';

type LoaderContext = Map<string, unknown>;

type Var = {
loaderContext: LoaderContext;
};

interface Env {
Variables: Var;
}

export function getLoaderCtx(c: Context<Env>): LoaderContext {
const loaderContext = c.get('loaderContext');
if (loaderContext) {
return loaderContext;
} else {
const loaderContext = new Map();

c.set('loaderContext', loaderContext);
return loaderContext;
}
}
1 change: 1 addition & 0 deletions packages/server/core/src/base/middlewares/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export * from './monitor';
export * from './renderHandler';
export * from './logger';
export * from './frameworkHeader';
export { getLoaderCtx } from './customServer';
2 changes: 1 addition & 1 deletion packages/server/core/src/base/middlewares/logger.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// The following code is modified based on https://github.com/honojs/hono/blob/main/src/middleware/logger/index.ts
// license at https://github.com/honojs/hono/blob/main/LICENSE
import type { Middleware, ServerEnv } from '../../core/server';
import { getPathname } from '../utils';
import type { Middleware, ServerEnv } from '../../core/server';

enum LogPrefix {
Outgoing = '-->',
Expand Down
16 changes: 12 additions & 4 deletions packages/server/core/src/base/middlewares/renderHandler/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { Render } from '../../../core/render';
import { Middleware, ServerEnv } from '../../../core/server';
import { Context, Middleware, ServerEnv } from '../../../core/server';
import { ServerBase, type ServerBaseOptions } from '../../serverBase';
import { checkIsProd, sortRoutes, getRuntimeEnv } from '../../utils';
import type { ServerNodeEnv } from '../../adapters/node/hono';
import { initReporter } from '../monitor';
import { CustomServer } from '../customServer';
import { CustomServer, getLoaderCtx } from '../customServer';
import { OnFallback, createRender } from './render';
import type * as ssrCacheModule from './ssrCache';

Expand All @@ -18,6 +18,7 @@ function createRenderHandler(
const serverManifest = c.get('serverManifest') || {};
const locals = c.get('locals');
const metrics = c.get('metrics');
const loaderContext = getLoaderCtx(c as Context);

const request = c.req.raw;
const nodeReq = c.env.node?.req;
Expand All @@ -29,6 +30,7 @@ function createRenderHandler(
templates,
metrics,
serverManifest,
loaderContext,
locals,
});

Expand Down Expand Up @@ -128,8 +130,14 @@ export async function bindRenderHandler(

!disableCustomHook && server.use(urlPath, customServerHookMiddleware);

const customServerMiddleware = customServer.getServerMiddleware();
server.use(urlPath, customServerMiddleware);
const customServerMiddleware = await customServer.getServerMiddleware();
if (customServerMiddleware) {
if (Array.isArray(customServerMiddleware)) {
server.use(urlPath, ...customServerMiddleware);
} else {
server.use(urlPath, customServerMiddleware);
}
}

render && server.all(urlPath, createRenderHandler(render));
}
Expand Down
22 changes: 16 additions & 6 deletions packages/server/core/src/base/middlewares/renderHandler/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ import { Logger, Metrics, Reporter, ServerRoute } from '@modern-js/types';
import { cutNameByHyphen } from '@modern-js/utils/universal';
import { TrieRouter } from 'hono/router/trie-router';
import type { Router } from 'hono/router';
import type { FallbackReason } from '../../../core/plugin';
import { REPLACE_REG } from '../../../base/constants';
import { Render } from '../../../core/render';
import {
parseQuery,
getPathname,
createErrorHtml,
sortRoutes,
parseQuery,
transformResponse,
getPathname,
onError as onErrorFn,
ErrorDigest,
} from '../../utils';
import type { FallbackReason } from '../../../core/plugin';
import { REPLACE_REG } from '../../../base/constants';
import { Render } from '../../../core/render';
import { dataHandler } from './dataHandler';
import { Params, SSRRenderOptions, ssrRender } from './ssrRender';

Expand Down Expand Up @@ -80,7 +80,16 @@ export async function createRender({

return async (
req,
{ logger, nodeReq, reporter, templates, serverManifest, locals, metrics },
{
logger,
nodeReq,
reporter,
templates,
serverManifest,
locals,
metrics,
loaderContext,
},
) => {
const [routeInfo, params] = matchRoute(router, req);

Expand Down Expand Up @@ -137,6 +146,7 @@ export async function createRender({
locals,
serverManifest,
metrics,
loaderContext: loaderContext || new Map(),
};

switch (renderMode) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import type {
Container,
} from '@modern-js/types';
import { createMemoryStorage } from '@modern-js/runtime-utils/storer';
import { createTransformStream, getPathname } from '../../utils';
import type { SSRServerContext, ServerRender } from '../../../core/server';
import { createReadableStreamFromReadable } from '../../adapters/node/polyfills/stream';
import { createTransformStream, getPathname } from '../../utils';

interface CacheStruct {
val: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export interface SSRRenderOptions {
metaName: string;
logger: Logger;
serverManifest: ServerManifest;
loaderContext: Map<string, unknown>;

params: Params;
/** Produce by custom server hook */
Expand All @@ -75,6 +76,7 @@ export async function ssrRender(
locals,
params,
metrics,
loaderContext,
}: SSRRenderOptions,
): Promise<Response> {
const { entryName } = routeInfo;
Expand Down Expand Up @@ -121,6 +123,7 @@ export async function ssrRender(

template: html,
loadableStats,
loaderContext,
routeManifest, // for streaming ssr
entryName: entryName!,
staticGenerate,
Expand Down
2 changes: 1 addition & 1 deletion packages/server/core/src/base/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export * from './env';
export * from './request';
export * from './transformStream';
export * from './middlewareCollector';
export * from './error';
export * from './warmup';
export * from './entry';
export * from './request';
Loading

0 comments on commit fe6299e

Please sign in to comment.