dinou 6.1.0 → 7.0.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 +99 -0
  2. package/README.md +9461 -1080
  3. package/cli.js +392 -169
  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 +309 -157
  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 +172 -95
  39. package/dinou/core/handler.js +2296 -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 +181 -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 +207 -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 +133 -15
  53. package/dinou/core/request-context.js +47 -13
  54. package/dinou/core/resolve-module-ppr.js +32 -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 +17 -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 +173 -94
  121. package/package.json +110 -107
  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,147 @@ 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 getProps = pageFunctionsModule.getProps;
132
+ pageFunctionsProps = await getProps?.(dParams ?? {});
133
+ props = { ...props, ...(pageFunctionsProps ?? {}) };
134
+ }
135
+
136
+ jsx = React.createElement(Page, props);
137
+ const noLayoutNotFoundPath = path.join(
138
+ notFoundDir,
139
+ `no_layout_not_found`,
140
+ );
141
+ if (existsSync(noLayoutNotFoundPath)) {
142
+ return jsx;
143
+ }
144
+ }
72
145
  } else {
73
- const pageModule = await importModule(notFoundPath);
146
+ if (isNotFound) isNotFound.value = false;
147
+ const pageModule = await importModule(pagePath);
74
148
  const Page = pageModule.default ?? pageModule;
149
+
75
150
  let props = {
76
- params: dParams ?? {},
151
+ params: dynamicParams,
77
152
  };
78
- const notFoundDir = path.dirname(notFoundPath);
79
153
 
154
+ const pageFolder = path.dirname(pagePath);
80
155
  const [pageFunctionsPath] = getFilePathAndDynamicParams(
81
156
  reqSegments,
82
157
  query,
83
- notFoundDir,
158
+ pageFolder,
84
159
  "page_functions",
85
160
  true,
86
161
  true,
@@ -90,47 +165,17 @@ async function getJSX(
90
165
  if (pageFunctionsPath) {
91
166
  const pageFunctionsModule = await importModule(pageFunctionsPath);
92
167
  const getProps = pageFunctionsModule.getProps;
93
- pageFunctionsProps = await getProps?.(dParams ?? {});
94
- props = { ...props, ...(pageFunctionsProps?.page ?? {}) };
168
+ pageFunctionsProps = await getProps?.(dynamicParams);
169
+ props = { ...props, ...(pageFunctionsProps ?? {}) };
95
170
  }
96
171
 
97
172
  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
173
  }
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
174
 
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 ?? {}) };
175
+ // 2. Segmented handling for Page: If only the page is requested, return without layouts
176
+ if (options && options.segment === "page") {
177
+ return jsx;
131
178
  }
132
-
133
- jsx = React.createElement(Page, props);
134
179
  }
135
180
 
136
181
  if (
@@ -172,14 +217,26 @@ async function getJSX(
172
217
  )[0];
173
218
  const Layout = layoutModule.default ?? layoutModule;
174
219
  const updatedSlots = {};
175
- for (const [slotName, slotElement] of Object.entries(slots)) {
220
+ for (const [slotName, slotValue] of Object.entries(slots)) {
176
221
  let updatedSlotElement;
222
+ const slotFilePath = slotValue?.slotPath || slotValue?.props?.__modulePath;
223
+ const slotParams = slotValue?.slotParams || slotValue?.props?.params || {};
177
224
  try {
178
- await asyncRenderJSXToClientJSX(slotElement);
179
- updatedSlotElement = slotElement;
225
+ let elementToRender;
226
+ if (slotValue && slotValue.slotPath) {
227
+ const slotModule = await importModule(slotValue.slotPath);
228
+ const Slot = slotModule.default ?? slotModule;
229
+ elementToRender = React.createElement(Slot, {
230
+ params: slotParams,
231
+ key: slotName,
232
+ __modulePath: slotValue.slotPath,
233
+ });
234
+ } else {
235
+ elementToRender = slotValue;
236
+ }
237
+ await asyncRenderJSXToClientJSX(elementToRender);
238
+ updatedSlotElement = elementToRender;
180
239
  } catch (e) {
181
- const slotFilePath = slotElement.props?.__modulePath;
182
-
183
240
  if (slotFilePath) {
184
241
  const realSlotFolder = path.dirname(slotFilePath);
185
242
 
@@ -226,11 +283,31 @@ async function getJSX(
226
283
  updatedSlots[slotName] = updatedSlotElement;
227
284
  }
228
285
  }
229
- let props = { params: dParams, ...updatedSlots };
230
- if (index === layouts.length - 1 || resetLayoutPath) {
231
- props = { ...props, ...(pageFunctionsProps?.layout ?? {}) };
286
+ const layoutProps = await getLayoutProps(layoutPath, dParams);
287
+ let props = { params: dParams, ...updatedSlots, ...(layoutProps ?? {}) };
288
+ try {
289
+ const testElement = React.createElement(Layout, props, null);
290
+ await asyncRenderJSXToClientJSX(testElement);
291
+ jsx = React.createElement(Layout, props, jsx);
292
+ } catch (layoutErr) {
293
+ console.warn(
294
+ `[Dinou] Layout ${layoutPath} failed during render, isolating layout error:`,
295
+ layoutErr?.message || layoutErr
296
+ );
297
+ const { getErrorJSX } = require("./get-error-jsx");
298
+ const serializedError = {
299
+ message: layoutErr.message || "Unknown Error",
300
+ name: layoutErr.name || "Error",
301
+ stack: isDevelopment ? layoutErr.stack : undefined,
302
+ };
303
+ jsx = await getErrorJSX(
304
+ reqPath,
305
+ query,
306
+ serializedError,
307
+ isDevelopment,
308
+ { segment: "page" }
309
+ );
232
310
  }
233
- jsx = React.createElement(Layout, props, jsx);
234
311
  if (resetLayoutPath) {
235
312
  break;
236
313
  }