dinou 6.1.1 → 7.1.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 (135) hide show
  1. package/CHANGELOG.md +106 -0
  2. package/README.md +9352 -1081
  3. package/cli.js +314 -91
  4. package/dinou/adapters/bun.js +62 -0
  5. package/dinou/adapters/cloudflare.js +65 -0
  6. package/dinou/adapters/deno.js +48 -0
  7. package/dinou/adapters/netlify.js +85 -0
  8. package/dinou/adapters/node.mjs +31 -0
  9. package/dinou/bun/build.mjs +1077 -0
  10. package/dinou/cloudflare/build.mjs +1121 -0
  11. package/dinou/cloudflare/shims/child_process.js +14 -0
  12. package/dinou/cloudflare/shims/empty.js +2 -0
  13. package/dinou/cloudflare/shims/fs.js +99 -0
  14. package/dinou/cloudflare/shims/os.js +29 -0
  15. package/dinou/config.js +1 -0
  16. package/dinou/config.mjs +2 -0
  17. package/dinou/constants.js +29 -4
  18. package/dinou/core/babel-esm-loader.js +66 -37
  19. package/dinou/core/bailout-proxy.js +61 -0
  20. package/dinou/core/build-static-pages.js +322 -165
  21. package/dinou/core/cache-revalidate.js +471 -144
  22. package/dinou/core/cache-slot.js +387 -0
  23. package/dinou/core/client-redirect.jsx +12 -7
  24. package/dinou/core/client-webpack.jsx +457 -82
  25. package/dinou/core/client.jsx +452 -82
  26. package/dinou/core/config.js +11 -0
  27. package/dinou/core/dinou-paths.js +52 -0
  28. package/dinou/core/edge-ssr.js +122 -0
  29. package/dinou/core/export-static.mjs +64 -0
  30. package/dinou/core/generate-route-types.js +252 -0
  31. package/dinou/core/generate-static-page.js +55 -94
  32. package/dinou/core/generate-static-rsc.js +47 -15
  33. package/dinou/core/generate-static.js +212 -10
  34. package/dinou/core/generating-isg.js +5 -0
  35. package/dinou/core/get-asset-from-manifest.js +9 -3
  36. package/dinou/core/get-error-jsx.js +221 -41
  37. package/dinou/core/get-file-path-and-dynamic-params.js +9 -13
  38. package/dinou/core/get-jsx.js +175 -96
  39. package/dinou/core/handler.js +2303 -0
  40. package/dinou/core/http-adapter.js +115 -0
  41. package/dinou/core/import-module.js +83 -53
  42. package/dinou/core/layout-functions.js +183 -0
  43. package/dinou/core/link.jsx +18 -6
  44. package/dinou/core/load-dinou-config.js +60 -0
  45. package/dinou/core/manifest-provider.js +261 -0
  46. package/dinou/core/navigation-utils.js +4 -0
  47. package/dinou/core/navigation.js +50 -39
  48. package/dinou/core/parse-exports.js +252 -2
  49. package/dinou/core/ppr-context.js +105 -0
  50. package/dinou/core/ppr-runtime.js +263 -0
  51. package/dinou/core/redirect.jsx +20 -19
  52. package/dinou/core/render-jsx-to-client-jsx.js +91 -87
  53. package/dinou/core/request-context.js +47 -13
  54. package/dinou/core/resolve-module-ppr.js +34 -0
  55. package/dinou/core/revalidating.js +28 -9
  56. package/dinou/core/route-generator.js +107 -0
  57. package/dinou/core/rsc-renderer.js +90 -0
  58. package/dinou/core/run-ssg.js +19 -0
  59. package/dinou/core/scan-dependency-components.js +218 -0
  60. package/dinou/core/server-function-proxy-webpack.js +3 -0
  61. package/dinou/core/server-function-proxy.js +3 -0
  62. package/dinou/core/slot.js +302 -0
  63. package/dinou/core/status-manifest.js +41 -1
  64. package/dinou/core/storage-adapter.js +522 -0
  65. package/dinou/core/url-resolver.js +16 -16
  66. package/dinou/core/vfs.js +139 -68
  67. package/dinou/deno/build.mjs +1112 -0
  68. package/dinou/deno/seed-kv.js +115 -0
  69. package/dinou/esbuild/build.mjs +51 -1
  70. package/dinou/esbuild/dev.mjs +290 -224
  71. package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +3 -2
  72. package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +104 -16
  73. package/dinou/esbuild/helpers-esbuild/get-esbuild-entries.mjs +31 -19
  74. package/dinou/esbuild/helpers-esbuild/strip-namespace.mjs +9 -0
  75. package/dinou/esbuild/helpers-esbuild/swc-disk-cache.mjs +225 -0
  76. package/dinou/esbuild/helpers-esbuild/update-manifest-for-module.mjs +7 -0
  77. package/dinou/esbuild/helpers-esbuild/write.mjs +111 -2
  78. package/dinou/esbuild/plugins-esbuild/assets-plugin.mjs +236 -161
  79. package/dinou/esbuild/plugins-esbuild/css-processor-plugin.mjs +101 -5
  80. package/dinou/esbuild/plugins-esbuild/react-client-manifest-plugin.mjs +63 -24
  81. package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +177 -56
  82. package/dinou/esbuild/plugins-esbuild/skip-missing-entry-points-plugin.mjs +3 -0
  83. package/dinou/esbuild/plugins-esbuild/stable-chunk-names-and-maps-plugin.mjs +182 -137
  84. package/dinou/esbuild/plugins-postcss/postcss-extract-plugin.js +38 -11
  85. package/dinou/esbuild/react-refresh/esm-hmr/client.mjs +55 -8
  86. package/dinou/esbuild/react-refresh/esm-hmr/server.js +1 -1
  87. package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +238 -101
  88. package/dinou/esbuild/react-refresh/is-react-refresh-boundary.mjs +18 -4
  89. package/dinou/index.d.ts +315 -11
  90. package/dinou/index.js +12 -6
  91. package/dinou/index.mjs +9 -0
  92. package/dinou/node/build.mjs +195 -0
  93. package/dinou/node/bundle-dual-engine.mjs +1012 -0
  94. package/dinou/node/dev.mjs +2589 -0
  95. package/dinou/node/port-selector.mjs +164 -0
  96. package/dinou/node/terminal-status.mjs +345 -0
  97. package/dinou/package.json +16 -14
  98. package/dinou/rollup/react-refresh/esm-hmr/client.js +66 -10
  99. package/dinou/rollup/react-refresh/esm-hmr/server.js +1 -1
  100. package/dinou/rollup/react-refresh/is-react-refresh-boundary.js +24 -5
  101. package/dinou/rollup/react-refresh/react-refresh-runtime.js +13 -6
  102. package/dinou/rollup/react-refresh/react-refresh-wrap-modules.js +56 -11
  103. package/dinou/rollup/react-refresh/rollup-plugin-esm-hmr.js +176 -48
  104. package/dinou/rollup/rollup-plugins/dinou-asset-plugin.js +9 -5
  105. package/dinou/rollup/rollup-plugins/rollup-plugin-memory.js +66 -0
  106. package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +468 -123
  107. package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +44 -12
  108. package/dinou/rollup/rollup-plugins/rollup-plugin-swc.js +100 -0
  109. package/dinou/rollup/rollup.config.js +155 -43
  110. package/dinou/server.d.ts +114 -12
  111. package/dinou/server.js +35 -10
  112. package/dinou/server.mjs +30 -9
  113. package/dinou/webpack/helpers/get-webpack-entries.js +14 -19
  114. package/dinou/webpack/loaders/server-functions-loader.js +22 -1
  115. package/dinou/webpack/loaders/swc-loader.js +76 -0
  116. package/dinou/webpack/plugins/manifest-generator-plugin.js +1 -0
  117. package/dinou/webpack/plugins/server-functions-plugin.js +75 -19
  118. package/dinou/webpack/plugins/webpack-memory-plugin.js +66 -0
  119. package/dinou/webpack/webpack.config.js +227 -29
  120. package/eject.js +113 -34
  121. package/package.json +18 -16
  122. package/dinou/core/asset-require-hook.js +0 -58
  123. package/dinou/core/client-error-webpack.jsx +0 -432
  124. package/dinou/core/client-error.jsx +0 -432
  125. package/dinou/core/concurrency-manager.js +0 -48
  126. package/dinou/core/context-proxy.js +0 -68
  127. package/dinou/core/generate-static-pages.js +0 -130
  128. package/dinou/core/generate-static-rscs.js +0 -151
  129. package/dinou/core/get-ssg-metadata.js +0 -31
  130. package/dinou/core/register-loader.mjs +0 -11
  131. package/dinou/core/register-paths.js +0 -27
  132. package/dinou/core/render-app-to-html.js +0 -430
  133. package/dinou/core/render-html.js +0 -407
  134. package/dinou/core/server.js +0 -1542
  135. package/dinou/esbuild/plugins-esbuild/write-metafile-plugin.mjs +0 -16
