@modern-js/prod-server 2.35.0 → 2.35.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/cjs/libs/context/context.js +29 -5
  2. package/dist/cjs/libs/preload/flushServerHeader.js +2 -2
  3. package/dist/cjs/libs/preload/parseLinks.js +8 -9
  4. package/dist/cjs/libs/preload/transformLinks2String.js +1 -2
  5. package/dist/cjs/libs/render/cache/__tests__/cache.test.js +7 -12
  6. package/dist/cjs/libs/render/cache/index.js +1 -2
  7. package/dist/cjs/libs/render/cache/spr.js +1 -2
  8. package/dist/cjs/libs/render/index.js +3 -2
  9. package/dist/cjs/libs/render/reader.js +1 -2
  10. package/dist/cjs/libs/route/matcher.js +2 -2
  11. package/dist/cjs/server/index.js +5 -7
  12. package/dist/cjs/server/modernServer.js +25 -27
  13. package/dist/cjs/workerServer.js +5 -6
  14. package/dist/esm/libs/context/context.js +29 -5
  15. package/dist/esm/libs/preload/flushServerHeader.js +3 -3
  16. package/dist/esm/libs/preload/parseLinks.js +7 -8
  17. package/dist/esm/libs/preload/transformLinks2String.js +1 -2
  18. package/dist/esm/libs/render/cache/__tests__/cache.test.js +12 -12
  19. package/dist/esm/libs/render/cache/index.js +2 -2
  20. package/dist/esm/libs/render/cache/spr.js +2 -2
  21. package/dist/esm/libs/render/index.js +5 -2
  22. package/dist/esm/libs/render/reader.js +2 -2
  23. package/dist/esm/libs/route/matcher.js +2 -2
  24. package/dist/esm/server/index.js +6 -8
  25. package/dist/esm/server/modernServer.js +26 -37
  26. package/dist/esm/workerServer.js +5 -6
  27. package/dist/esm-node/libs/context/context.js +29 -5
  28. package/dist/esm-node/libs/preload/flushServerHeader.js +2 -2
  29. package/dist/esm-node/libs/preload/parseLinks.js +7 -8
  30. package/dist/esm-node/libs/preload/transformLinks2String.js +1 -2
  31. package/dist/esm-node/libs/render/cache/__tests__/cache.test.js +7 -12
  32. package/dist/esm-node/libs/render/cache/index.js +1 -2
  33. package/dist/esm-node/libs/render/cache/spr.js +1 -2
  34. package/dist/esm-node/libs/render/index.js +3 -2
  35. package/dist/esm-node/libs/render/reader.js +1 -2
  36. package/dist/esm-node/libs/route/matcher.js +2 -2
  37. package/dist/esm-node/server/index.js +6 -8
  38. package/dist/esm-node/server/modernServer.js +25 -27
  39. package/dist/esm-node/workerServer.js +5 -6
  40. package/dist/types/libs/context/context.d.ts +2 -1
  41. package/dist/types/type.d.ts +1 -0
  42. package/dist/types/utils.d.ts +1 -1
  43. package/package.json +9 -8
  44. package/dist/cjs/libs/logger.js +0 -123
  45. package/dist/esm/libs/logger.js +0 -125
  46. package/dist/esm-node/libs/logger.js +0 -106
  47. package/dist/types/libs/logger.d.ts +0 -61
@@ -1,8 +1,8 @@
1
1
  import path from "path";
2
2
  import { NESTED_ROUTE_SPEC_FILE, ROUTE_MANIFEST_FILE, ROUTE_SPEC_FILE, fs } from "@modern-js/utils";
3
3
  import { parse as htmlParse } from "node-html-parser";
