@modern-js/plugin-data-loader 0.0.0-next-20240315022508 → 0.0.0-next-20240315034729
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.
- package/dist/cjs/runtime/index.js +54 -8
- package/dist/cjs/server/index.js +63 -0
- package/dist/esm/runtime/index.js +142 -11
- package/dist/esm/server/index.js +66 -0
- package/dist/esm-node/runtime/index.js +55 -9
- package/dist/esm-node/server/index.js +33 -0
- package/dist/types/runtime/index.d.ts +5 -8
- package/dist/types/server/index.d.ts +3 -0
- package/package.json +16 -8
|
@@ -59,20 +59,66 @@ function convertModernRedirectResponse(headers, basename) {
|
|
|
59
59
|
headers: newHeaders
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
|
-
const
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
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);
|
|
66
111
|
if (!routeId || !entry) {
|
|
67
112
|
return;
|
|
68
113
|
}
|
|
69
114
|
const basename = entry.urlPath;
|
|
70
115
|
const end = (0, import_time.time)();
|
|
71
|
-
const { logger, reporter } = context;
|
|
116
|
+
const { res, logger, reporter } = context;
|
|
72
117
|
const routes = (0, import_browser.transformNestedRoutes)(routesConfig, reporter);
|
|
73
118
|
const { queryRoute } = (0, import_remix_router.createStaticHandler)(routes, {
|
|
74
119
|
basename
|
|
75
120
|
});
|
|
121
|
+
const request = createRequest(context);
|
|
76
122
|
const requestContext = (0, import_node2.createRequestContext)();
|
|
77
123
|
requestContext.set(import_node2.reporterCtx, reporter);
|
|
78
124
|
let response;
|
|
@@ -105,8 +151,6 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
|
|
|
105
151
|
}
|
|
106
152
|
});
|
|
107
153
|
}
|
|
108
|
-
const cost = end();
|
|
109
|
-
reporter === null || reporter === void 0 ? void 0 : reporter.reportTiming(`${import_constants.LOADER_REPORTER_NAME}-navigation`, cost);
|
|
110
154
|
} catch (error) {
|
|
111
155
|
const message = (0, import_remix_router.isRouteErrorResponse)(error) ? error.data : String(error);
|
|
112
156
|
if (error instanceof Error) {
|
|
@@ -121,7 +165,9 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
|
|
|
121
165
|
}
|
|
122
166
|
});
|
|
123
167
|
}
|
|
124
|
-
|
|
168
|
+
const cost = end();
|
|
169
|
+
reporter.reportTiming(`${import_constants.LOADER_REPORTER_NAME}-navigation`, cost);
|
|
170
|
+
await sendLoaderResponse(res, response);
|
|
125
171
|
};
|
|
126
172
|
// Annotate the CommonJS export names for ESM import in node:
|
|
127
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,7 +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";
|
|
4
|
-
import { installGlobals, Response as NodeResponse } from "@remix-run/node";
|
|
5
|
+
import { installGlobals, writeReadableStreamToWritable, Response as NodeResponse } from "@remix-run/node";
|
|
5
6
|
import { createStaticHandler, UNSAFE_DEFERRED_SYMBOL as DEFERRED_SYMBOL, isRouteErrorResponse } from "@modern-js/runtime-utils/remix-router";
|
|
6
7
|
import { transformNestedRoutes } from "@modern-js/runtime-utils/browser";
|
|
7
8
|
import { isPlainObject } from "@modern-js/utils/lodash";
|
|
@@ -37,16 +38,140 @@ function convertModernRedirectResponse(headers, basename) {
|
|
|
37
38
|
headers: newHeaders
|
|
38
39
|
});
|
|
39
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
|
+
}();
|
|
40
165
|
var handleRequest = function() {
|
|
41
166
|
var _ref = _async_to_generator(function(param) {
|
|
42
|
-
var
|
|
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;
|
|
43
168
|
return _ts_generator(this, function(_state) {
|
|
44
169
|
switch (_state.label) {
|
|
45
170
|
case 0:
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
routeId =
|
|
49
|
-
entry = matchEntry(
|
|
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);
|
|
50
175
|
if (!routeId || !entry) {
|
|
51
176
|
return [
|
|
52
177
|
2
|
|
@@ -54,11 +179,12 @@ var handleRequest = function() {
|
|
|
54
179
|
}
|
|
55
180
|
basename = entry.urlPath;
|
|
56
181
|
end = time();
|
|
57
|
-
logger = context.logger, reporter = context.reporter;
|
|
182
|
+
res = context.res, logger = context.logger, reporter = context.reporter;
|
|
58
183
|
routes = transformNestedRoutes(routesConfig, reporter);
|
|
59
184
|
queryRoute = createStaticHandler(routes, {
|
|
60
185
|
basename
|
|
61
186
|
}).queryRoute;
|
|
187
|
+
request = createRequest(context);
|
|
62
188
|
requestContext = createRequestContext();
|
|
63
189
|
requestContext.set(reporterCtx, reporter);
|
|
64
190
|
_state.label = 1;
|
|
@@ -102,8 +228,6 @@ var handleRequest = function() {
|
|
|
102
228
|
}
|
|
103
229
|
});
|
|
104
230
|
}
|
|
105
|
-
cost = end();
|
|
106
|
-
reporter === null || reporter === void 0 ? void 0 : reporter.reportTiming("".concat(LOADER_REPORTER_NAME, "-navigation"), cost);
|
|
107
231
|
return [
|
|
108
232
|
3,
|
|
109
233
|
4
|
|
@@ -127,9 +251,16 @@ var handleRequest = function() {
|
|
|
127
251
|
4
|
|
128
252
|
];
|
|
129
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();
|
|
130
262
|
return [
|
|
131
|
-
2
|
|
132
|
-
response
|
|
263
|
+
2
|
|
133
264
|
];
|
|
134
265
|
}
|
|
135
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,4 +1,4 @@
|
|
|
1
|
-
import { installGlobals, Response as NodeResponse } from "@remix-run/node";
|
|
1
|
+
import { installGlobals, writeReadableStreamToWritable, Response as NodeResponse } from "@remix-run/node";
|
|
2
2
|
import { createStaticHandler, UNSAFE_DEFERRED_SYMBOL as DEFERRED_SYMBOL, isRouteErrorResponse } from "@modern-js/runtime-utils/remix-router";
|
|
3
3
|
import { transformNestedRoutes } from "@modern-js/runtime-utils/browser";
|
|
4
4
|
import { isPlainObject } from "@modern-js/utils/lodash";
|
|
@@ -34,20 +34,66 @@ function convertModernRedirectResponse(headers, basename) {
|
|
|
34
34
|
headers: newHeaders
|
|
35
35
|
});
|
|
36
36
|
}
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
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);
|
|
41
86
|
if (!routeId || !entry) {
|
|
42
87
|
return;
|
|
43
88
|
}
|
|
44
89
|
const basename = entry.urlPath;
|
|
45
90
|
const end = time();
|
|
46
|
-
const { logger, reporter } = context;
|
|
91
|
+
const { res, logger, reporter } = context;
|
|
47
92
|
const routes = transformNestedRoutes(routesConfig, reporter);
|
|
48
93
|
const { queryRoute } = createStaticHandler(routes, {
|
|
49
94
|
basename
|
|
50
95
|
});
|
|
96
|
+
const request = createRequest(context);
|
|
51
97
|
const requestContext = createRequestContext();
|
|
52
98
|
requestContext.set(reporterCtx, reporter);
|
|
53
99
|
let response;
|
|
@@ -80,8 +126,6 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
|
|
|
80
126
|
}
|
|
81
127
|
});
|
|
82
128
|
}
|
|
83
|
-
const cost = end();
|
|
84
|
-
reporter === null || reporter === void 0 ? void 0 : reporter.reportTiming(`${LOADER_REPORTER_NAME}-navigation`, cost);
|
|
85
129
|
} catch (error) {
|
|
86
130
|
const message = isRouteErrorResponse(error) ? error.data : String(error);
|
|
87
131
|
if (error instanceof Error) {
|
|
@@ -96,7 +140,9 @@ const handleRequest = async ({ request, serverRoutes, routes: routesConfig, cont
|
|
|
96
140
|
}
|
|
97
141
|
});
|
|
98
142
|
}
|
|
99
|
-
|
|
143
|
+
const cost = end();
|
|
144
|
+
reporter.reportTiming(`${LOADER_REPORTER_NAME}-navigation`, cost);
|
|
145
|
+
await sendLoaderResponse(res, response);
|
|
100
146
|
};
|
|
101
147
|
export {
|
|
102
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,13 +1,10 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { NestedRoute, ServerRoute } from '@modern-js/types';
|
|
2
2
|
import { Response as NodeResponse } from '@remix-run/node';
|
|
3
|
+
import { ServerContext } from '@modern-js/runtime-utils/node';
|
|
3
4
|
export declare function isRedirectResponse(status: number): boolean;
|
|
4
5
|
export declare function isResponse(value: any): value is NodeResponse;
|
|
5
|
-
export declare const handleRequest: ({
|
|
6
|
-
|
|
6
|
+
export declare const handleRequest: ({ context, serverRoutes, routes: routesConfig, }: {
|
|
7
|
+
context: ServerContext;
|
|
7
8
|
serverRoutes: ServerRoute[];
|
|
8
9
|
routes: NestedRoute[];
|
|
9
|
-
|
|
10
|
-
logger: Logger;
|
|
11
|
-
reporter?: Reporter;
|
|
12
|
-
};
|
|
13
|
-
}) => Promise<Response | void>;
|
|
10
|
+
}) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"modern",
|
|
16
16
|
"modern.js"
|
|
17
17
|
],
|
|
18
|
-
"version": "0.0.0-next-
|
|
18
|
+
"version": "0.0.0-next-20240315034729",
|
|
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
|
]
|
|
@@ -50,8 +58,8 @@
|
|
|
50
58
|
"@remix-run/node": "^1.12.0",
|
|
51
59
|
"path-to-regexp": "^6.2.0",
|
|
52
60
|
"@swc/helpers": "0.5.3",
|
|
53
|
-
"@modern-js/utils": "0.0.0-next-
|
|
54
|
-
"@modern-js/
|
|
61
|
+
"@modern-js/runtime-utils": "0.0.0-next-20240315034729",
|
|
62
|
+
"@modern-js/utils": "0.0.0-next-20240315034729"
|
|
55
63
|
},
|
|
56
64
|
"devDependencies": {
|
|
57
65
|
"@types/babel__core": "^7.20.1",
|
|
@@ -67,11 +75,11 @@
|
|
|
67
75
|
"webpack": "^5.89.0",
|
|
68
76
|
"react": "^18",
|
|
69
77
|
"react-dom": "^18",
|
|
70
|
-
"@modern-js/core": "0.0.0-next-
|
|
71
|
-
"@modern-js/
|
|
72
|
-
"@modern-js/types": "0.0.0-next-
|
|
73
|
-
"@scripts/build": "0.0.0-next-
|
|
74
|
-
"@scripts/jest-config": "0.0.0-next-
|
|
78
|
+
"@modern-js/server-core": "0.0.0-next-20240315034729",
|
|
79
|
+
"@modern-js/core": "0.0.0-next-20240315034729",
|
|
80
|
+
"@modern-js/types": "0.0.0-next-20240315034729",
|
|
81
|
+
"@scripts/build": "0.0.0-next-20240315034729",
|
|
82
|
+
"@scripts/jest-config": "0.0.0-next-20240315034729"
|
|
75
83
|
},
|
|
76
84
|
"peerDependencies": {
|
|
77
85
|
"react": ">=17.0.0"
|