@@ -1,4 +1,5 @@
1
1
  const path = require("path");
2
+ const { pathToFileURL } = require("url");
2
3
  const { existsSync } = require("./vfs");
3
4
  const React = require("react");
4
5
  const {
@@ -6,6 +7,7 @@ const {
6
7
  } = require("./get-file-path-and-dynamic-params");
7
8
  const importModule = require("./import-module");
8
9
  const { asyncRenderJSXToClientJSX } = require("./render-jsx-to-client-jsx");
10
+ const { getLayoutProps } = require("./layout-functions");
9
11
 
10
12
  async function getJSX(
11
13
  reqPath,
@@ -13,74 +15,148 @@ async function getJSX(
13
15
  isNotFound = null,
14
16
  isDevelopment = false,
15
17
  forceNotFound = false,
18
+ options = {},
16
19
  ) {
17
20
  const srcFolder = path.resolve(process.cwd(), "src");
18
21
  const reqSegments = reqPath.split("/").filter(Boolean);
19
- const hasRouterSyntax = reqSegments.some((seg) => {
20
- const isGroup = seg.startsWith("(") && seg.endsWith(")");
21
-
22
- const isDynamic = seg.startsWith("[") && seg.endsWith("]");
23
- const isSlot = seg.startsWith("@");
24
-
25
- return isGroup || isDynamic || isSlot;
26
- });
27
-
28
- let pagePath;
29
- if (!hasRouterSyntax) {
30
- const folderPath = path.join(srcFolder, ...reqSegments);
31
- if (existsSync(folderPath)) {
32
- for (const ext of [".tsx", ".ts", ".jsx", ".js"]) {
33
- const candidatePath = path.join(folderPath, `page${ext}`);
34
- if (existsSync(candidatePath)) {
35
- pagePath = candidatePath;
36
- break;
37
- }
22
+ const normalizedReqPath =
23
+ "/" + reqSegments.join("/") + (reqSegments.length > 0 ? "/" : "");
24
+
25
+ let jsx;
26
+ let pageFunctionsProps;
27
+
28
+ // 1. Segmented handling for Layout: If only the layout is requested
29
+ if (options && options.segment === "layout") {
30
+ let { DinouPageSlot } = require("./slot.js");
31
+ if (
32
+ typeof DinouPageSlot === "function" &&
33
+ DinouPageSlot.$$typeof !== Symbol.for("react.client.reference")
34
+ ) {
35
+ const slotPath = path.resolve(__dirname, "slot.js");
36
+ const fileUrl = pathToFileURL(slotPath).href;
37
+ let regFn = null;
38
+ try {
39
+ const pkg = require("react-server-dom-webpack/server");
40
+ regFn = pkg.registerClientReference;
41
+ } catch (e) {}
42
+ if (!regFn) {
43
+ try {
44
+ const pkg = require("@roggc/react-server-dom-esm/server.node.js");
45
+ regFn = pkg.registerClientReference;
46
+ } catch (e) {}
47
+ }
48
+ if (regFn) {
49
+ DinouPageSlot = regFn(DinouPageSlot, fileUrl, "DinouPageSlot");
50
+ } else {
51
+ Object.defineProperties(DinouPageSlot, {
52
+ $$typeof: { value: Symbol.for("react.client.reference") },
53
+ $$id: { value: fileUrl + "#DinouPageSlot" },
54
+ });
38
55
  }
39
56
  }
40
- }
41
- let dynamicParams = {};
57
+ jsx = React.createElement(DinouPageSlot);
58
+ } else {
59
+ const hasRouterSyntax = reqSegments.some((seg) => {
60
+ const isGroup = seg.startsWith("(") && seg.endsWith(")");
42
61
 
43
- if (!pagePath) {
44
- const [filePath, dParams] = getFilePathAndDynamicParams(
45
- reqSegments,
46
- query,
47
- srcFolder,
48
- );
49
- pagePath = filePath;
50
- dynamicParams = dParams ?? {};
51
- }
62
+ const isDynamic = seg.startsWith("[") && seg.endsWith("]");
63
+ const isSlot = seg.startsWith("@");
64
+ const isPrivate = seg.startsWith("_");
52
65
 
53
- let jsx;
54
- let pageFunctionsProps;
66
+ return isGroup || isDynamic || isSlot || isPrivate;
67
+ });
55
68
 
56
- if (!pagePath || forceNotFound) {
57
- if (isNotFound) isNotFound.value = true;
58
- const [notFoundPath, dParams] = getFilePathAndDynamicParams(
59
- reqSegments,
60
- query,
61
- srcFolder,
62
- "not_found",
63
- true,
64
- false,
65
- );
66
- if (!notFoundPath) {
67
- jsx = React.createElement(
68
- "div",
69
- null,
70
- `Page not found: no "page" file found for "${reqPath}"`,
69
+ let pagePath;
70
+ let folderPath = "";
71
+ if (!hasRouterSyntax) {
72
+ folderPath = path.join(srcFolder, ...reqSegments);
73
+ if (existsSync(folderPath)) {
74
+ for (const ext of [".tsx", ".ts", ".jsx", ".js"]) {
75
+ const candidatePath = path.join(folderPath, `page${ext}`);
76
+ if (existsSync(candidatePath)) {
77
+ pagePath = candidatePath;
78
+ break;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ let dynamicParams = {};
84
+
85
+ if (!pagePath) {
86
+ const [filePath, dParams] = getFilePathAndDynamicParams(
87
+ reqSegments,
88
+ query,
89
+ srcFolder,
90
+ );
91
+ pagePath = filePath;
92
+ dynamicParams = dParams ?? {};
93
+ }
94
+
95
+ if (!pagePath || forceNotFound) {
96
+ if (isNotFound) isNotFound.value = true;
97
+ const [notFoundPath, dParams] = getFilePathAndDynamicParams(
98
+ reqSegments,
99
+ query,
100
+ srcFolder,
101
+ "not_found",
102
+ true,
103
+ false,
71
104
  );
105
+ if (!notFoundPath) {
106
+ jsx = React.createElement(
107
+ "div",
108
+ null,
109
+ `Page not found: no "page" file found for "${normalizedReqPath}"`,
110
+ );
111
+ } else {
112
+ const pageModule = await importModule(notFoundPath);
113
+ const Page = pageModule.default ?? pageModule;
114
+ let props = {
115
+ params: dParams ?? {},
116
+ };
117
+ const notFoundDir = path.dirname(notFoundPath);
118
+
119
+ const [pageFunctionsPath] = getFilePathAndDynamicParams(
120
+ reqSegments,
121
+ query,
122
+ notFoundDir,
123
+ "page_functions",
124
+ true,
125
+ true,
126
+ undefined,
127
+ reqSegments.length,
128
+ );
129
+ if (pageFunctionsPath) {
130
+ const pageFunctionsModule = await importModule(pageFunctionsPath);
131
+ const defaultExport = pageFunctionsModule.default?.default ? pageFunctionsModule.default.default : pageFunctionsModule.default;
132
+ const getProps = pageFunctionsModule.getProps || defaultExport?.getProps;
133
+ pageFunctionsProps = await getProps?.(dParams ?? {});
134
+ props = { ...props, ...(pageFunctionsProps ?? {}) };
135
+ }
136
+
137
+ jsx = React.createElement(Page, props);
138
+ const noLayoutNotFoundPath = path.join(
139
+ notFoundDir,
140
+ `no_layout_not_found`,
141
+ );
142
+ if (existsSync(noLayoutNotFoundPath)) {
143
+ return jsx;
144
+ }
145
+ }
72
146
  } else {
73
- const pageModule = await importModule(notFoundPath);
147
+ if (isNotFound) isNotFound.value = false;
148
+ const pageModule = await importModule(pagePath);
74
149
  const Page = pageModule.default ?? pageModule;
150
+
75
151
  let props = {
76
- params: dParams ?? {},
152
+ params: dynamicParams,
77
153
  };
78
- const notFoundDir = path.dirname(notFoundPath);
79
154
 
155
+ const pageFolder = path.dirname(pagePath);
80
156
  const [pageFunctionsPath] = getFilePathAndDynamicParams(
81
157
  reqSegments,
82
158
  query,
83
- notFoundDir,
159
+ pageFolder,
84
160
  "page_functions",
85
161
  true,
86
162
  true,
@@ -89,48 +165,19 @@ async function getJSX(
89
165
  );
90
166
  if (pageFunctionsPath) {
91
167
  const pageFunctionsModule = await importModule(pageFunctionsPath);
92
- const getProps = pageFunctionsModule.getProps;
93
- pageFunctionsProps = await getProps?.(dParams ?? {});
94
- props = { ...props, ...(pageFunctionsProps?.page ?? {}) };
168
+ const defaultExport = pageFunctionsModule.default?.default ? pageFunctionsModule.default.default : pageFunctionsModule.default;
169
+ const getProps = pageFunctionsModule.getProps || defaultExport?.getProps;
170
+ pageFunctionsProps = await getProps?.(dynamicParams);
171
+ props = { ...props, ...(pageFunctionsProps ?? {}) };
95
172
  }
96
173
 
97
174
  jsx = React.createElement(Page, props);
98
- const noLayoutNotFoundPath = path.join(
99
- notFoundDir,
100
- `no_layout_not_found`,
101
- );
102
- if (existsSync(noLayoutNotFoundPath)) {
103
- return jsx;
104
- }
105
175
  }
106
- } else {
107
- if (isNotFound) isNotFound.value = false;
108
- const pageModule = await importModule(pagePath);
109
- const Page = pageModule.default ?? pageModule;
110
-
111
- let props = {
112
- params: dynamicParams,
113
- };
114
176
 
115
- const pageFolder = path.dirname(pagePath);
116
- const [pageFunctionsPath] = getFilePathAndDynamicParams(
117
- reqSegments,
118
- query,
119
- pageFolder,
120
- "page_functions",
121
- true,
122
- true,
123
- undefined,
124
- reqSegments.length,
125
- );
126
- if (pageFunctionsPath) {
127
- const pageFunctionsModule = await importModule(pageFunctionsPath);
128
- const getProps = pageFunctionsModule.getProps;
129
- pageFunctionsProps = await getProps?.(dynamicParams);
130
- props = { ...props, ...(pageFunctionsProps?.page ?? {}) };
177
+ // 2. Segmented handling for Page: If only the page is requested, return without layouts
178
+ if (options && options.segment === "page") {
179
+ return jsx;
131
180
  }
132
-
133
- jsx = React.createElement(Page, props);
134
181
  }
135
182
 
136
183
  if (
@@ -172,14 +219,26 @@ async function getJSX(
172
219
  )[0];
173
220
  const Layout = layoutModule.default ?? layoutModule;
174
221
  const updatedSlots = {};
175
- for (const [slotName, slotElement] of Object.entries(slots)) {
222
+ for (const [slotName, slotValue] of Object.entries(slots)) {
176
223
  let updatedSlotElement;
224
+ const slotFilePath = slotValue?.slotPath || slotValue?.props?.__modulePath;
225
+ const slotParams = slotValue?.slotParams || slotValue?.props?.params || {};
177
226
  try {
178
- await asyncRenderJSXToClientJSX(slotElement);
179
- updatedSlotElement = slotElement;
227
+ let elementToRender;
228
+ if (slotValue && slotValue.slotPath) {
229
+ const slotModule = await importModule(slotValue.slotPath);
230
+ const Slot = slotModule.default ?? slotModule;
231
+ elementToRender = React.createElement(Slot, {
232
+ params: slotParams,
233
+ key: slotName,
234
+ __modulePath: slotValue.slotPath,
235
+ });
236
+ } else {
237
+ elementToRender = slotValue;
238
+ }
239
+ await asyncRenderJSXToClientJSX(elementToRender);
240
+ updatedSlotElement = elementToRender;
180
241
  } catch (e) {
181
- const slotFilePath = slotElement.props?.__modulePath;
182
-
183
242
  if (slotFilePath) {
184
243
  const realSlotFolder = path.dirname(slotFilePath);
185
244
 
@@ -226,11 +285,31 @@ async function getJSX(
226
285
  updatedSlots[slotName] = updatedSlotElement;
227
286
  }
228
287
  }
229
- let props = { params: dParams, ...updatedSlots };
230
- if (index === layouts.length - 1 || resetLayoutPath) {
231
- props = { ...props, ...(pageFunctionsProps?.layout ?? {}) };
288
+ const layoutProps = await getLayoutProps(layoutPath, dParams);
289
+ let props = { params: dParams, ...updatedSlots, ...(layoutProps ?? {}) };
290
+ try {
291
+ const testElement = React.createElement(Layout, props, null);
292
+ await asyncRenderJSXToClientJSX(testElement);
293
+ jsx = React.createElement(Layout, props, jsx);
294
+ } catch (layoutErr) {
295
+ console.warn(
296
+ `[Dinou] Layout ${layoutPath} failed during render, isolating layout error:`,
297
+ layoutErr?.message || layoutErr
298
+ );
299
+ const { getErrorJSX } = require("./get-error-jsx");
300
+ const serializedError = {
301
+ message: layoutErr.message || "Unknown Error",
302
+ name: layoutErr.name || "Error",
303
+ stack: isDevelopment ? layoutErr.stack : undefined,
304
+ };
305
+ jsx = await getErrorJSX(
306
+ reqPath,
307
+ query,
308
+ serializedError,
309
+ isDevelopment,
310
+ { segment: "page" }
311
+ );
232
312
  }
233
- jsx = React.createElement(Layout, props, jsx);
234
313
  if (resetLayoutPath) {
235
314
  break;
236
315
  }