@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.
- package/dist/cjs/runtime/index.js +63 -15
- package/dist/cjs/server/index.js +63 -0
- package/dist/esm/runtime/index.js +147 -14
- package/dist/esm/server/index.js +66 -0
- package/dist/esm-node/runtime/index.js +60 -12
- package/dist/esm-node/server/index.js +33 -0
- package/dist/types/runtime/index.d.ts +7 -9
- package/dist/types/server/index.d.ts +3 -0
- package/package.json +17 -8
|
@@ -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
|
|
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
|
|
61
|
-
const
|
|
62
|
-
const
|
|
63
|
-
|
|
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
|
|
75
|
-
requestContext
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
45
|
-
|
|
46
|
-
routeId =
|
|
47
|
-
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);
|
|
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
|
|
222
|
+
response = new NodeResponse(body, init);
|
|
95
223
|
}
|
|
96
224
|
} else {
|
|
97
|
-
response = isResponse(response) ? response : new
|
|
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
|
|
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
|
|
32
|
+
return new NodeResponse(null, {
|
|
31
33
|
status: 204,
|
|
32
34
|
headers: newHeaders
|
|
33
35
|
});
|
|
34
36
|
}
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const
|
|
38
|
-
|
|
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
|
|
120
|
+
response = new NodeResponse(body, init);
|
|
73
121
|
}
|
|
74
122
|
} else {
|
|
75
|
-
response = isResponse(response) ? response : new
|
|
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
|
|
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
|
-
|
|
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 {
|
|
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
|
|
4
|
-
export declare const handleRequest: ({
|
|
5
|
-
|
|
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
|
-
|
|
9
|
-
logger: Logger;
|
|
10
|
-
reporter?: Reporter;
|
|
11
|
-
};
|
|
12
|
-
}) => 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-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-
|
|
53
|
-
"@modern-js/runtime-utils": "0.0.0-next-
|
|
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-
|
|
70
|
-
"@modern-js/
|
|
71
|
-
"@modern-js/
|
|
72
|
-
"@scripts/
|
|
73
|
-
"@scripts/
|
|
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"
|