Skip to content

Commit

Permalink
chore: support getMonitors API
Browse files Browse the repository at this point in the history
  • Loading branch information
zllkjc committed Feb 21, 2025
1 parent 753e63c commit 5111c83
Show file tree
Hide file tree
Showing 13 changed files with 341 additions and 346 deletions.
154 changes: 85 additions & 69 deletions packages/cli/plugin-data-loader/src/runtime/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { transformNestedRoutes } from '@modern-js/runtime-utils/browser';
import {
MonitorsCtx,
createRequestContext,
reporterCtx,
} from '@modern-js/runtime-utils/node';
import { storage } from '@modern-js/runtime-utils/node';
import {
UNSAFE_DEFERRED_SYMBOL as DEFERRED_SYMBOL,
type UNSAFE_DeferredData as DeferredData,
Expand All @@ -13,6 +13,7 @@ import {
} from '@modern-js/runtime-utils/remix-router';
import { matchEntry } from '@modern-js/runtime-utils/server';
import { time } from '@modern-js/runtime-utils/time';
import { parseHeaders } from '@modern-js/runtime-utils/universal/request';
import type { ServerLoaderBundle } from '@modern-js/server-core';
import { isPlainObject } from '@modern-js/utils/lodash';
import { LOADER_REPORTER_NAME } from '@modern-js/utils/universal/constants';
Expand Down Expand Up @@ -70,81 +71,96 @@ export const handleRequest: ServerLoaderBundle['handleRequest'] = async ({
const basename = entry.urlPath;
const end = time();
const { reporter, loaderContext, monitors } = context;
const routes = transformNestedRoutes(routesConfig, reporter);
const { queryRoute } = createStaticHandler(routes, {
basename,
});
const headersData = parseHeaders(request);

const requestContext = createRequestContext(loaderContext);
requestContext.set(MonitorsCtx, monitors);
// TODO: we may remove it or put it to other runtime plugins in next version
requestContext.set(reporterCtx, reporter);
return storage.run(
{
headers: headersData,
monitors,
},
async () => {
const routes = transformNestedRoutes(routesConfig, reporter);
const { queryRoute } = createStaticHandler(routes, {
basename,
});

let response;
const requestContext = createRequestContext(loaderContext);
// TODO: we may remove it or put it to other runtime plugins in next version
requestContext.set(reporterCtx, reporter);

try {
response = await queryRoute(request, {
routeId,
requestContext,
});
let response;

if (isResponse(response) && isRedirectResponse(response.status)) {
response = convertModernRedirectResponse(
response.headers as unknown as Headers,
basename,
);
} else if (isPlainObject(response) && DEFERRED_SYMBOL in response) {
const deferredData = response[DEFERRED_SYMBOL] as DeferredData;
const body = createDeferredReadableStream(deferredData, request.signal);
const init = deferredData.init || {};
if (init.status && isRedirectResponse(init.status)) {
if (!init.headers) {
throw new Error('redirect response includes no headers');
try {
response = await queryRoute(request, {
routeId,
requestContext,
});

if (isResponse(response) && isRedirectResponse(response.status)) {
response = convertModernRedirectResponse(
response.headers as unknown as Headers,
basename,
);
} else if (isPlainObject(response) && DEFERRED_SYMBOL in response) {
const deferredData = response[DEFERRED_SYMBOL] as DeferredData;
const body = createDeferredReadableStream(
deferredData,
request.signal,
);
const init = deferredData.init || {};
if (init.status && isRedirectResponse(init.status)) {
if (!init.headers) {
throw new Error('redirect response includes no headers');
}
response = convertModernRedirectResponse(
new Headers(init.headers),
basename,
);
} else {
const headers = new Headers(init.headers);
headers.set(
'Content-Type',
`${CONTENT_TYPE_DEFERRED}; charset=UTF-8`,
);
init.headers = headers;
response = new Response(body, init);
}
} else {
response = isResponse(response)
? response
: new Response(JSON.stringify(response), {
headers: {
'Content-Type': 'application/json; charset=utf-8',
},
});
}
response = convertModernRedirectResponse(
new Headers(init.headers),
basename,
);
} else {
const headers = new Headers(init.headers);
headers.set('Content-Type', `${CONTENT_TYPE_DEFERRED}; charset=UTF-8`);
init.headers = headers;
response = new Response(body, init);
}
} else {
response = isResponse(response)
? response
: new Response(JSON.stringify(response), {
const cost = end();
// add response header for client know if the response is from modern server
response.headers.set('X-Modernjs-Response', 'yes');
onTiming?.(`${LOADER_REPORTER_NAME}-navigation`, cost);
} catch (error) {
if (isResponse(error)) {
error.headers.set('X-Modernjs-Catch', 'yes');
response = error;
} else if (isRouteErrorResponse(error)) {
response = errorResponseToJson(error);
} else {
const errorInstance =
error instanceof Error || error instanceof DOMException
? error
: new Error('Unexpected Server Error');

// Handle errors uniformly using the application/json
response = json(serializeError(errorInstance), {
status: 500,
headers: {
'Content-Type': 'application/json; charset=utf-8',
'X-Modernjs-Error': 'yes',
},
});
}
const cost = end();
// add response header for client know if the response is from modern server
response.headers.set('X-Modernjs-Response', 'yes');
onTiming?.(`${LOADER_REPORTER_NAME}-navigation`, cost);
} catch (error) {
if (isResponse(error)) {
error.headers.set('X-Modernjs-Catch', 'yes');
response = error;
} else if (isRouteErrorResponse(error)) {
response = errorResponseToJson(error);
} else {
const errorInstance =
error instanceof Error || error instanceof DOMException
? error
: new Error('Unexpected Server Error');

// Handle errors uniformly using the application/json
response = json(serializeError(errorInstance), {
status: 500,
headers: {
'X-Modernjs-Error': 'yes',
},
});
}
}
}
}

return response as unknown as Response;
return response as unknown as Response;
},
);
};
3 changes: 0 additions & 3 deletions packages/runtime/plugin-runtime/src/core/compatible.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,6 @@ export const useRuntimeContext = () => {
getInitData: () => {
return Object.freeze(context.initialData);
},
getMonitors(): Omit<Monitors, 'push'> {
return baseSSRContext.monitors || {};
},
}
: ({} as TSSRContext);

Expand Down
Loading

0 comments on commit 5111c83

Please sign in to comment.