@modern-js/plugin-data-loader 0.0.0-next-20240320040617 → 0.0.0-next-20240320180839

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.
@@ -23,14 +23,16 @@ __export(runtime_exports, {
23
23
  isResponse: () => isResponse
24
24
  });
25
25
  module.exports = __toCommonJS(runtime_exports);
26
+ var import_node = require("@remix-run/node");
26
27
  var import_remix_router = require("@modern-js/runtime-utils/remix-router");
27
28
  var import_browser = require("@modern-js/runtime-utils/browser");
28
29
  var import_lodash = require("@modern-js/utils/lodash");
29
- var import_node = require("@modern-js/runtime-utils/node");
30
+ var import_node2 = require("@modern-js/runtime-utils/node");
30
31
  var import_time = require("@modern-js/runtime-utils/time");
31
32
  var import_constants = require("@modern-js/utils/universal/constants");
32
33
  var import_constants2 = require("../common/constants");
33
34
  var import_response = require("./response");
35
+ (0, import_node.installGlobals)();
34
36
  const redirectStatusCodes = /* @__PURE__ */ new Set([
35
37
  301,
36
38
  302,
@@ -52,27 +54,73 @@ function convertModernRedirectResponse(headers, basename) {
52
54
  }
53
55
  newHeaders.set("X-Modernjs-Redirect", redirectUrl);
54
56
  newHeaders.delete("Location");
55
- return new Response(null, {
57
+ return new import_node.Response(null, {
56
58
  status: 204,
57
59
  headers: newHeaders
58
60
  });
59
61
  }
60
- const handleRequest = async ({ request, serverRoutes, routes: routesConfig, context }) => {
61
- const url = new URL(request.url);
62
- const routeId = url.searchParams.get(import_constants2.LOADER_ID_PARAM);
63
- const entry = (0, import_node.matchEntry)(url.pathname, serverRoutes);
62
+ const createLoaderHeaders = (requestHeaders) => {
63
+ const headers = new Headers();
64
+ for (const [key, values] of Object.entries(requestHeaders)) {
65
+ if (values) {
66
+ if (Array.isArray(values)) {
67
+ for (const value of values) {
68
+ headers.append(key, value);
69
+ }
70
+ } else {
71
+ headers.set(key, values);
72
+ }
73
+ }
74
+ }
75
+ return headers;
76
+ };
77
+ const createRequest = (context) => {
78
+ const origin = `${context.protocol}://${context.host}`;
79
+ const url = new URL(context.url, origin);
80
+ const controller = new AbortController();
81
+ const init = {
82
+ method: context.method,
83
+ headers: createLoaderHeaders(context.headers),
84
+ signal: controller.signal
85
+ };
86
+ if (![
87
+ "GET",
88
+ "HEAD"
89
+ ].includes(context.method.toUpperCase())) {
90
+ init.body = context.req;
91
+ }
92
+ const request = new Request(url.href, init);
93
+ return request;
94
+ };
95
+ const sendLoaderResponse = async (res, nodeResponse) => {
96
+ res.statusMessage = nodeResponse.statusText;
97
+ res.statusCode = nodeResponse.status;
98
+ for (const [key, value] of nodeResponse.headers.entries()) {
99
+ res.setHeader(key, value);
100
+ }
101
+ if (nodeResponse.body) {
102
+ await (0, import_node.writeReadableStreamToWritable)(nodeResponse.body, res);
103
+ } else {
104
+ res.end();
105
+ }
106
+ };
107
+ const handleRequest = async ({ context, serverRoutes, routes: routesConfig }) => {
108
+ const { query } = context;
109
+ const routeId = query[import_constants2.LOADER_ID_PARAM];
110
+ const entry = (0, import_node2.matchEntry)(context.path, serverRoutes);
64
111
  if (!routeId || !entry) {
65
112
  return;
66
113
  }
67
114
  const basename = entry.urlPath;
68
115
  const end = (0, import_time.time)();
69
- const { logger, reporter } = context;
116
+ const { res, logger, reporter } = context;
70
117
  const routes = (0, import_browser.transformNestedRoutes)(routesConfig, reporter);
71
118
  const { queryRoute } = (0, import_remix_router.createStaticHandler)(routes, {
72
119
  basename
73
120
  });
74
- const requestContext = (0, import_node.createRequestContext)();
75
- requestContext.set(import_node.reporterCtx, reporter);
121
+ const request = createRequest(context);
122
+ const requestContext = (0, import_node2.createRequestContext)();
123
+ requestContext.set(import_node2.reporterCtx, reporter);
76
124
  let response;
77
125
  try {
78
126
  response = await queryRoute(request, {
@@ -94,17 +142,15 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
94
142
  const headers = new Headers(init.headers);
95
143
  headers.set("Content-Type", `${import_constants2.CONTENT_TYPE_DEFERRED}; charset=UTF-8`);
96
144
  init.headers = headers;
97
- response = new Response(body, init);
145
+ response = new import_node.Response(body, init);
98
146
  }
99
147
  } else {
100
- response = isResponse(response) ? response : new Response(JSON.stringify(response), {
148
+ response = isResponse(response) ? response : new import_node.Response(JSON.stringify(response), {
101
149
  headers: {
102
150
  "Content-Type": "application/json; charset=utf-8"
103
151
  }
104
152
  });
105
153
  }
106
- const cost = end();
107
- reporter === null || reporter === void 0 ? void 0 : reporter.reportTiming(`${import_constants.LOADER_REPORTER_NAME}-navigation`, cost);
108
154
  } catch (error) {
109
155
  const message = (0, import_remix_router.isRouteErrorResponse)(error) ? error.data : String(error);
110
156
  if (error instanceof Error) {
@@ -112,14 +158,16 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
112
158
  } else {
113
159
  logger === null || logger === void 0 ? void 0 : logger.error(message);
114
160
  }
115
- response = new Response(message, {
161
+ response = new import_node.Response(message, {
116
162
  status: 500,
117
163
  headers: {
118
164
  "Content-Type": "text/plain"
119
165
  }
120
166
  });
121
167
  }
122
- return response;
168
+ const cost = end();
169
+ reporter.reportTiming(`${import_constants.LOADER_REPORTER_NAME}-navigation`, cost);
170
+ await sendLoaderResponse(res, response);
123
171
  };
124
172
  // Annotate the CommonJS export names for ESM import in node:
125
173
  0 && (module.exports = {
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var server_exports = {};
30
+ __export(server_exports, {
31
+ default: () => server_default
32
+ });
33
+ module.exports = __toCommonJS(server_exports);
34
+ var import_path = __toESM(require("path"));
35
+ var import_fs = __toESM(require("fs"));
36
+ var import_utils = require("@modern-js/utils");
37
+ var import_node = require("@modern-js/runtime-utils/node");
38
+ var server_default = () => ({
39
+ name: "@modern-js/plugin-data-loader",
40
+ setup: () => ({
41
+ prepareLoaderHandler({ serverRoutes, distDir }) {
42
+ return async (context) => {
43
+ const entry = (0, import_node.matchEntry)(context.path, serverRoutes);
44
+ if (!entry) {
45
+ return;
46
+ }
47
+ const routesPath = import_path.default.join(distDir, import_utils.SERVER_BUNDLE_DIRECTORY, `${entry.entryName || import_utils.MAIN_ENTRY_NAME}-server-loaders.js`);
48
+ if (!import_fs.default.existsSync(routesPath)) {
49
+ return;
50
+ }
51
+ const { routes, handleRequest } = await Promise.resolve().then(() => __toESM(require(routesPath)));
52
+ if (!routes) {
53
+ return;
54
+ }
55
+ return handleRequest({
56
+ serverRoutes,
57
+ context,
58
+ routes
59
+ });
60
+ };
61
+ }
62
+ })
63
+ });
@@ -1,6 +1,8 @@
1
1
  import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
2
  import { _ as _instanceof } from "@swc/helpers/_/_instanceof";
3
+ import { _ as _sliced_to_array } from "@swc/helpers/_/_sliced_to_array";
3
4
  import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
5
+ import { installGlobals, writeReadableStreamToWritable, Response as NodeResponse } from "@remix-run/node";
4
6
  import { createStaticHandler, UNSAFE_DEFERRED_SYMBOL as DEFERRED_SYMBOL, isRouteErrorResponse } from "@modern-js/runtime-utils/remix-router";
5
7
  import { transformNestedRoutes } from "@modern-js/runtime-utils/browser";
6
8
  import { isPlainObject } from "@modern-js/utils/lodash";
@@ -9,6 +11,7 @@ import { time } from "@modern-js/runtime-utils/time";
9
11
  import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
10
12
  import { CONTENT_TYPE_DEFERRED, LOADER_ID_PARAM } from "../common/constants";
11
13
  import { createDeferredReadableStream } from "./response";
14
+ installGlobals();
12
15
  var redirectStatusCodes = /* @__PURE__ */ new Set([
13
16
  301,
14
17
  302,
@@ -30,21 +33,145 @@ function convertModernRedirectResponse(headers, basename) {
30
33
  }
31
34
  newHeaders.set("X-Modernjs-Redirect", redirectUrl);
32
35
  newHeaders.delete("Location");
33
- return new Response(null, {
36
+ return new NodeResponse(null, {
34
37
  status: 204,
35
38
  headers: newHeaders
36
39
  });
37
40
  }
41
+ var createLoaderHeaders = function(requestHeaders) {
42
+ var headers = new Headers();
43
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
44
+ try {
45
+ for (var _iterator = Object.entries(requestHeaders)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
46
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], values = _step_value[1];
47
+ if (values) {
48
+ if (Array.isArray(values)) {
49
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = void 0;
50
+ try {
51
+ for (var _iterator1 = values[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true) {
52
+ var value = _step1.value;
53
+ headers.append(key, value);
54
+ }
55
+ } catch (err) {
56
+ _didIteratorError1 = true;
57
+ _iteratorError1 = err;
58
+ } finally {
59
+ try {
60
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
61
+ _iterator1.return();
62
+ }
63
+ } finally {
64
+ if (_didIteratorError1) {
65
+ throw _iteratorError1;
66
+ }
67
+ }
68
+ }
69
+ } else {
70
+ headers.set(key, values);
71
+ }
72
+ }
73
+ }
74
+ } catch (err) {
75
+ _didIteratorError = true;
76
+ _iteratorError = err;
77
+ } finally {
78
+ try {
79
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
80
+ _iterator.return();
81
+ }
82
+ } finally {
83
+ if (_didIteratorError) {
84
+ throw _iteratorError;
85
+ }
86
+ }
87
+ }
88
+ return headers;
89
+ };
90
+ var createRequest = function(context) {
91
+ var origin = "".concat(context.protocol, "://").concat(context.host);
92
+ var url = new URL(context.url, origin);
93
+ var controller = new AbortController();
94
+ var init = {
95
+ method: context.method,
96
+ headers: createLoaderHeaders(context.headers),
97
+ signal: controller.signal
98
+ };
99
+ if (![
100
+ "GET",
101
+ "HEAD"
102
+ ].includes(context.method.toUpperCase())) {
103
+ init.body = context.req;
104
+ }
105
+ var request = new Request(url.href, init);
106
+ return request;
107
+ };
108
+ var sendLoaderResponse = function() {
109
+ var _ref = _async_to_generator(function(res, nodeResponse) {
110
+ var _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, _step_value, key, value;
111
+ return _ts_generator(this, function(_state) {
112
+ switch (_state.label) {
113
+ case 0:
114
+ res.statusMessage = nodeResponse.statusText;
115
+ res.statusCode = nodeResponse.status;
116
+ _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = void 0;
117
+ try {
118
+ for (_iterator = nodeResponse.headers.entries()[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
119
+ _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
120
+ res.setHeader(key, value);
121
+ }
122
+ } catch (err) {
123
+ _didIteratorError = true;
124
+ _iteratorError = err;
125
+ } finally {
126
+ try {
127
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
128
+ _iterator.return();
129
+ }
130
+ } finally {
131
+ if (_didIteratorError) {
132
+ throw _iteratorError;
133
+ }
134
+ }
135
+ }
136
+ if (!nodeResponse.body)
137
+ return [
138
+ 3,
139
+ 2
140
+ ];
141
+ return [
142
+ 4,
143
+ writeReadableStreamToWritable(nodeResponse.body, res)
144
+ ];
145
+ case 1:
146
+ _state.sent();
147
+ return [
148
+ 3,
149
+ 3
150
+ ];
151
+ case 2:
152
+ res.end();
153
+ _state.label = 3;
154
+ case 3:
155
+ return [
156
+ 2
157
+ ];
158
+ }
159
+ });
160
+ });
161
+ return function sendLoaderResponse2(res, nodeResponse) {
162
+ return _ref.apply(this, arguments);
163
+ };
164
+ }();
38
165
  var handleRequest = function() {
39
166
  var _ref = _async_to_generator(function(param) {
40
- var request, serverRoutes, routesConfig, context, url, routeId, entry, basename, end, logger, reporter, routes, queryRoute, requestContext, response, deferredData, body, init, headers, cost, error, message;
167
+ var context, serverRoutes, routesConfig, query, routeId, entry, basename, end, res, logger, reporter, routes, queryRoute, request, requestContext, response, deferredData, body, init, headers, error, message, cost;
41
168
  return _ts_generator(this, function(_state) {
42
169
  switch (_state.label) {
43
170
  case 0:
44
- request = param.request, serverRoutes = param.serverRoutes, routesConfig = param.routes, context = param.context;
45
- url = new URL(request.url);
46
- routeId = url.searchParams.get(LOADER_ID_PARAM);
47
- entry = matchEntry(url.pathname, serverRoutes);
171
+ context = param.context, serverRoutes = param.serverRoutes, routesConfig = param.routes;
172
+ query = context.query;
173
+ routeId = query[LOADER_ID_PARAM];
174
+ entry = matchEntry(context.path, serverRoutes);
48
175
  if (!routeId || !entry) {
49
176
  return [
50
177
  2
@@ -52,11 +179,12 @@ var handleRequest = function() {
52
179
  }
53
180
  basename = entry.urlPath;
54
181
  end = time();
55
- logger = context.logger, reporter = context.reporter;
182
+ res = context.res, logger = context.logger, reporter = context.reporter;
56
183
  routes = transformNestedRoutes(routesConfig, reporter);
57
184
  queryRoute = createStaticHandler(routes, {
58
185
  basename
59
186
  }).queryRoute;
187
+ request = createRequest(context);
60
188
  requestContext = createRequestContext();
61
189
  requestContext.set(reporterCtx, reporter);
62
190
  _state.label = 1;
@@ -91,17 +219,15 @@ var handleRequest = function() {
91
219
  headers = new Headers(init.headers);
92
220
  headers.set("Content-Type", "".concat(CONTENT_TYPE_DEFERRED, "; charset=UTF-8"));
93
221
  init.headers = headers;
94
- response = new Response(body, init);
222
+ response = new NodeResponse(body, init);
95
223
  }
96
224
  } else {
97
- response = isResponse(response) ? response : new Response(JSON.stringify(response), {
225
+ response = isResponse(response) ? response : new NodeResponse(JSON.stringify(response), {
98
226
  headers: {
99
227
  "Content-Type": "application/json; charset=utf-8"
100
228
  }
101
229
  });
102
230
  }
103
- cost = end();
104
- reporter === null || reporter === void 0 ? void 0 : reporter.reportTiming("".concat(LOADER_REPORTER_NAME, "-navigation"), cost);
105
231
  return [
106
232
  3,
107
233
  4
@@ -114,7 +240,7 @@ var handleRequest = function() {
114
240
  } else {
115
241
  logger === null || logger === void 0 ? void 0 : logger.error(message);
116
242
  }
117
- response = new Response(message, {
243
+ response = new NodeResponse(message, {
118
244
  status: 500,
119
245
  headers: {
120
246
  "Content-Type": "text/plain"
@@ -125,9 +251,16 @@ var handleRequest = function() {
125
251
  4
126
252
  ];
127
253
  case 4:
254
+ cost = end();
255
+ reporter.reportTiming("".concat(LOADER_REPORTER_NAME, "-navigation"), cost);
256
+ return [
257
+ 4,
258
+ sendLoaderResponse(res, response)
259
+ ];
260
+ case 5:
261
+ _state.sent();
128
262
  return [
129
- 2,
130
- response
263
+ 2
131
264
  ];
132
265
  }
133
266
  });
@@ -0,0 +1,66 @@
1
+ import { _ as _async_to_generator } from "@swc/helpers/_/_async_to_generator";
2
+ import { _ as _ts_generator } from "@swc/helpers/_/_ts_generator";
3
+ import path from "path";
4
+ import fs from "fs";
5
+ import { MAIN_ENTRY_NAME, SERVER_BUNDLE_DIRECTORY } from "@modern-js/utils";
6
+ import { matchEntry } from "@modern-js/runtime-utils/node";
7
+ function server_default() {
8
+ return {
9
+ name: "@modern-js/plugin-data-loader",
10
+ setup: function() {
11
+ return {
12
+ prepareLoaderHandler: function prepareLoaderHandler(param) {
13
+ var serverRoutes = param.serverRoutes, distDir = param.distDir;
14
+ return function() {
15
+ var _ref = _async_to_generator(function(context) {
16
+ var entry, routesPath, _ref2, routes, handleRequest;
17
+ return _ts_generator(this, function(_state) {
18
+ switch (_state.label) {
19
+ case 0:
20
+ entry = matchEntry(context.path, serverRoutes);
21
+ if (!entry) {
22
+ return [
23
+ 2
24
+ ];
25
+ }
26
+ routesPath = path.join(distDir, SERVER_BUNDLE_DIRECTORY, "".concat(entry.entryName || MAIN_ENTRY_NAME, "-server-loaders.js"));
27
+ if (!fs.existsSync(routesPath)) {
28
+ return [
29
+ 2
30
+ ];
31
+ }
32
+ return [
33
+ 4,
34
+ import(routesPath)
35
+ ];
36
+ case 1:
37
+ _ref2 = _state.sent(), routes = _ref2.routes, handleRequest = _ref2.handleRequest;
38
+ if (!routes) {
39
+ return [
40
+ 2
41
+ ];
42
+ }
43
+ return [
44
+ 2,
45
+ handleRequest({
46
+ serverRoutes,
47
+ context,
48
+ routes
49
+ })
50
+ ];
51
+ }
52
+ });
53
+ });
54
+ return function(context) {
55
+ return _ref.apply(this, arguments);
56
+ };
57
+ }();
58
+ }
59
+ };
60
+ }
61
+ };
62
+ }
63
+ ;
64
+ export {
65
+ server_default as default
66
+ };
@@ -1,3 +1,4 @@
1
+ import { installGlobals, writeReadableStreamToWritable, Response as NodeResponse } from "@remix-run/node";
1
2
  import { createStaticHandler, UNSAFE_DEFERRED_SYMBOL as DEFERRED_SYMBOL, isRouteErrorResponse } from "@modern-js/runtime-utils/remix-router";
2
3
  import { transformNestedRoutes } from "@modern-js/runtime-utils/browser";
3
4
  import { isPlainObject } from "@modern-js/utils/lodash";
@@ -6,6 +7,7 @@ import { time } from "@modern-js/runtime-utils/time";
6
7
  import { LOADER_REPORTER_NAME } from "@modern-js/utils/universal/constants";
7
8
  import { CONTENT_TYPE_DEFERRED, LOADER_ID_PARAM } from "../common/constants";
8
9
  import { createDeferredReadableStream } from "./response";
10
+ installGlobals();
9
11
  const redirectStatusCodes = /* @__PURE__ */ new Set([
10
12
  301,
11
13
  302,
@@ -27,25 +29,71 @@ function convertModernRedirectResponse(headers, basename) {
27
29
  }
28
30
  newHeaders.set("X-Modernjs-Redirect", redirectUrl);
29
31
  newHeaders.delete("Location");
30
- return new Response(null, {
32
+ return new NodeResponse(null, {
31
33
  status: 204,
32
34
  headers: newHeaders
33
35
  });
34
36
  }
35
- const handleRequest = async ({ request, serverRoutes, routes: routesConfig, context }) => {
36
- const url = new URL(request.url);
37
- const routeId = url.searchParams.get(LOADER_ID_PARAM);
38
- const entry = matchEntry(url.pathname, serverRoutes);
37
+ const createLoaderHeaders = (requestHeaders) => {
38
+ const headers = new Headers();
39
+ for (const [key, values] of Object.entries(requestHeaders)) {
40
+ if (values) {
41
+ if (Array.isArray(values)) {
42
+ for (const value of values) {
43
+ headers.append(key, value);
44
+ }
45
+ } else {
46
+ headers.set(key, values);
47
+ }
48
+ }
49
+ }
50
+ return headers;
51
+ };
52
+ const createRequest = (context) => {
53
+ const origin = `${context.protocol}://${context.host}`;
54
+ const url = new URL(context.url, origin);
55
+ const controller = new AbortController();
56
+ const init = {
57
+ method: context.method,
58
+ headers: createLoaderHeaders(context.headers),
59
+ signal: controller.signal
60
+ };
61
+ if (![
62
+ "GET",
63
+ "HEAD"
64
+ ].includes(context.method.toUpperCase())) {
65
+ init.body = context.req;
66
+ }
67
+ const request = new Request(url.href, init);
68
+ return request;
69
+ };
70
+ const sendLoaderResponse = async (res, nodeResponse) => {
71
+ res.statusMessage = nodeResponse.statusText;
72
+ res.statusCode = nodeResponse.status;
73
+ for (const [key, value] of nodeResponse.headers.entries()) {
74
+ res.setHeader(key, value);
75
+ }
76
+ if (nodeResponse.body) {
77
+ await writeReadableStreamToWritable(nodeResponse.body, res);
78
+ } else {
79
+ res.end();
80
+ }
81
+ };
82
+ const handleRequest = async ({ context, serverRoutes, routes: routesConfig }) => {
83
+ const { query } = context;
84
+ const routeId = query[LOADER_ID_PARAM];
85
+ const entry = matchEntry(context.path, serverRoutes);
39
86
  if (!routeId || !entry) {
40
87
  return;
41
88
  }
42
89
  const basename = entry.urlPath;
43
90
  const end = time();
44
- const { logger, reporter } = context;
91
+ const { res, logger, reporter } = context;
45
92
  const routes = transformNestedRoutes(routesConfig, reporter);
46
93
  const { queryRoute } = createStaticHandler(routes, {
47
94
  basename
48
95
  });
96
+ const request = createRequest(context);
49
97
  const requestContext = createRequestContext();
50
98
  requestContext.set(reporterCtx, reporter);
51
99
  let response;
@@ -69,17 +117,15 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
69
117
  const headers = new Headers(init.headers);
70
118
  headers.set("Content-Type", `${CONTENT_TYPE_DEFERRED}; charset=UTF-8`);
71
119
  init.headers = headers;
72
- response = new Response(body, init);
120
+ response = new NodeResponse(body, init);
73
121
  }
74
122
  } else {
75
- response = isResponse(response) ? response : new Response(JSON.stringify(response), {
123
+ response = isResponse(response) ? response : new NodeResponse(JSON.stringify(response), {
76
124
  headers: {
77
125
  "Content-Type": "application/json; charset=utf-8"
78
126
  }
79
127
  });
80
128
  }
81
- const cost = end();
82
- reporter === null || reporter === void 0 ? void 0 : reporter.reportTiming(`${LOADER_REPORTER_NAME}-navigation`, cost);
83
129
  } catch (error) {
84
130
  const message = isRouteErrorResponse(error) ? error.data : String(error);
85
131
  if (error instanceof Error) {
@@ -87,14 +133,16 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
87
133
  } else {
88
134
  logger === null || logger === void 0 ? void 0 : logger.error(message);
89
135
  }
90
- response = new Response(message, {
136
+ response = new NodeResponse(message, {
91
137
  status: 500,
92
138
  headers: {
93
139
  "Content-Type": "text/plain"
94
140
  }
95
141
  });
96
142
  }
97
- return response;
143
+ const cost = end();
144
+ reporter.reportTiming(`${LOADER_REPORTER_NAME}-navigation`, cost);
145
+ await sendLoaderResponse(res, response);
98
146
  };
99
147
  export {
100
148
  handleRequest,
@@ -0,0 +1,33 @@
1
+ import path from "path";
2
+ import fs from "fs";
3
+ import { MAIN_ENTRY_NAME, SERVER_BUNDLE_DIRECTORY } from "@modern-js/utils";
4
+ import { matchEntry } from "@modern-js/runtime-utils/node";
5
+ var server_default = () => ({
6
+ name: "@modern-js/plugin-data-loader",
7
+ setup: () => ({
8
+ prepareLoaderHandler({ serverRoutes, distDir }) {
9
+ return async (context) => {
10
+ const entry = matchEntry(context.path, serverRoutes);
11
+ if (!entry) {
12
+ return;
13
+ }
14
+ const routesPath = path.join(distDir, SERVER_BUNDLE_DIRECTORY, `${entry.entryName || MAIN_ENTRY_NAME}-server-loaders.js`);
15
+ if (!fs.existsSync(routesPath)) {
16
+ return;
17
+ }
18
+ const { routes, handleRequest } = await import(routesPath);
19
+ if (!routes) {
20
+ return;
21
+ }
22
+ return handleRequest({
23
+ serverRoutes,
24
+ context,
25
+ routes
26
+ });
27
+ };
28
+ }
29
+ })
30
+ });
31
+ export {
32
+ server_default as default
33
+ };
@@ -1,12 +1,10 @@
1
- import type { Logger, NestedRoute, Reporter, ServerRoute } from '@modern-js/types';
1
+ import type { NestedRoute, ServerRoute } from '@modern-js/types';
2
+ import { Response as NodeResponse } from '@remix-run/node';
3
+ import { ServerContext } from '@modern-js/runtime-utils/node';
2
4
  export declare function isRedirectResponse(status: number): boolean;
3
- export declare function isResponse(value: any): value is Response;
4
- export declare const handleRequest: ({ request, serverRoutes, routes: routesConfig, context, }: {
5
- request: Request;
5
+ export declare function isResponse(value: any): value is NodeResponse;
6
+ export declare const handleRequest: ({ context, serverRoutes, routes: routesConfig, }: {
7
+ context: ServerContext;
6
8
  serverRoutes: ServerRoute[];
7
9
  routes: NestedRoute[];
8
- context: {
9
- logger: Logger;
10
- reporter?: Reporter;
11
- };
12
- }) => Promise<Response | void>;
10
+ }) => Promise<void>;
@@ -0,0 +1,3 @@
1
+ import type { ServerPlugin } from '@modern-js/server-core';
2
+ declare const _default: () => ServerPlugin;
3
+ export default _default;
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "modern",
16
16
  "modern.js"
17
17
  ],
18
- "version": "0.0.0-next-20240320040617",
18
+ "version": "0.0.0-next-20240320180839",
19
19
  "engines": {
20
20
  "node": ">=14.17.6"
21
21
  },
@@ -29,6 +29,11 @@
29
29
  "jsnext:source": "./src/cli/loader.ts",
30
30
  "default": "./dist/cjs/cli/loader.js"
31
31
  },
32
+ "./server": {
33
+ "types": "./dist/types/server/index.d.ts",
34
+ "jsnext:source": "./src/server/index.ts",
35
+ "default": "./dist/cjs/server/index.js"
36
+ },
32
37
  "./runtime": {
33
38
  "types": "./dist/types/runtime/index.d.ts",
34
39
  "jsnext:source": "./src/runtime/index.ts",
@@ -40,6 +45,9 @@
40
45
  "loader": [
41
46
  "./dist/types/cli/loader.d.ts"
42
47
  ],
48
+ "server": [
49
+ "./dist/types/server/index.d.ts"
50
+ ],
43
51
  "runtime": [
44
52
  "./dist/types/runtime/index.d.ts"
45
53
  ]
@@ -47,10 +55,11 @@
47
55
  },
48
56
  "dependencies": {
49
57
  "@babel/core": "^7.23.2",
58
+ "@remix-run/node": "^1.12.0",
50
59
  "path-to-regexp": "^6.2.0",
51
60
  "@swc/helpers": "0.5.3",
52
- "@modern-js/utils": "0.0.0-next-20240320040617",
53
- "@modern-js/runtime-utils": "0.0.0-next-20240320040617"
61
+ "@modern-js/utils": "0.0.0-next-20240320180839",
62
+ "@modern-js/runtime-utils": "0.0.0-next-20240320180839"
54
63
  },
55
64
  "devDependencies": {
56
65
  "@types/babel__core": "^7.20.1",
@@ -66,11 +75,11 @@
66
75
  "webpack": "^5.89.0",
67
76
  "react": "^18",
68
77
  "react-dom": "^18",
69
- "@modern-js/core": "0.0.0-next-20240320040617",
70
- "@modern-js/server-core": "0.0.0-next-20240320040617",
71
- "@modern-js/types": "0.0.0-next-20240320040617",
72
- "@scripts/jest-config": "0.0.0-next-20240320040617",
73
- "@scripts/build": "0.0.0-next-20240320040617"
78
+ "@modern-js/core": "0.0.0-next-20240320180839",
79
+ "@modern-js/types": "0.0.0-next-20240320180839",
80
+ "@modern-js/server-core": "0.0.0-next-20240320180839",
81
+ "@scripts/build": "0.0.0-next-20240320180839",
82
+ "@scripts/jest-config": "0.0.0-next-20240320180839"
74
83
  },
75
84
  "peerDependencies": {
76
85
  "react": ">=17.0.0"