@modern-js/plugin-data-loader 2.5.0-alpha.0 → 2.5.1-alpha.0

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 (39) hide show
  1. package/dist/cjs/cli/create-request.js +3 -14
  2. package/dist/cjs/cli/generate-client.js +4 -0
  3. package/dist/cjs/cli/loader.js +3 -0
  4. package/dist/cjs/server/index.js +200 -19
  5. package/dist/esm/cli/create-request.js +2 -41
  6. package/dist/esm/cli/loader.js +6 -0
  7. package/dist/esm/server/index.js +447 -29
  8. package/dist/esm-node/cli/create-request.js +3 -14
  9. package/dist/esm-node/cli/loader.js +3 -0
  10. package/dist/esm-node/server/index.js +196 -21
  11. package/dist/js/modern/cli/create-request.js +66 -0
  12. package/dist/js/modern/cli/generate-client.js +42 -0
  13. package/dist/js/modern/cli/loader.js +40 -0
  14. package/dist/js/modern/common/constants.js +6 -0
  15. package/dist/js/modern/server/index.js +237 -0
  16. package/dist/js/node/cli/create-request.js +90 -0
  17. package/dist/js/node/cli/generate-client.js +71 -0
  18. package/dist/js/node/cli/loader.js +61 -0
  19. package/dist/js/node/common/constants.js +30 -0
  20. package/dist/js/node/server/index.js +261 -0
  21. package/dist/js/treeshaking/cli/create-request.js +186 -0
  22. package/dist/js/treeshaking/cli/generate-client.js +45 -0
  23. package/dist/js/treeshaking/cli/loader.js +154 -0
  24. package/dist/js/treeshaking/common/constants.js +3 -0
  25. package/dist/{esm/runtime → js/treeshaking/server}/index.js +222 -66
  26. package/dist/types/cli/create-request.d.ts +1 -2
  27. package/dist/types/server/index.d.ts +15 -0
  28. package/package.json +10 -21
  29. package/dist/cjs/cli/data.js +0 -162
  30. package/dist/cjs/runtime/index.js +0 -159
  31. package/dist/cjs/runtime/response.js +0 -102
  32. package/dist/esm/cli/data.js +0 -820
  33. package/dist/esm/runtime/response.js +0 -284
  34. package/dist/esm-node/cli/data.js +0 -142
  35. package/dist/esm-node/runtime/index.js +0 -143
  36. package/dist/esm-node/runtime/response.js +0 -79
  37. package/dist/types/cli/data.d.ts +0 -6
  38. package/dist/types/runtime/index.d.ts +0 -15
  39. package/dist/types/runtime/response.d.ts +0 -2
@@ -24,7 +24,6 @@ module.exports = __toCommonJS(create_request_exports);
24
24
  var import_path_to_regexp = require("path-to-regexp");
25
25
  var import_react_router_dom = require("react-router-dom");
26
26
  var import_constants = require("../common/constants");
27
- var import_data = require("./data");
28
27
  const getRequestUrl = ({
29
28
  params,
30
29
  request,
@@ -44,14 +43,7 @@ const handleRedirectResponse = (res) => {
44
43
  const { headers } = res;
45
44
  const location = headers.get("X-Modernjs-Redirect");
46
45
  if (location) {
47
- throw (0, import_react_router_dom.redirect)(location);
48
- }
49
- return res;
50
- };
51
- const handleDeferredResponse = async (res) => {
52
- var _a;
53
- if (((_a = res.headers.get("Content-Type")) == null ? void 0 : _a.match(/text\/modernjs-deferred/)) && res.body) {
54
- return await (0, import_data.parseDeferredReadableStream)(res.body);
46
+ return (0, import_react_router_dom.redirect)(location);
55
47
  }
56
48
  return res;
57
49
  };
@@ -61,17 +53,14 @@ const createRequest = (routeId, method = "get") => {
61
53
  request
62
54
  }) => {
63
55
  const url = getRequestUrl({ params, request, routeId });
64
- let res;
65
- res = await fetch(url, {
56
+ const res = await fetch(url, {
66
57
  method,
67
58
  signal: request.signal
68
59
  });
69
60
  if (!res.ok) {
70
61
  throw res;
71
62
  }
72
- res = handleRedirectResponse(res);
73
- res = await handleDeferredResponse(res);
74
- return res;
63
+ return handleRedirectResponse(res);
75
64
  };
76
65
  };
77
66
  // Annotate the CommonJS export names for ESM import in node:
@@ -17,6 +17,10 @@ var __copyProps = (to, from, except, desc) => {
17
17
  return to;
18
18
  };
19
19
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
24
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
25
  mod
22
26
  ));