4
- import { matchRoutes } from "@modern-js/utils/runtime/remix-router";
5
- import { matchEntry } from "@modern-js/utils/runtime-node";
4
+ import { matchRoutes } from "@modern-js/runtime-utils/remix-router";
5
+ import { matchEntry } from "@modern-js/runtime-utils/node";
6
6
  export async function parseLinks({ pathname, distDir, template }) {
7
7
  const links = await parseLinksFromRoutes(pathname, distDir);
8
8
  return links.concat(parseLinksFromHtml(template));
@@ -48,7 +48,7 @@ async function parseLinksFromRoutes(pathname, distDir) {
48
48
  const serverRoutes = routesJson.routes;
49
49
  const entry = matchEntry(pathname, serverRoutes);
50
50
  if (entry) {
51
- var _routeAssets_entryName, _matches, _assets_filter, _assets, _assets_filter1, _assets1;
51
+ var _routeAssets_entryName, _assets_filter, _assets_filter1;
52
52
  const routes = await import(nestedRoutesSpec);
53
53
  const { entryName } = entry;
54
54
  if (!entryName) {
@@ -62,23 +62,22 @@ async function parseLinksFromRoutes(pathname, distDir) {
62
62
  const { routeAssets } = routesManifest;
63
63
  const matches = matchRoutes(entryRoutes, pathname, entry.urlPath);
64
64
  const entryAssets = (_routeAssets_entryName = routeAssets[entryName]) === null || _routeAssets_entryName === void 0 ? void 0 : _routeAssets_entryName.assets;
65
- const assets = (_matches = matches) === null || _matches === void 0 ? void 0 : _matches.reduce((acc, match) => {
65
+ const assets = matches === null || matches === void 0 ? void 0 : matches.reduce((acc, match) => {
66
66
  const routeId = match.route.id;
67
67
  if (routeId) {
68
- var _matchedManifest;
69
68
  const matchedManifest = routeAssets[routeId];
70
- const assets2 = (_matchedManifest = matchedManifest) === null || _matchedManifest === void 0 ? void 0 : _matchedManifest.assets;
69
+ const assets2 = matchedManifest === null || matchedManifest === void 0 ? void 0 : matchedManifest.assets;
71
70
  if (Array.isArray(assets2)) {
72
71
  acc.push(...assets2);
73
72
  }
74
73
  }
75
74
  return acc;
76
75
  }, []).concat(entryAssets || []);
77
- const cssLinks = (_assets = assets) === null || _assets === void 0 ? void 0 : (_assets_filter = _assets.filter((asset) => asset.endsWith(".css"))) === null || _assets_filter === void 0 ? void 0 : _assets_filter.map((uri) => ({
76
+ const cssLinks = assets === null || assets === void 0 ? void 0 : (_assets_filter = assets.filter((asset) => asset.endsWith(".css"))) === null || _assets_filter === void 0 ? void 0 : _assets_filter.map((uri) => ({
78
77
  uri,
79
78
  as: "style"
80
79
  }));
81
- const scriptLinks = (_assets1 = assets) === null || _assets1 === void 0 ? void 0 : (_assets_filter1 = _assets1.filter((asset) => asset.endsWith(".js"))) === null || _assets_filter1 === void 0 ? void 0 : _assets_filter1.map((uri) => ({
80
+ const scriptLinks = assets === null || assets === void 0 ? void 0 : (_assets_filter1 = assets.filter((asset) => asset.endsWith(".js"))) === null || _assets_filter1 === void 0 ? void 0 : _assets_filter1.map((uri) => ({
82
81
  uri,
83
82
  as: "script"
84
83
  }));
@@ -8,7 +8,6 @@ export function transformLinks2String(links, preload) {
8
8
  return resolveLinks;
9
9
  }
10
10
  function addInclude(links, include) {
11
- var _include;
12
11
  const images = [
13
12
  "gif",
14
13
  "jpg",
@@ -34,7 +33,7 @@ function addInclude(links, include) {
34
33
  "ttf",
35
34
  "otf"
36
35
  ];
37
- const includes = ((_include = include) === null || _include === void 0 ? void 0 : _include.map((item) => {
36
+ const includes = (include === null || include === void 0 ? void 0 : include.map((item) => {
38
37
  if (typeof item === "string") {
39
38
  const type = (() => {
40
39
  if (item.endsWith(".js")) {
@@ -15,7 +15,6 @@ const createCacheConfig = (config = {}) => ({
15
15
  jest.setTimeout(6e4);
16
16
  describe("cache", () => {
17
17
  it("should cache correctly", async () => {
18
- var _cacheResult;
19
18
  destroyCache();
20
19
  const cache = createCache();
21
20
  const context = {
@@ -29,7 +28,7 @@ describe("cache", () => {
29
28
  await cache.set(context, content, cacheConfig, true);
30
29
  const cacheResult = await cache.get(context);
31
30
  expect(cacheResult).not.toBe(null);
32
- expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe("hello");
31
+ expect(cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.content).toBe("hello");
33
32
  });
34
33
  it("should ignore cache set when cache config not exist", async () => {
35
34
  destroyCache();
@@ -124,7 +123,6 @@ describe("cache", () => {
124
123
  destroyCache();
125
124
  const cache = createCache();
126
125
  for (const cacheable of cacheabelAry) {
127
- var _cacheResult;
128
126
  const context = {
129
127
  entry: "",
130
128
  pathname: cacheable.requestOpt.url,
@@ -134,14 +132,13 @@ describe("cache", () => {
134
132
  const cacheConfig = createCacheConfig(cacheable.cacheConfig || {});
135
133
  await cache.set(context, cacheable.content, cacheConfig, true);
136
134
  const cacheResult = await cache.get(context);
137
- expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe(cacheable.content);
135
+ expect(cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.content).toBe(cacheable.content);
138
136
  }
139
137
  });
140
138
  it("should match cache correctly", async () => {
141
139
  destroyCache();
142
140
  const cache = createCache();
143
141
  for (const cacheable of matchedCacheableAry) {
144
- var _cacheResult;
145
142
  const [baseCacheable, matchOne, ...other] = cacheable;
146
143
  const { requestOpt = {}, cacheConfig, content } = baseCacheable;
147
144
  const context = {
@@ -158,7 +155,7 @@ describe("cache", () => {
158
155
  headers: matchOne.headers
159
156
  };
160
157
  const cacheResult = await cache.get(matchContext);
161
- expect((_cacheResult = cacheResult) === null || _cacheResult === void 0 ? void 0 : _cacheResult.content).toBe(content);
158
+ expect(cacheResult === null || cacheResult === void 0 ? void 0 : cacheResult.content).toBe(content);
162
159
  for (const notMatch of other) {
163
160
  const notMatchContext = {
164
161
  entry: "",
@@ -172,7 +169,6 @@ describe("cache", () => {
172
169
  }
173
170
  });
174
171
  it("should stale cache correctly", async () => {
175
- var _freshResult, _staleResult;
176
172
  destroyCache();
177
173
  const cache = createCache();
178
174
  const context = {
@@ -188,17 +184,16 @@ describe("cache", () => {
188
184
  const shouldCache = await cache.set(context, content, config, true);
189
185
  expect(shouldCache.value).toBe(true);
190
186
  const freshResult = await cache.get(context);
191
- expect((_freshResult = freshResult) === null || _freshResult === void 0 ? void 0 : _freshResult.isStale).toBe(false);
187
+ expect(freshResult === null || freshResult === void 0 ? void 0 : freshResult.isStale).toBe(false);
192
188
  await new Promise((resolve) => {
193
189
  setTimeout(() => {
194
190
  resolve();
195
191
  }, 6e3);
196
192
  });
197
193
  const staleResult = await cache.get(context);
198
- expect((_staleResult = staleResult) === null || _staleResult === void 0 ? void 0 : _staleResult.isStale).toBe(true);
194
+ expect(staleResult === null || staleResult === void 0 ? void 0 : staleResult.isStale).toBe(true);
199
195
  });
200
196
  it("should garbage cache correctly", async () => {
201
- var _freshResult, _staleResult;
202
197
  destroyCache();
203
198
  const cache = createCache();
204
199
  const context = {
@@ -215,13 +210,13 @@ describe("cache", () => {
215
210
  const shouldCache = await cache.set(context, content, config, true);
216
211
  expect(shouldCache.value).toBe(true);
217
212
  const freshResult = await cache.get(context);
218
- expect((_freshResult = freshResult) === null || _freshResult === void 0 ? void 0 : _freshResult.isGarbage).toBe(false);
213
+ expect(freshResult === null || freshResult === void 0 ? void 0 : freshResult.isGarbage).toBe(false);
219
214
  await new Promise((resolve) => {
220
215
  setTimeout(() => {
221
216
  resolve();
222
217
  }, 1e4);
223
218
  });
224
219
  const staleResult = await cache.get(context);
225
- expect((_staleResult = staleResult) === null || _staleResult === void 0 ? void 0 : _staleResult.isGarbage).toBe(true);
220
+ expect(staleResult === null || staleResult === void 0 ? void 0 : staleResult.isGarbage).toBe(true);
226
221
  });
227
222
  });
@@ -5,7 +5,6 @@ import { namespaceHash, withCoalescedInvoke } from "./util";
5
5
  export default (renderFn, ctx) => {
6
6
  const sprCache = createCache();
7
7
  const doRender = async (context) => {
8
- var _cacheFile;
9
8
  const cacheContext = {
10
9
  entry: context.entryName,
11
10
  ...context.request
@@ -41,7 +40,7 @@ export default (renderFn, ctx) => {
41
40
  const renderResult = await renderFn(context);
42
41
  return afterRender(renderResult, saveHtmlIntoCache);
43
42
  }
44
- const cacheHash = (_cacheFile = cacheFile) === null || _cacheFile === void 0 ? void 0 : _cacheFile.hash;
43
+ const cacheHash = cacheFile === null || cacheFile === void 0 ? void 0 : cacheFile.hash;
45
44
  if (cacheFile.isGarbage) {
46
45
  const renderResult = await renderFn(context);
47
46
  return afterRender(renderResult, saveHtmlIntoCache);
@@ -141,10 +141,9 @@ class CacheManager {
141
141
  return maybeSync(doCache)(sync);
142
142
  }
143
143
  async del(context, cacheHash) {
144
- var _data;
145
144
  const cacheKey = this.generateRequestKey(context);
146
145
  const data = this.cache.get(cacheKey);
147
- (_data = data) === null || _data === void 0 ? void 0 : _data.caches.del(cacheHash);
146
+ data === null || data === void 0 ? void 0 : data.caches.del(cacheHash);
148
147
  }
149
148
  constructor(cacheOptions) {
150
149
  _define_property(this, "cache", void 0);
@@ -6,6 +6,7 @@ import { handleDirectory } from "./static";
6
6
  import { readFile } from "./reader";
7
7
  import * as ssr from "./ssr";
8
8
  import { injectServerData } from "./utils";
9
+ const calcFallback = (metaName) => `x-${cutNameByHyphen(metaName)}-ssr-fallback`;
9
10
  export const createRenderHandler = ({ distDir, staticGenerate, conf, forceCSR, nonce, ssrRender, metaName = "modern-js" }) => async function render({ ctx, route, runner }) {
10
11
  if (ctx.resHasHandled()) {
11
12
  return null;
@@ -21,7 +22,7 @@ export const createRenderHandler = ({ distDir, staticGenerate, conf, forceCSR, n
21
22
  if (!content) {
22
23
  return null;
23
24
  }
24
- const useCSR = forceCSR && (ctx.query.csr || ctx.headers[`x-${cutNameByHyphen(metaName)}-ssr-fallback`]);
25
+ const useCSR = forceCSR && (ctx.query.csr || ctx.headers[calcFallback(metaName)]);
25
26
  if (route.isSSR && !useCSR) {
26
27
  try {
27
28
  const userAgent = ctx.getReqHeader("User-Agent");
@@ -59,7 +60,7 @@ export const createRenderHandler = ({ distDir, staticGenerate, conf, forceCSR, n
59
60
  return result;
60
61
  } catch (err) {
61
62
  ctx.error(ERROR_DIGEST.ERENDER, err.stack || err.message);
62
- ctx.res.set("x-modern-ssr-fallback", "1");
63
+ ctx.res.set(calcFallback(metaName), "1");
63
64
  }
64
65
  }
65
66
  return {
@@ -72,9 +72,8 @@ export class LruReader {
72
72
  }
73
73
  const reader = new LruReader();
74
74
  export const readFile = async (filepath) => {
75
- var _file;
76
75
  const file = await reader.read(filepath);
77
- return (_file = file) === null || _file === void 0 ? void 0 : _file.content;
76
+ return file === null || file === void 0 ? void 0 : file.content;
78
77
  };
79
78
  export const updateFile = () => {
80
79
  reader.update();
@@ -39,9 +39,9 @@ export class RouteMatcher {
39
39
  if (!this.urlReg) {
40
40
  return this.urlPath.length;
41
41
  } else {
42
- var _result_, _result;
42
+ var _result_;
43
43
  const result = this.urlReg.exec(pathname);
44
- return ((_result = result) === null || _result === void 0 ? void 0 : (_result_ = _result[0]) === null || _result_ === void 0 ? void 0 : _result_.length) || null;
44
+ return (result === null || result === void 0 ? void 0 : (_result_ = result[0]) === null || _result_ === void 0 ? void 0 : _result_.length) || null;
45
45
  }
46
46
  }
47
47
  // if match url path
@@ -1,6 +1,6 @@
1
1
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
2
  import path from "path";
3
- import { fs, Logger, SHARED_DIR, OUTPUT_CONFIG_FILE, dotenv, dotenvExpand, INTERNAL_SERVER_PLUGINS } from "@modern-js/utils";
3
+ import { fs, Logger, SHARED_DIR, OUTPUT_CONFIG_FILE, dotenv, dotenvExpand, INTERNAL_SERVER_PLUGINS, ensureAbsolutePath } from "@modern-js/utils";
4
4
  import { serverManager, AppContext, ConfigContext, loadPlugins } from "@modern-js/server-core";
5
5
  import { metrics as defaultMetrics } from "../libs/metrics";
6
6
  import { loadConfig, getServerConfigPath, requireConfig } from "../libs/loadConfig";
@@ -80,7 +80,7 @@ export class Server {
80
80
  const { pwd, config } = options;
81
81
  const { serverConfig } = this;
82
82
  const finalServerConfig = this.runConfigHook(runner, serverConfig);
83
- const resolvedConfigPath = path.join(pwd, config.output.path || "dist", OUTPUT_CONFIG_FILE);
83
+ const resolvedConfigPath = ensureAbsolutePath(pwd, path.join(config.output.path || "dist", OUTPUT_CONFIG_FILE));
84
84
  options.config = loadConfig({
85
85
  cliConfig: config,
86
86
  serverConfig: finalServerConfig,
@@ -92,8 +92,7 @@ export class Server {
92
92
  }
93
93
  listen(options, listener) {
94
94
  const callback = () => {
95
- var _listener;
96
- (_listener = listener) === null || _listener === void 0 ? void 0 : _listener();
95
+ listener === null || listener === void 0 ? void 0 : listener();
97
96
  };
98
97
  if (typeof options === "object") {
99
98
  if (process.env.PORT) {
@@ -143,7 +142,6 @@ export class Server {
143
142
  });
144
143
  }
145
144
  initAppContext() {
146
- var _appContext, _appContext1, _appContext2;
147
145
  const { options } = this;
148
146
  const { pwd: appDirectory, plugins = [], config, appContext } = options;
149
147
  const serverPlugins = plugins.map((p) => ({
@@ -151,9 +149,9 @@ export class Server {
151
149
  }));
152
150
  return {
153
151
  appDirectory,
154
- apiDirectory: (_appContext = appContext) === null || _appContext === void 0 ? void 0 : _appContext.apiDirectory,
155
- lambdaDirectory: (_appContext1 = appContext) === null || _appContext1 === void 0 ? void 0 : _appContext1.lambdaDirectory,
156
- sharedDirectory: ((_appContext2 = appContext) === null || _appContext2 === void 0 ? void 0 : _appContext2.sharedDirectory) || path.resolve(appDirectory, SHARED_DIR),
152
+ apiDirectory: appContext === null || appContext === void 0 ? void 0 : appContext.apiDirectory,
153
+ lambdaDirectory: appContext === null || appContext === void 0 ? void 0 : appContext.lambdaDirectory,
154
+ sharedDirectory: (appContext === null || appContext === void 0 ? void 0 : appContext.sharedDirectory) || path.resolve(appDirectory, SHARED_DIR),
157
155
  distDirectory: path.join(appDirectory, config.output.path || "dist"),
158
156
  plugins: serverPlugins
159
157
  };
@@ -2,7 +2,7 @@ import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
2
  import { createServer } from "http";
3
3
  import path from "path";
4
4
  import { fs, isPromise, isWebOnly, mime, ROUTE_SPEC_FILE } from "@modern-js/utils";
5
- import { time } from "@modern-js/utils/universal/time";
5
+ import { time } from "@modern-js/runtime-utils/time";
6
6
  import { RouteMatchManager } from "../libs/route";
7
7
  import { createRenderHandler } from "../libs/render";
8
8
  import { createStaticFileHandler, faviconFallbackHandler } from "../libs/serveFile";
@@ -16,7 +16,7 @@ const SERVER_DIR = "./server";
16
16
  export class ModernServer {
17
17
  // server prepare
18
18
  async onInit(runner, app) {
19
- var _conf_bff, _app, _this_conf_output;
19
+ var _conf_bff, _this_conf_output;
20
20
  this.runner = runner;
21
21
  const { distDir, conf } = this;
22
22
  this.initReader();
@@ -28,7 +28,7 @@ export class ModernServer {
28
28
  this.addHandler(handler);
29
29
  });
30
30
  }
31
- (_app = app) === null || _app === void 0 ? void 0 : _app.on("close", () => {
31
+ app === null || app === void 0 ? void 0 : app.on("close", () => {
32
32
  this.reader.close();
33
33
  });
34
34
  const usageRoutes = this.filterRoutes(this.getRoutes());
@@ -164,10 +164,9 @@ export class ModernServer {
164
164
  return handler;
165
165
  }
166
166
  async prepareAPIHandler(extension) {
167
- var _bff, _bff1;
168
167
  const { workDir, runner, conf } = this;
169
168
  const { bff } = conf;
170
- const prefix = ((_bff = bff) === null || _bff === void 0 ? void 0 : _bff.prefix) || "/api";
169
+ const prefix = (bff === null || bff === void 0 ? void 0 : bff.prefix) || "/api";
171
170
  const webOnly = await isWebOnly();
172
171
  if (webOnly && process.env.NODE_ENV === "development") {
173
172
  return (req, res) => {
@@ -179,7 +178,7 @@ export class ModernServer {
179
178
  pwd: workDir,
180
179
  config: extension,
181
180
  prefix: Array.isArray(prefix) ? prefix[0] : prefix,
182
- httpMethodDecider: (_bff1 = bff) === null || _bff1 === void 0 ? void 0 : _bff1.httpMethodDecider,
181
+ httpMethodDecider: bff === null || bff === void 0 ? void 0 : bff.httpMethodDecider,
183
182
  render: this.render.bind(this)
184
183
  }, {
185
184
  onLast: () => null
@@ -290,16 +289,14 @@ export class ModernServer {
290
289
  await this.handleAPI(context);
291
290
  return;
292
291
  }
293
- if (route.entryName) {
292
+ if (route.entryName && this.runMode === RUN_MODE.FULL) {
294
293
  const afterMatchContext = createAfterMatchContext(context, route.entryName);
295
- if (this.runMode === RUN_MODE.FULL) {
296
- const end2 = time();
297
- await this.runner.afterMatch(afterMatchContext, {
298
- onLast: noop
299
- });
300
- const cost = end2();
301
- cost && reporter.reportTiming(ServerReportTimings.SERVER_HOOK_AFTER_MATCH, cost);
302
- }
294
+ const end2 = time();
295
+ await this.runner.afterMatch(afterMatchContext, {
296
+ onLast: noop
297
+ });
298
+ const cost = end2();
299
+ cost && reporter.reportTiming(ServerReportTimings.SERVER_HOOK_AFTER_MATCH, cost);
303
300
  if (this.isSend(res)) {
304
301
  return;
305
302
  }
@@ -342,16 +339,14 @@ export class ModernServer {
342
339
  responseStream.pipe(res);
343
340
  return;
344
341
  }
345
- if (route.entryName) {
342
+ if (route.entryName && this.runMode === RUN_MODE.FULL) {
346
343
  const afterRenderContext = createAfterRenderContext(context, response.toString());
347
- if (this.runMode === RUN_MODE.FULL) {
348
- const end2 = time();
349
- await this.runner.afterRender(afterRenderContext, {
350
- onLast: noop
351
- });
352
- const cost = end2();
353
- cost && reporter.reportTiming(ServerReportTimings.SERVER_HOOK_AFTER_RENDER, cost);
354
- }
344
+ const end2 = time();
345
+ await this.runner.afterRender(afterRenderContext, {
346
+ onLast: noop
347
+ });
348
+ const cost = end2();
349
+ cost && reporter.reportTiming(ServerReportTimings.SERVER_HOOK_AFTER_RENDER, cost);
355
350
  if (this.isSend(res)) {
356
351
  return;
357
352
  }
@@ -360,7 +355,11 @@ export class ModernServer {
360
355
  res.end(response);
361
356
  }
362
357
  isSend(res) {
363
- if (res.writableEnded) {
358
+ if (res.modernFlushedHeaders) {
359
+ if (res.writableFinished) {
360
+ return true;
361
+ }
362
+ } else if (res.headersSent) {
364
363
  return true;
365
364
  }
366
365
  if (res.getHeader("Location") && isRedirect(res.statusCode)) {
@@ -465,7 +464,6 @@ export class ModernServer {
465
464
  context.res.end(createErrorDocument(status, text));
466
465
  }
467
466
  constructor({ pwd, config, routes, staticGenerate, logger, metrics, runMode, proxyTarget, appContext }) {
468
- var _appContext;
469
467
  _define_property(this, "pwd", void 0);
470
468
  _define_property(this, "distDir", void 0);
471
469
  _define_property(this, "workDir", void 0);
@@ -499,6 +497,6 @@ export class ModernServer {
499
497
  this.proxyTarget = proxyTarget;
500
498
  this.staticGenerate = staticGenerate || false;
501
499
  this.runMode = runMode || RUN_MODE.FULL;
502
- this.metaName = (_appContext = appContext) === null || _appContext === void 0 ? void 0 : _appContext.metaName;
500
+ this.metaName = appContext === null || appContext === void 0 ? void 0 : appContext.metaName;
503
501
  }
504
502
  }
@@ -1,7 +1,7 @@
1
1
  import { _ as _define_property } from "@swc/helpers/_/_define_property";
2
2
  import { createAsyncPipeline } from "@modern-js/plugin";
3
+ import { Logger } from "@modern-js/utils/logger";
3
4
  import { createAfterMatchContext, createAfterRenderContext, createMiddlewareContext } from "./libs/hook-api/index.worker";
4
- import { Logger } from "./libs/logger";
5
5
  import { RouteMatchManager } from "./libs/route";
6
6
  import { metrics as defaultMetrics } from "./libs/metrics";
7
7
  import { defaultReporter } from "./libs/reporter";
@@ -70,7 +70,7 @@ export const createHandler = (manifest) => {
70
70
  const { pages, routes } = manifest;
71
71
  routeMgr.reset(routes);
72
72
  return async (options) => {
73
- var _page_serverHooks_afterMatch, _page_serverHooks, _page;
73
+ var _page_serverHooks_afterMatch, _page_serverHooks;
74
74
  const { request, loadableStats, routeManifest } = options;
75
75
  const url = new URL(request.url);
76
76
  const pageMatch = routeMgr.match(url.pathname);
@@ -86,7 +86,7 @@ export const createHandler = (manifest) => {
86
86
  const reporter = defaultReporter;
87
87
  const hookContext = createWorkerHookContext(request.url, logger, metrics, reporter);
88
88
  const afterMatchHookContext = createAfterMatchContext(hookContext, entryName);
89
- (_page = page) === null || _page === void 0 ? void 0 : (_page_serverHooks = _page.serverHooks) === null || _page_serverHooks === void 0 ? void 0 : (_page_serverHooks_afterMatch = _page_serverHooks.afterMatch) === null || _page_serverHooks_afterMatch === void 0 ? void 0 : _page_serverHooks_afterMatch.call(_page_serverHooks, afterMatchHookContext, () => void 0);
89
+ page === null || page === void 0 ? void 0 : (_page_serverHooks = page.serverHooks) === null || _page_serverHooks === void 0 ? void 0 : (_page_serverHooks_afterMatch = _page_serverHooks.afterMatch) === null || _page_serverHooks_afterMatch === void 0 ? void 0 : _page_serverHooks_afterMatch.call(_page_serverHooks, afterMatchHookContext, () => void 0);
90
90
  if (checkIsSent(hookContext)) {
91
91
  return new ReturnResponse(hookContext.res.body || "Unkown body", hookContext.res.status, hookContext.res.headers);
92
92
  }
@@ -122,14 +122,13 @@ export const createHandler = (manifest) => {
122
122
  logger,
123
123
  reporter: defaultReporter,
124
124
  metrics,
125
- // FIXME: pass correctly req & res
126
125
  req: request,
126
+ res: responseLike,
127
127
  serverTiming: {
128
128
  addServeTiming() {
129
129
  return this;
130
130
  }
131
- },
132
- res: responseLike
131
+ }
133
132
  };
134
133
  const body = await page.serverRender(serverRenderContext);
135
134
  const afterRenderHookContext = createAfterRenderContext(hookContext, body);
@@ -2,7 +2,7 @@
2
2
  /// <reference types="node" />
3
3
  /// <reference types="node" />
4
4
  /// <reference types="node/http" />
5
- /// <reference types=".dts-temp/bmyOg3OGCKlzOU69708oM/src/type" />
5
+ /// <reference types=".dts-temp/ZUvIIbCulxIv-S9jEs5YO/src/type" />
6
6
  import { IncomingMessage, ServerResponse } from 'http';
7
7
  import qs from 'querystring';
8
8
  import type { ModernServerContext as ModernServerContextInterface, Reporter as ModernServerReporter, ServerTiming as ModernServerTiming } from '@modern-js/types';
@@ -12,6 +12,7 @@ export type ContextOptions = {
12
12
  };
13
13
  type ResponseBody = string | Buffer;
14
14
  export declare class ModernServerContext implements ModernServerContextInterface {
15
+ #private;
15
16
  /**
16
17
  * http request
17
18
  */
@@ -15,6 +15,7 @@ declare module 'http' {
15
15
  }
16
16
  interface OutgoingMessage {
17
17
  set: (key: string, value: any) => this;
18
+ modernFlushedHeaders?: boolean;
18
19
  }
19
20
  }
20
21
  export type ModernServerOptions = {
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node/http" />
3
- /// <reference types=".dts-temp/bmyOg3OGCKlzOU69708oM/src/type" />
3
+ /// <reference types=".dts-temp/ZUvIIbCulxIv-S9jEs5YO/src/type" />
4
4
  import { IncomingMessage } from 'http';
5
5
  import type { OutputNormalizedConfig, HtmlNormalizedConfig } from '@modern-js/server-core';
6
6
  export declare const debug: any;
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "2.35.0",
18
+ "version": "2.35.1",
19
19
  "jsnext:source": "./src/index.ts",
20
20
  "types": "./dist/types/index.d.ts",
21
21
  "main": "./dist/cjs/index.js",
@@ -74,9 +74,10 @@
74
74
  "node-html-parser": "^6.1.5",
75
75
  "path-to-regexp": "^6.2.0",
76
76
  "serve-static": "^1.14.1",
77
- "@modern-js/plugin": "2.35.0",
78
- "@modern-js/utils": "2.35.0",
79
- "@modern-js/server-core": "2.35.0"
77
+ "@modern-js/plugin": "2.35.1",
78
+ "@modern-js/server-core": "2.35.1",
79
+ "@modern-js/utils": "2.35.1",
80
+ "@modern-js/runtime-utils": "2.35.1"
80
81
  },
81
82
  "devDependencies": {
82
83
  "@types/cookie": "^0.4.1",
@@ -95,10 +96,10 @@
95
96
  "portfinder": "^1.0.28",
96
97
  "typescript": "^5",
97
98
  "ws": "^8.13.0",
98
- "@modern-js/server-core": "2.35.0",
99
- "@modern-js/types": "2.35.0",
100
- "@scripts/build": "2.35.0",
101
- "@scripts/jest-config": "2.35.0"
99
+ "@modern-js/server-core": "2.35.1",
100
+ "@modern-js/types": "2.35.1",
101
+ "@scripts/build": "2.35.1",
102
+ "@scripts/jest-config": "2.35.1"
102
103
  },
103
104
  "sideEffects": false,
104
105
  "publishConfig": {
@@ -1,123 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for (var name in all)
7
- Object.defineProperty(target, name, {
8
- enumerable: true,
9
- get: all[name]
10
- });
11
- }
12
- _export(exports, {
13
- Logger: function() {
14
- return Logger;
15
- },
16
- logger: function() {
17
- return logger;
18
- }
19
- });
20
- const _define_property = require("@swc/helpers/_/_define_property");
21
- const LOG_LEVEL = {
22
- error: 0,
23
- warn: 1,
24
- info: 2,
25
- debug: 3,
26
- log: 4
27
- };
28
- const LOG_TYPES = {
29
- error: {
30
- color: "red",
31
- label: "error",
32
- level: "error"
33
- },
34
- info: {
35
- color: "cyan",
36
- label: "info",
37
- level: "info"
38
- },
39
- success: {
40
- color: "green",
41
- label: "Success",
42
- level: "info"
43
- },
44
- warn: {
45
- color: "yellow",
46
- label: "warn",
47
- level: "warn"
48
- },
49
- debug: {
50
- color: "red",
51
- label: "debug",
52
- level: "debug"
53
- },
54
- log: {
55
- level: "log"
56
- }
57
- };
58
- const DEFAULT_CONFIG = {
59
- displayLabel: true,
60
- uppercaseLabel: false
61
- };
62
- class Logger {
63
- _log(type, message, ...args) {
64
- if (message === void 0 || message === null) {
65
- console.log();
66
- return;
67
- }
68
- if (LOG_LEVEL[type] > LOG_LEVEL[this.level]) {
69
- return;
70
- }
71
- let label = "";
72
- let text = "";
73
- const logType = this.types[type];
74
- if (this.config.displayLabel && logType.label) {
75
- label = this.config.uppercaseLabel ? logType.label.toUpperCase() : logType.label;
76
- label = label.padEnd(this.longestLabel.length);
77
- }
78
- if (message instanceof Error) {
79
- if (message.stack) {
80
- const [name, ...rest] = message.stack.split("\n");
81
- text = `${name}
82
- ${rest.join("\n")}`;
83
- } else {
84
- text = message.message;
85
- }
86
- } else {
87
- text = `${message}`;
88
- }
89
- const log = label.length > 0 ? `${label} ${text}` : text;
90
- console.log(log, ...args);
91
- }
92
- getLongestLabel() {
93
- let longestLabel = "";
94
- Object.keys(this.types).forEach((type) => {
95
- const { label = "" } = this.types[type];
96
- if (label.length > longestLabel.length) {
97
- longestLabel = label;
98
- }
99
- });
100
- return longestLabel;
101
- }
102
- constructor(options = {}) {
103
- _define_property._(this, "level", void 0);
104
- _define_property._(this, "config", void 0);
105
- _define_property._(this, "types", void 0);
106
- _define_property._(this, "longestLabel", void 0);
107
- this.level = options.level || LOG_TYPES.log.level;
108
- this.config = {
109
- ...DEFAULT_CONFIG,
110
- ...options.config || {}
111
- };
112
- this.types = {
113
- ...LOG_TYPES,
114
- ...options.types || {}
115
- };
116
- this.longestLabel = this.getLongestLabel();
117
- Object.keys(this.types).forEach((type) => {
118
- this[type] = this._log.bind(this, type);
119
- });
120
- }
121
- }
122
- const logger = new Logger();
123
- logger.Logger = Logger;