@@ -28,6 +28,9 @@ async function loader(source) {
28
28
  if (target === "node") {
29
29
  return source;
30
30
  }
31
+ if (target === "webworker") {
32
+ return source;
33
+ }
31
34
  const options = this.getOptions();
32
35
  const code = (0, import_generate_client.generateClient)({
33
36
  mapFile: options.mapFile,
@@ -17,18 +17,208 @@ var __copyProps = (to, from, except, desc) => {
17
17
  return to;
18
18
  };
19
19
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
20
+ // If the importer is in node compatibility mode or this is not an ESM
21
+ // file that has been converted to a CommonJS file using a Babel-
22
+ // compatible transform (i.e. "__esModule" has not been set), then set
23
+ // "default" to the CommonJS "module.exports" for node compatibility.
20
24
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
21
25
  mod
22
26
  ));
23
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
24
28
  var server_exports = {};
25
29
  __export(server_exports, {
26
- default: () => server_default
30
+ default: () => server_default,
31
+ getPathWithoutEntry: () => getPathWithoutEntry,
32
+ handleRequest: () => handleRequest,
33
+ isRedirectResponse: () => isRedirectResponse,
34
+ isResponse: () => isResponse
27
35
  });
28
36
  module.exports = __toCommonJS(server_exports);
29
37
  var import_path = __toESM(require("path"));
38
+ var import_node = require("@remix-run/node");
39
+ var import_react_router_dom = require("react-router-dom");
30
40
  var import_utils = require("@modern-js/utils");
31
- var import_runtime = require("../runtime");
41
+ var import_constants = require("../common/constants");
42
+ (0, import_node.installGlobals)();
43
+ const redirectStatusCodes = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
44
+ function sortByUrlPath(entries) {
45
+ entries.sort(function(a, b) {
46
+ const length1 = a.urlPath.length;
47
+ const length2 = b.urlPath.length;
48
+ if (length1 < length2) {
49
+ return 1;
50
+ }
51
+ if (length1 > length2) {
52
+ return -1;
53
+ }
54
+ return 0;
55
+ });
56
+ return entries;
57
+ }
58
+ function isRedirectResponse(response) {
59
+ return redirectStatusCodes.has(response.status);
60
+ }
61
+ function isResponse(value) {
62
+ return value != null && typeof value.status === "number" && typeof value.statusText === "string" && typeof value.headers === "object" && typeof value.body !== "undefined";
63
+ }
64
+ const json = (data, init = {}) => {
65
+ const responseInit = typeof init === "number" ? { status: init } : init;
66
+ const headers = new Headers(responseInit.headers);
67
+ if (!headers.has("Content-Type")) {
68
+ headers.set("Content-Type", "application/json; charset=utf-8");
69
+ }
70
+ return new import_node.Response(JSON.stringify(data), {
71
+ ...responseInit,
72
+ headers
73
+ });
74
+ };
75
+ const callRouteLoader = async ({
76
+ routeId,
77
+ loader,
78
+ params,
79
+ request,
80
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
81
+ loadContext
82
+ }) => {
83
+ if (!loader) {
84
+ throw new Error(
85
+ `You made a ${request.method} request to ${request.url} but did not provide a default component or \`loader\` for route "${routeId}", so there is no way to handle the request.`
86
+ );
87
+ }
88
+ let result;
89
+ try {
90
+ result = await loader({
91
+ request,
92
+ params
93
+ });
94
+ } catch (error) {
95
+ if (!isResponse(error)) {
96
+ throw error;
97
+ }
98
+ result = error;
99
+ }
100
+ if (result === void 0) {
101
+ throw new Error(
102
+ `You defined a loader for route "${routeId}" but didn't return anything from your \`loader\` function. Please return a value or \`null\`.`
103
+ );
104
+ }
105
+ return isResponse(result) ? result : json(result);
106
+ };
107
+ const createLoaderHeaders = (requestHeaders) => {
108
+ const headers = new Headers();
109
+ for (const [key, values] of Object.entries(requestHeaders)) {
110
+ if (values) {
111
+ if (Array.isArray(values)) {
112
+ for (const value of values) {
113
+ headers.append(key, value);
114
+ }
115
+ } else {
116
+ headers.set(key, values);
117
+ }
118
+ }
119
+ }
120
+ return headers;
121
+ };
122
+ const createLoaderRequest = (context) => {
123
+ const origin = `${context.protocol}://${context.host}`;
124
+ const url = new URL(context.url, origin);
125
+ const controller = new AbortController();
126
+ const init = {
127
+ method: context.method,
128
+ headers: createLoaderHeaders(context.headers),
129
+ signal: controller.signal
130
+ };
131
+ return new Request(url.href, init);
132
+ };
133
+ const sendLoaderResponse = async (res, nodeResponse) => {
134
+ res.statusMessage = nodeResponse.statusText;
135
+ res.statusCode = nodeResponse.status;
136
+ for (const [key, value] of nodeResponse.headers.entries()) {
137
+ res.setHeader(key, value);
138
+ }
139
+ if (nodeResponse.body) {
140
+ await (0, import_node.writeReadableStreamToWritable)(nodeResponse.body, res);
141
+ } else {
142
+ res.end();
143
+ }
144
+ };
145
+ const getPathWithoutEntry = (pathname, entryPath) => {
146
+ if (entryPath === "/") {
147
+ return pathname;
148
+ }
149
+ return pathname.replace(entryPath, "");
150
+ };
151
+ const matchEntry = (pathname, entries) => {
152
+ const newEntries = sortByUrlPath(entries);
153
+ return newEntries.find((entry) => pathname.startsWith(entry.urlPath));
154
+ };
155
+ const handleRequest = async ({
156
+ context,
157
+ serverRoutes,
158
+ distDir
159
+ }) => {
160
+ const { method, query } = context;
161
+ const routeId = query[import_constants.LOADER_ID_PARAM];
162
+ if (!routeId || method.toLowerCase() !== "get") {
163
+ return;
164
+ }
165
+ const entry = matchEntry(context.path, serverRoutes);
166
+ if (!entry) {
167
+ return;
168
+ }
169
+ const routesPath = import_path.default.join(
170
+ distDir,
171
+ import_utils.SERVER_BUNDLE_DIRECTORY,
172
+ `${entry.entryName || import_utils.MAIN_ENTRY_NAME}-server-loaders`
173
+ );
174
+ const { routes } = await Promise.resolve().then(() => __toESM(require(routesPath)));
175
+ if (!routes) {
176
+ return;
177
+ }
178
+ const { res } = context;
179
+ const pathname = getPathWithoutEntry(context.path, entry.urlPath);
180
+ const matches = (0, import_react_router_dom.matchRoutes)(routes, pathname);
181
+ if (!matches) {
182
+ res.statusCode = 403;
183
+ res.end(`Route ${pathname} was not matched`);
184
+ return;
185
+ }
186
+ const match = matches == null ? void 0 : matches.find((match2) => match2.route.id === routeId);
187
+ if (!match) {
188
+ res.statusCode = 403;
189
+ res.end(`Route ${routeId} does not match URL ${context.path}`);
190
+ return;
191
+ }
192
+ const request = createLoaderRequest(context);
193
+ let response;
194
+ try {
195
+ response = await callRouteLoader({
196
+ loader: match.route.loader,
197
+ routeId: match.route.id,
198
+ params: match.params,
199
+ request,
200
+ loadContext: {}
201
+ });
202
+ if (isRedirectResponse(response)) {
203
+ const headers = new Headers(response.headers);
204
+ headers.set("X-Modernjs-Redirect", headers.get("Location"));
205
+ headers.delete("Location");
206
+ response = new import_node.Response(null, {
207
+ status: 204,
208
+ headers
209
+ });
210
+ }
211
+ } catch (error) {
212
+ const message = String(error);
213
+ response = new import_node.Response(message, {
214
+ status: 500,
215
+ headers: {
216
+ "Content-Type": "text/plain"
217
+ }
218
+ });
219
+ }
220
+ sendLoaderResponse(res, response);
221
+ };
32
222
  var server_default = () => ({
33
223
  name: "@modern-js/plugin-data-loader",
34
224
  setup: () => ({
@@ -37,28 +227,19 @@ var server_default = () => ({
37
227
  distDir
38
228
  }) {
39
229
  return async (context) => {
40
- const entry = (0, import_runtime.matchEntry)(context.path, serverRoutes);
41
- if (!entry) {
42
- throw new Error("Route is not matched");
43
- }
44
- const routesPath = import_path.default.join(
45
- distDir,
46
- import_utils.SERVER_BUNDLE_DIRECTORY,
47
- `${entry.entryName || import_utils.MAIN_ENTRY_NAME}-server-loaders`
48
- );
49
- const { routes, handleRequest } = await Promise.resolve().then(() => __toESM(require(routesPath)));
50
- if (!routes) {
51
- throw new Error("Missing route info");
52
- ;
53
- }
54
230
  return handleRequest({
55
231
  serverRoutes,
56
- context,
57
- routes
232
+ distDir,
233
+ context
58
234
  });
59
235
  };
60
236
  }
61
237
  })
62
238
  });
63
239
  // Annotate the CommonJS export names for ESM import in node:
64
- 0 && (module.exports = {});
240
+ 0 && (module.exports = {
241
+ getPathWithoutEntry,
242
+ handleRequest,
243
+ isRedirectResponse,
244
+ isResponse
245
+ });
@@ -125,7 +125,6 @@ var __generator = this && this.__generator || function(thisArg, body) {
125
125
  import { compile } from "path-to-regexp";
126
126
  import { redirect } from "react-router-dom";
127
127
  import { LOADER_ID_PARAM, DIRECT_PARAM } from "../common/constants";
128
- import { parseDeferredReadableStream } from "./data";
129
128
  var getRequestUrl = function(param) {
130
129
  var params = param.params, request = param.request, routeId = param.routeId;
131
130
  var url = new URL(request.url);
@@ -142,41 +141,10 @@ var handleRedirectResponse = function(res) {
142
141
  var headers = res.headers;
143
142
  var location = headers.get("X-Modernjs-Redirect");
144
143
  if (location) {
145
- throw redirect(location);
144
+ return redirect(location);
146
145
  }
147
146
  return res;
148
147
  };
149
- var handleDeferredResponse = function() {
150
- var _ref = _asyncToGenerator(function(res) {
151
- var _res_headers_get;
152
- return __generator(this, function(_state) {
153
- switch(_state.label){
154
- case 0:
155
- if (!(((_res_headers_get = res.headers.get("Content-Type")) === null || _res_headers_get === void 0 ? void 0 : _res_headers_get.match(/text\/modernjs-deferred/)) && res.body)) return [
156
- 3,
157
- 2
158
- ];
159
- return [
160
- 4,
161
- parseDeferredReadableStream(res.body)
162
- ];
163
- case 1:
164
- return [
165
- 2,
166
- _state.sent()
167
- ];
168
- case 2:
169
- return [
170
- 2,
171
- res
172
- ];
173
- }
174
- });
175
- });
176
- return function handleDeferredResponse(res) {
177
- return _ref.apply(this, arguments);
178
- };
179
- }();
180
148
  var createRequest = function(routeId) {
181
149
  var method = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : "get";
182
150
  return function() {
@@ -203,16 +171,9 @@ var createRequest = function(routeId) {
203
171
  if (!res.ok) {
204
172
  throw res;
205
173
  }
206
- res = handleRedirectResponse(res);
207
- return [
208
- 4,
209
- handleDeferredResponse(res)
210
- ];
211
- case 2:
212
- res = _state.sent();
213
174
  return [
214
175
  2,
215
- res
176
+ handleRedirectResponse(res)
216
177
  ];
217
178
  }
218
179
  });
@@ -138,6 +138,12 @@ function _loader() {
138
138
  source
139
139
  ];
140
140
  }
141
+ if (target === "webworker") {
142
+ return [
143
+ 2,
144
+ source
145
+ ];
146
+ }
141
147
  options = this.getOptions();
142
148
  code = generateClient({
143
149
  mapFile: options.mapFile,