dinou 7.2.0 → 8.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 (114) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +1 -1
  3. package/cli.js +124 -121
  4. package/dinou/adapters/netlify.js +1 -0
  5. package/dinou/adapters/{node.mjs → node.js} +9 -3
  6. package/dinou/bun/{build.mjs → build.js} +20 -8
  7. package/dinou/cloudflare/{build.mjs → build.js} +23 -8
  8. package/dinou/cloudflare/shims/fs.js +3 -0
  9. package/dinou/constants.js +3 -3
  10. package/dinou/core/asset-extensions.js +5 -5
  11. package/dinou/core/bailout-proxy.js +3 -3
  12. package/dinou/core/build-static-pages.js +21 -17
  13. package/dinou/core/cache-revalidate.js +14 -33
  14. package/dinou/core/cache-slot.js +21 -10
  15. package/dinou/core/config.js +2 -5
  16. package/dinou/core/createScopedName.js +3 -3
  17. package/dinou/core/dinou-paths.js +15 -12
  18. package/dinou/core/generate-route-types.js +8 -3
  19. package/dinou/core/generate-static-page.js +6 -5
  20. package/dinou/core/generate-static-rsc.js +15 -10
  21. package/dinou/core/generate-static.js +11 -10
  22. package/dinou/core/generating-isg.js +12 -11
  23. package/dinou/core/get-abs-path-with-ext.js +8 -6
  24. package/dinou/core/get-asset-from-manifest.js +4 -4
  25. package/dinou/core/get-error-jsx.js +12 -9
  26. package/dinou/core/get-file-path-and-dynamic-params.js +7 -4
  27. package/dinou/core/get-jsx.js +19 -13
  28. package/dinou/core/handler.js +73 -33
  29. package/dinou/core/http-adapter.js +6 -2
  30. package/dinou/core/import-module.js +5 -4
  31. package/dinou/core/layout-functions.js +11 -6
  32. package/dinou/core/load-dinou-config.js +10 -4
  33. package/dinou/core/manifest-provider.js +11 -4
  34. package/dinou/core/parse-exports.js +11 -6
  35. package/dinou/core/path-utils.js +2 -2
  36. package/dinou/core/ppr-context.js +11 -11
  37. package/dinou/core/ppr-runtime.js +10 -6
  38. package/dinou/core/render-jsx-to-client-jsx.js +6 -3
  39. package/dinou/core/request-context.js +11 -7
  40. package/dinou/core/resolve-module-ppr.js +2 -2
  41. package/dinou/core/resolve-setup-files.js +70 -0
  42. package/dinou/core/revalidating.js +14 -25
  43. package/dinou/core/route-generator.js +12 -8
  44. package/dinou/core/rsc-renderer.js +13 -2
  45. package/dinou/core/run-ssg.js +9 -4
  46. package/dinou/core/safe-rename.js +3 -3
  47. package/dinou/core/scan-dependency-components.js +9 -3
  48. package/dinou/core/status-manifest.js +5 -5
  49. package/dinou/core/storage-adapter.js +13 -3
  50. package/dinou/core/url-resolver.js +2 -2
  51. package/dinou/core/vfs.js +7 -7
  52. package/dinou/deno/{build.mjs → build.js} +20 -8
  53. package/dinou/esbuild/{build.mjs → build.js} +4 -4
  54. package/dinou/esbuild/{dev.mjs → dev.js} +6 -6
  55. package/dinou/esbuild/helpers-esbuild/{get-config-esbuild-prod.mjs → get-config-esbuild-prod.js} +7 -7
  56. package/dinou/esbuild/helpers-esbuild/{get-config-esbuild.mjs → get-config-esbuild.js} +8 -8
  57. package/dinou/esbuild/helpers-esbuild/{get-esbuild-entries.mjs → get-esbuild-entries.js} +2 -2
  58. package/dinou/esbuild/plugins-esbuild/{assets-plugin.mjs → assets-plugin.js} +1 -1
  59. package/dinou/esbuild/plugins-esbuild/{stable-chunk-names-and-maps-plugin.mjs → stable-chunk-names-and-maps-plugin.js} +1 -1
  60. package/dinou/esbuild/plugins-esbuild/{write-plugin.mjs → write-plugin.js} +1 -1
  61. package/dinou/esbuild/plugins-postcss/postcss-extract-plugin.js +4 -3
  62. package/dinou/esbuild/react-refresh/babel-config.js +5 -1
  63. package/dinou/esbuild/react-refresh/esm-hmr/server.js +7 -4
  64. package/dinou/esbuild/react-refresh/{esm-hmr-plugin.mjs → esm-hmr-plugin.js} +4 -4
  65. package/dinou/esbuild/react-refresh/{react-refresh-runtime.mjs → react-refresh-runtime.js} +1 -1
  66. package/dinou/index.d.ts +13 -0
  67. package/dinou/index.js +40 -19
  68. package/dinou/node/{build.mjs → build.js} +10 -6
  69. package/dinou/node/{bundle-dual-engine.mjs → bundle-dual-engine.js} +22 -10
  70. package/dinou/node/{dev.mjs → dev.js} +43 -20
  71. package/dinou/package.json +8 -7
  72. package/dinou/rollup/postcss.config.js +1 -1
  73. package/dinou/rollup/react-refresh/esm-hmr/server.js +7 -4
  74. package/dinou/rollup/react-refresh/react-refresh-wrap-modules.js +2 -1
  75. package/dinou/rollup/react-refresh/rollup-plugin-esm-hmr.js +23 -16
  76. package/dinou/rollup/rollup-plugins/dinou-asset-plugin.js +6 -5
  77. package/dinou/rollup/rollup-plugins/manifest-generator-plugin.js +2 -1
  78. package/dinou/rollup/rollup-plugins/rollup-plugin-memory.js +3 -2
  79. package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +16 -13
  80. package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +7 -6
  81. package/dinou/rollup/rollup-plugins/rollup-plugin-swc.js +6 -3
  82. package/dinou/rollup/rollup.config.js +27 -23
  83. package/dinou/server.js +21 -26
  84. package/dinou/webpack/helpers/get-webpack-entries.js +14 -11
  85. package/dinou/webpack/loaders/server-functions-loader.js +5 -6
  86. package/dinou/webpack/loaders/swc-loader.js +4 -2
  87. package/dinou/webpack/plugins/manifest-generator-plugin.js +3 -1
  88. package/dinou/webpack/plugins/server-functions-plugin.js +4 -3
  89. package/dinou/webpack/plugins/webpack-memory-plugin.js +3 -2
  90. package/dinou/webpack/postcss.config.js +1 -1
  91. package/dinou/webpack/webpack.config.js +22 -20
  92. package/eject.js +198 -191
  93. package/package.json +111 -110
  94. package/dinou/config.js +0 -1
  95. package/dinou/config.mjs +0 -2
  96. package/dinou/core/css-require-hook.js +0 -64
  97. package/dinou/index.mjs +0 -43
  98. package/dinou/server.mjs +0 -30
  99. /package/dinou/core/{export-static.mjs → export-static.js} +0 -0
  100. /package/dinou/esbuild/helpers-esbuild/{normalize-path.mjs → normalize-path.js} +0 -0
  101. /package/dinou/esbuild/helpers-esbuild/{strip-namespace.mjs → strip-namespace.js} +0 -0
  102. /package/dinou/esbuild/helpers-esbuild/{swc-disk-cache.mjs → swc-disk-cache.js} +0 -0
  103. /package/dinou/esbuild/helpers-esbuild/{update-manifest-for-module.mjs → update-manifest-for-module.js} +0 -0
  104. /package/dinou/esbuild/helpers-esbuild/{write.mjs → write.js} +0 -0
  105. /package/dinou/esbuild/plugins-esbuild/{babel-react-compiler-plugin.mjs → babel-react-compiler-plugin.js} +0 -0
  106. /package/dinou/esbuild/plugins-esbuild/{css-processor-plugin.mjs → css-processor-plugin.js} +0 -0
  107. /package/dinou/esbuild/plugins-esbuild/{manifest-generator-plugin.mjs → manifest-generator-plugin.js} +0 -0
  108. /package/dinou/esbuild/plugins-esbuild/{react-client-manifest-plugin.mjs → react-client-manifest-plugin.js} +0 -0
  109. /package/dinou/esbuild/plugins-esbuild/{server-functions-plugin.mjs → server-functions-plugin.js} +0 -0
  110. /package/dinou/esbuild/plugins-esbuild/{skip-missing-entry-points-plugin.mjs → skip-missing-entry-points-plugin.js} +0 -0
  111. /package/dinou/esbuild/react-refresh/esm-hmr/{client.mjs → client.js} +0 -0
  112. /package/dinou/esbuild/react-refresh/{is-react-refresh-boundary.mjs → is-react-refresh-boundary.js} +0 -0
  113. /package/dinou/node/{port-selector.mjs → port-selector.js} +0 -0
  114. /package/dinou/node/{terminal-status.mjs → terminal-status.js} +0 -0
@@ -1,9 +1,9 @@
1
- const {
1
+ import {
2
2
  isPprBuildActive,
3
3
  enterSuspense,
4
4
  exitSuspense,
5
5
  registerHole,
6
- } = require("./ppr-context.js");
6
+ } from "./ppr-context.js";
7
7
 
8
8
  // Function to check if a component is a client component
9
9
  function isClientComponent(type) {
@@ -176,6 +176,9 @@ async function asyncRenderJSXToClientJSX(jsx, key = null) {
176
176
  }
177
177
  }
178
178
 
179
- module.exports = {
179
+ export {
180
+ asyncRenderJSXToClientJSX,
181
+ };
182
+ export default {
180
183
  asyncRenderJSXToClientJSX,
181
184
  };
@@ -1,14 +1,12 @@
1
1
  // dinou/core/request-context.js
2
-
3
2
  const DINOU_CONTEXT_KEY = Symbol.for("dinou.request.context.storage");
4
3
  let requestStorage;
5
4
 
6
5
  if (typeof window === "undefined") {
7
- let AsyncLocalStorageClass;
8
-
9
- if (typeof globalThis.AsyncLocalStorage !== "undefined") {
10
- AsyncLocalStorageClass = globalThis.AsyncLocalStorage;
11
- }
6
+ let AsyncLocalStorageClass =
7
+ typeof globalThis.AsyncLocalStorage !== "undefined"
8
+ ? globalThis.AsyncLocalStorage
9
+ : undefined;
12
10
 
13
11
  if (!AsyncLocalStorageClass) {
14
12
  try {
@@ -69,7 +67,13 @@ function getContext() {
69
67
  return store || getCurrentContext() || {};
70
68
  }
71
69
 
72
- module.exports = {
70
+ export {
71
+ requestStorage,
72
+ getContext,
73
+ setCurrentContext,
74
+ getCurrentContext,
75
+ };
76
+ export default {
73
77
  requestStorage,
74
78
  getContext,
75
79
  setCurrentContext,
@@ -3,7 +3,7 @@
3
3
  // Supports constants (export const ppr = true/false), sync functions (export function ppr()),
4
4
  // and async functions (export async function ppr()).
5
5
 
6
- async function resolveModulePpr(mod) {
6
+ export async function resolveModulePpr(mod) {
7
7
  if (!mod) return null;
8
8
  const raw =
9
9
  mod.ppr !== undefined
@@ -29,6 +29,6 @@ async function resolveModulePpr(mod) {
29
29
  return Boolean(raw);
30
30
  }
31
31
 
32
- module.exports = {
32
+ export default {
33
33
  resolveModulePpr,
34
34
  };
@@ -0,0 +1,70 @@
1
+ // dinou/core/resolve-setup-files.js
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+
5
+ /**
6
+ * Resolves setup files according to Dinou's configuration hierarchy:
7
+ * 1. Plugin setup files (plugin.setupFiles) always execute first.
8
+ * 2. User setup files:
9
+ * - If config.setupFiles is explicitly provided in dinou.config.mjs, it is the sole source of truth.
10
+ * - Otherwise, falls back to checking the project root for dinou.setup.mjs, dinou.setup.js, or dinou.setup.ts.
11
+ *
12
+ * @param {string} projectRoot
13
+ * @param {object} config - Dinou config object
14
+ * @returns {string[]} Array of absolute file paths to inject/execute
15
+ */
16
+ function resolveSetupFiles(projectRoot, config = {}) {
17
+ const pluginSetupFiles = [];
18
+ if (config.plugins && Array.isArray(config.plugins)) {
19
+ for (const plugin of config.plugins) {
20
+ if (plugin && Array.isArray(plugin.setupFiles)) {
21
+ for (const file of plugin.setupFiles) {
22
+ const resolved = path.isAbsolute(file)
23
+ ? file
24
+ : path.resolve(projectRoot, file);
25
+ if (fs.existsSync(resolved)) {
26
+ pluginSetupFiles.push(resolved);
27
+ } else {
28
+ console.warn(
29
+ `⚠️ [Dinou] Plugin "${plugin.name || "unnamed"}" specified setup file not found: ${file}`,
30
+ );
31
+ }
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+ let userSetupFiles = [];
38
+ if (Array.isArray(config.setupFiles)) {
39
+ // Explicit configuration takes precedence over convention
40
+ for (const file of config.setupFiles) {
41
+ const resolved = path.isAbsolute(file)
42
+ ? file
43
+ : path.resolve(projectRoot, file);
44
+ if (fs.existsSync(resolved)) {
45
+ userSetupFiles.push(resolved);
46
+ } else {
47
+ console.warn(`⚠️ [Dinou] Configured setupFile not found: ${file}`);
48
+ }
49
+ }
50
+ } else {
51
+ // Convention: check ONLY project root
52
+ const rootCandidates = [
53
+ "dinou.setup.mjs",
54
+ "dinou.setup.js",
55
+ "dinou.setup.ts",
56
+ ];
57
+ for (const name of rootCandidates) {
58
+ const fullPath = path.resolve(projectRoot, name);
59
+ if (fs.existsSync(fullPath)) {
60
+ userSetupFiles.push(fullPath);
61
+ break; // Only pick the highest priority extension match
62
+ }
63
+ }
64
+ }
65
+
66
+ return [...new Set([...pluginSetupFiles, ...userSetupFiles])];
67
+ }
68
+
69
+ export { resolveSetupFiles };
70
+ export default { resolveSetupFiles };
@@ -1,23 +1,8 @@
1
- const path = require("path");
2
- const fs = require("fs").promises;
3
- const { existsSync, copyFileSync } = require("fs");
4
- let _generateStaticPage = null;
5
- function getGenerateStaticPage() {
6
- if (!_generateStaticPage) _generateStaticPage = require("./generate-static-page");
7
- return _generateStaticPage;
8
- }
9
- let _buildStaticPage = null;
10
- function getBuildStaticPage() {
11
- if (!_buildStaticPage) _buildStaticPage = require("./build-static-pages").buildStaticPage;
12
- return _buildStaticPage;
13
- }
14
- let _generateStaticRSC = null;
15
- function getGenerateStaticRSC() {
16
- if (!_generateStaticRSC) _generateStaticRSC = require("./generate-static-rsc");
17
- return _generateStaticRSC;
18
- }
19
- const { safeRename } = require("./safe-rename");
20
- const { updateStatus } = require("./status-manifest");
1
+ import path from "node:path";
2
+ import fs from "node:fs/promises";
3
+ import { existsSync, copyFileSync } from "node:fs";
4
+ import { safeRename } from "./safe-rename.js";
5
+ import { updateStatus } from "./status-manifest.js";
21
6
 
22
7
  const regenerating = new Set();
23
8
 
@@ -63,18 +48,21 @@ function revalidating(reqPath, isDynamicFromServer) {
63
48
  (async () => {
64
49
  try {
65
50
  console.log(`[ISR] Starting regeneration for ${reqPath}...`);
51
+ const { buildStaticPage } = await import("./build-static-pages.js");
52
+ const { default: generateStaticRSC } = await import("./generate-static-rsc.js");
53
+ const { default: generateStaticPage } = await import("./generate-static-page.js");
54
+
66
55
  const isDynamic = {};
67
- await getBuildStaticPage()(reqPath, isDynamic);
56
+ await buildStaticPage(reqPath, isDynamic);
68
57
  if (isDynamic.value) {
69
58
  isDynamicFromServer.value = true;
70
59
  console.log(
71
60
  `[ISR] Bailout detected for ${reqPath}. Switching to Dynamic.`
72
61
  );
73
-
74
62
  return;
75
63
  }
76
64
 
77
- const rscResult = await getGenerateStaticRSC()(reqPath);
65
+ const rscResult = await generateStaticRSC(reqPath);
78
66
  if (!rscResult.success) {
79
67
  console.warn(`⚠️ [ISR] RSC generation failed for ${reqPath}. Aborting.`);
80
68
  await fs.unlink(rscResult.tempPath).catch(() => { });
@@ -84,7 +72,7 @@ function revalidating(reqPath, isDynamicFromServer) {
84
72
  // Commit the RSC payload immediately so that generateStaticPage can read it
85
73
  await safeRename(rscResult.tempPath, rscResult.finalPath);
86
74
 
87
- const pageResult = await getGenerateStaticPage()(reqPath);
75
+ const pageResult = await generateStaticPage(reqPath);
88
76
  if (pageResult.success) {
89
77
  await safeRename(pageResult.tempPath, pageResult.finalPath);
90
78
  updateStatus(reqPath, pageResult.status);
@@ -110,4 +98,5 @@ function revalidating(reqPath, isDynamicFromServer) {
110
98
 
111
99
  const inFlightGenerations = new Map();
112
100
 
113
- module.exports = { revalidating, regenerating, inFlightGenerations };
101
+ export { revalidating, regenerating, inFlightGenerations };
102
+ export default { revalidating, regenerating, inFlightGenerations };
@@ -1,6 +1,7 @@
1
- const fs = require("fs");
2
- const path = require("path");
3
- const parseExports = require("./parse-exports.js");
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import parseExports from "./parse-exports.js";
4
+ import { generateRouteTypes } from "./generate-route-types.js";
4
5
 
5
6
  function collectSourceFiles(dir, baseDir = dir) {
6
7
  if (!fs.existsSync(dir)) return [];
@@ -11,7 +12,7 @@ function collectSourceFiles(dir, baseDir = dir) {
11
12
  const fullPath = path.join(dir, entry.name);
12
13
  if (entry.isDirectory()) {
13
14
  files = files.concat(collectSourceFiles(fullPath, baseDir));
14
- } else if (/\.[jt]sx?$/.test(entry.name) && !entry.name.endsWith(".d.ts")) {
15
+ } else if (/\.(?:[jt]sx?|mjs)$/.test(entry.name) && !entry.name.endsWith(".d.ts")) {
15
16
  const relPath = path.relative(baseDir, fullPath).replace(/\\/g, "/");
16
17
  files.push({
17
18
  relPath: "src/" + relPath,
@@ -60,7 +61,7 @@ function generateRouteModulesCode(projectRoot = process.cwd(), relativeImportBas
60
61
  lines.push(` ${JSON.stringify(file.relPath)}: () => import(${JSON.stringify(importPath)}),`);
61
62
 
62
63
  // Detect PPR from page_functions or layout_functions ONLY
63
- if (/(?:^|\/)(?:page_functions|layout_functions|page\.functions|layout\.functions)\.[jt]sx?$/.test(file.relPath)) {
64
+ if (/(?:^|\/)(?:page_functions|layout_functions|page\.functions|layout\.functions)\.(?:[jt]sx?|mjs)$/.test(file.relPath)) {
64
65
  try {
65
66
  const content = fs.readFileSync(file.fullPath, "utf8");
66
67
  const isPpr = parseExports.parsePprConfig ? parseExports.parsePprConfig(content) : null;
@@ -98,9 +99,12 @@ function generateRouteModulesCode(projectRoot = process.cwd(), relativeImportBas
98
99
  return lines.join("\n");
99
100
  }
100
101
 
101
- const { generateRouteTypes } = require("./generate-route-types.js");
102
-
103
- module.exports = {
102
+ export {
103
+ collectSourceFiles,
104
+ generateRouteModulesCode,
105
+ generateRouteTypes,
106
+ };
107
+ export default {
104
108
  collectSourceFiles,
105
109
  generateRouteModulesCode,
106
110
  generateRouteTypes,
@@ -1,7 +1,10 @@
1
1
  // dinou/core/rsc-renderer.js
2
2
  // Universal RSC Stream Renderer supporting Node Streams and Web Streams (Cloudflare Workers / Edge).
3
3
 
4
- const { pathToFileURL } = require("url");
4
+ import { pathToFileURL } from "node:url";
5
+ import { createRequire } from "node:module";
6
+
7
+ const require = createRequire(import.meta.url);
5
8
 
6
9
  const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
7
10
 
@@ -31,6 +34,9 @@ function getNodeRenderer() {
31
34
 
32
35
  let edgeRender = null;
33
36
  function getEdgeRenderer() {
37
+ if (typeof globalThis !== "undefined" && globalThis.__DINOU_EDGE_RENDERER__) {
38
+ return globalThis.__DINOU_EDGE_RENDERER__;
39
+ }
34
40
  if (!edgeRender) {
35
41
  try {
36
42
  edgeRender = require("react-server-dom-webpack/server.edge");
@@ -83,7 +89,12 @@ function pipeRSC(model, bridge, manifest, options = {}) {
83
89
  pipe(bridge);
84
90
  }
85
91
 
86
- module.exports = {
92
+ export {
93
+ isEdgeRuntime,
94
+ renderRSCStream,
95
+ pipeRSC,
96
+ };
97
+ export default {
87
98
  isEdgeRuntime,
88
99
  renderRSCStream,
89
100
  pipeRSC,
@@ -3,17 +3,22 @@
3
3
  process.env.NODE_ENV = "production";
4
4
  process.env.DINOU_RUNTIME = "node-bundle";
5
5
 
6
- const generateStatic = require("./generate-static.js");
6
+ import { fileURLToPath } from "node:url";
7
+ import generateStatic from "./generate-static.js";
7
8
 
8
- async function runSSG() {
9
+ export async function runSSG() {
9
10
  await generateStatic();
10
11
  }
11
12
 
12
- if (require.main === module) {
13
+ const isMainModule =
14
+ process.argv[1] &&
15
+ fileURLToPath(import.meta.url) === process.argv[1];
16
+
17
+ if (isMainModule) {
13
18
  runSSG().catch((err) => {
14
19
  console.error("❌ [SSG] Static generation failed:", err);
15
20
  process.exit(1);
16
21
  });
17
22
  }
18
23
 
19
- module.exports = { runSSG };
24
+ export default { runSSG };
@@ -1,6 +1,6 @@
1
- const fs = require("fs").promises;
1
+ import fs from "node:fs/promises";
2
2
 
3
- async function safeRename(oldPath, newPath, retries = 5, delay = 100) {
3
+ export async function safeRename(oldPath, newPath, retries = 5, delay = 100) {
4
4
  for (let i = 0; i < retries; i++) {
5
5
  try {
6
6
  await fs.rename(oldPath, newPath);
@@ -22,4 +22,4 @@ async function safeRename(oldPath, newPath, retries = 5, delay = 100) {
22
22
  }
23
23
  }
24
24
 
25
- module.exports = { safeRename };
25
+ export default { safeRename };
@@ -1,8 +1,8 @@
1
1
  // dinou/core/scan-dependency-components.js
2
2
  // Scans dependencies for React "use client" directives without recursively walking massive trees.
3
3
 
4
- const fs = require("fs");
5
- const path = require("path");
4
+ import fs from "node:fs";
5
+ import path from "node:path";
6
6
 
7
7
  function isSupportedClientModule(filePath, content) {
8
8
  const norm = filePath.replace(/\\/g, "/");
@@ -210,7 +210,13 @@ async function scanProjectDependenciesForClientComponentsAsync(projectRoot, clie
210
210
  } catch (e) {}
211
211
  }
212
212
 
213
- module.exports = {
213
+ export {
214
+ isSupportedClientModule,
215
+ scanDependencyForClientComponents,
216
+ scanProjectDependenciesForClientComponents,
217
+ scanProjectDependenciesForClientComponentsAsync,
218
+ };
219
+ export default {
214
220
  isSupportedClientModule,
215
221
  scanDependencyForClientComponents,
216
222
  scanProjectDependenciesForClientComponents,
@@ -1,5 +1,5 @@
1
- const fs = require("fs");
2
- const path = require("path");
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
3
 
4
4
  const statusMap = new Map();
5
5
  let isLoaded = false;
@@ -30,7 +30,7 @@ function saveToFile() {
30
30
  } catch (e) {}
31
31
  }
32
32
 
33
- function getStatus(reqPath) {
33
+ export function getStatus(reqPath) {
34
34
  loadFromFile();
35
35
  // Also check without trailing slash or with trailing slash
36
36
  const clean = reqPath.endsWith("/") ? reqPath.slice(0, -1) : reqPath;
@@ -42,7 +42,7 @@ function getStatus(reqPath) {
42
42
  );
43
43
  }
44
44
 
45
- function updateStatus(reqPath, status) {
45
+ export function updateStatus(reqPath, status) {
46
46
  loadFromFile();
47
47
  const current = statusMap.get(reqPath)?.status;
48
48
  if (current === status) return;
@@ -51,4 +51,4 @@ function updateStatus(reqPath, status) {
51
51
  saveToFile();
52
52
  }
53
53
 
54
- module.exports = { getStatus, updateStatus };
54
+ export default { getStatus, updateStatus };
@@ -2,8 +2,8 @@
2
2
  // Pluggable storage abstraction for ISR/ISG cache and static artifacts.
3
3
  // Supports FileSystem (Node.js/Netlify/Docker), Cloudflare KV (Edge), and Memory.
4
4
 
5
- const path = require("path");
6
- const fs = require("fs");
5
+ import path from "node:path";
6
+ import fs from "node:fs";
7
7
 
8
8
  class StorageAdapter {
9
9
  async get(key) {
@@ -510,7 +510,17 @@ function setStorageAdapter(adapter) {
510
510
  globalThis[DINOU_STORAGE_KEY] = adapter;
511
511
  }
512
512
 
513
- module.exports = {
513
+ export {
514
+ StorageAdapter,
515
+ FileSystemStorage,
516
+ CloudflareKVStorage,
517
+ DenoKVStorage,
518
+ MemoryStorage,
519
+ RedisStorage,
520
+ getStorageAdapter,
521
+ setStorageAdapter,
522
+ };
523
+ export default {
514
524
  StorageAdapter,
515
525
  FileSystemStorage,
516
526
  CloudflareKVStorage,
@@ -1,4 +1,4 @@
1
- function resolveRelativeUrl(href, currentPathname) {
1
+ export function resolveRelativeUrl(href, currentPathname) {
2
2
  if (!href || typeof href !== "string") {
3
3
  return "/";
4
4
  }
@@ -13,4 +13,4 @@ function resolveRelativeUrl(href, currentPathname) {
13
13
  return resolved.pathname + resolved.search + resolved.hash;
14
14
  }
15
15
 
16
- module.exports = { resolveRelativeUrl };
16
+ export default { resolveRelativeUrl };
package/dinou/core/vfs.js CHANGED
@@ -1,5 +1,5 @@
1
- const fs = require("fs");
2
- const path = require("path");
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
3
 
4
4
  const isDevelopment =
5
5
  process.env.DINOU_DEV === "true" ||
@@ -7,7 +7,7 @@ const isDevelopment =
7
7
  process.env.NODE_ENV !== "production";
8
8
  const localVfs = {};
9
9
 
10
- function getVfs() {
10
+ export function getVfs() {
11
11
  if (typeof globalThis !== "undefined" && globalThis.__DINOU_VFS__) {
12
12
  return globalThis.__DINOU_VFS__;
13
13
  }
@@ -21,7 +21,7 @@ function normalizeKey(p) {
21
21
  return s;
22
22
  }
23
23
 
24
- function buildVfs(dir, baseDir = dir) {
24
+ export function buildVfs(dir, baseDir = dir) {
25
25
  const vfs = getVfs();
26
26
  if (!fs.existsSync(dir)) return;
27
27
  const entries = fs.readdirSync(dir, { withFileTypes: true });
@@ -94,7 +94,7 @@ function lookupVfs(vfs, p) {
94
94
  return null;
95
95
  }
96
96
 
97
- function existsSync(filePath) {
97
+ export function existsSync(filePath) {
98
98
  const vfs = getVfs();
99
99
  if (lookupVfs(vfs, filePath) !== null) {
100
100
  return true;
@@ -107,7 +107,7 @@ function existsSync(filePath) {
107
107
  return false;
108
108
  }
109
109
 
110
- function readdirSync(dirPath, options) {
110
+ export function readdirSync(dirPath, options) {
111
111
  const vfs = getVfs();
112
112
  const entry = lookupVfs(vfs, dirPath);
113
113
 
@@ -131,7 +131,7 @@ function readdirSync(dirPath, options) {
131
131
  return [];
132
132
  }
133
133
 
134
- module.exports = {
134
+ export default {
135
135
  existsSync,
136
136
  readdirSync,
137
137
  buildVfs,
@@ -7,23 +7,30 @@
7
7
  import fs from "node:fs";
8
8
  import path from "node:path";
9
9
  import esbuild from "esbuild";
10
- import { createRequire } from "node:module";
11
10
  import { fileURLToPath, pathToFileURL } from "node:url";
12
11
 
13
- const require = createRequire(import.meta.url);
14
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
15
- const { generateRouteModulesCode, generateRouteTypes } = require("../core/route-generator.js");
16
- const parseExports = require("../core/parse-exports.js");
17
- const { useClientRegex, useServerRegex } = require("../constants.js");
18
- const {
12
+ import { generateRouteModulesCode, generateRouteTypes } from "../core/route-generator.js";
13
+ import parseExports from "../core/parse-exports.js";
14
+ import { useClientRegex, useServerRegex } from "../constants.js";
15
+ import {
19
16
  isSupportedClientModule,
20
17
  scanProjectDependenciesForClientComponents,
21
- } = require("../core/scan-dependency-components.js");
18
+ } from "../core/scan-dependency-components.js";
19
+ import { getDinouConfig } from "../core/load-dinou-config.js";
20
+ import { resolveSetupFiles } from "../core/resolve-setup-files.js";
21
+
22
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
22
23
 
23
24
  const projectRoot = process.cwd();
24
25
  const denoDir = path.resolve(projectRoot, ".dinou/deno");
25
26
  fs.mkdirSync(denoDir, { recursive: true });
26
27
 
28
+ const dinouConfig = await getDinouConfig(projectRoot);
29
+ const setupFiles = resolveSetupFiles(projectRoot, dinouConfig);
30
+ if (setupFiles.length > 0) {
31
+ console.log(` 🔌 [Dinou Setup] Active setup files (${setupFiles.length}): ${setupFiles.map((f) => path.basename(f)).join(", ")}`);
32
+ }
33
+
27
34
  try {
28
35
  generateRouteTypes(projectRoot);
29
36
  } catch (e) {}
@@ -687,6 +694,8 @@ fs.writeFileSync(ssrClientManifestPath, ssrManifestCode, "utf8");
687
694
  const rscEntryContent = `// Auto-generated RSC Engine entry for Deno Deploy / Edge
688
695
  import "./env-setup.js";
689
696
  import "./route-modules.js";
697
+ import * as edgeRenderer from "react-server-dom-webpack/server.edge";
698
+ globalThis.__DINOU_EDGE_RENDERER__ = edgeRenderer;
690
699
  export { handleRequest } from "${dinouDirSlash}/core/handler.js";
691
700
  `;
692
701
  const rscEntryPath = path.join(denoDir, "rsc-entry.js");
@@ -1046,6 +1055,7 @@ try {
1046
1055
  alias: commonAlias,
1047
1056
  loader: commonLoader,
1048
1057
  jsx: "automatic",
1058
+ inject: setupFiles.length > 0 ? setupFiles : undefined,
1049
1059
  define: {
1050
1060
  "process.env.NODE_ENV": '"production"',
1051
1061
  "process.env.DINOU_RUNTIME": '"deno-edge"',
@@ -1069,6 +1079,7 @@ try {
1069
1079
  alias: commonAlias,
1070
1080
  loader: commonLoader,
1071
1081
  jsx: "automatic",
1082
+ inject: setupFiles.length > 0 ? setupFiles : undefined,
1072
1083
  define: {
1073
1084
  "process.env.NODE_ENV": '"production"',
1074
1085
  "process.env.DINOU_RUNTIME": '"deno-edge"',
@@ -1090,6 +1101,7 @@ try {
1090
1101
  conditions: ["deno", "worker", "browser"],
1091
1102
  external: externalList,
1092
1103
  banner,
1104
+ inject: setupFiles.length > 0 ? setupFiles : undefined,
1093
1105
  alias: commonAlias,
1094
1106
  loader: commonLoader,
1095
1107
  define: {
@@ -1,10 +1,10 @@
1
1
  import esbuild from "esbuild";
2
2
  import fs from "node:fs/promises";
3
- import getConfigEsbuildProd from "./helpers-esbuild/get-config-esbuild-prod.mjs";
4
- import getEsbuildEntries from "./helpers-esbuild/get-esbuild-entries.mjs";
3
+ import getConfigEsbuildProd from "./helpers-esbuild/get-config-esbuild-prod.js";
4
+ import getEsbuildEntries from "./helpers-esbuild/get-esbuild-entries.js";
5
5
  import { fileURLToPath } from "url";
6
6
  import path from "node:path";
7
- import { updateManifestForModule } from "./helpers-esbuild/update-manifest-for-module.mjs";
7
+ import { updateManifestForModule } from "./helpers-esbuild/update-manifest-for-module.js";
8
8
 
9
9
  const __filename = fileURLToPath(import.meta.url);
10
10
  const __dirname = path.dirname(__filename);
@@ -33,7 +33,7 @@ const frameworkEntryPoints = {
33
33
  __dirname,
34
34
  "../core/server-function-proxy.js"
35
35
  ),
36
- runtime: path.resolve(__dirname, "react-refresh/react-refresh-runtime.mjs"),
36
+ runtime: path.resolve(__dirname, "react-refresh/react-refresh-runtime.js"),
37
37
  "react-refresh-entry": path.resolve(
38
38
  __dirname,
39
39
  "react-refresh/react-refresh-entry.js"
@@ -5,17 +5,17 @@ if (!process.env.NODE_ENV) {
5
5
 
6
6
  import esbuild from "esbuild";
7
7
  import fs from "node:fs/promises";
8
- import getConfigEsbuild from "./helpers-esbuild/get-config-esbuild.mjs";
9
- import getEsbuildEntries from "./helpers-esbuild/get-esbuild-entries.mjs";
8
+ import getConfigEsbuild from "./helpers-esbuild/get-config-esbuild.js";
9
+ import getEsbuildEntries from "./helpers-esbuild/get-esbuild-entries.js";
10
10
  import path from "node:path";
11
- import normalizePath from "./helpers-esbuild/normalize-path.mjs";
11
+ import normalizePath from "./helpers-esbuild/normalize-path.js";
12
12
  import { fileURLToPath } from "url";
13
- import { updateManifestForModule } from "./helpers-esbuild/update-manifest-for-module.mjs";
13
+ import { updateManifestForModule } from "./helpers-esbuild/update-manifest-for-module.js";
14
14
  import {
15
15
  syncAllSwcFiles,
16
16
  transformToDisk,
17
17
  getMirrorPath,
18
- } from "./helpers-esbuild/swc-disk-cache.mjs";
18
+ } from "./helpers-esbuild/swc-disk-cache.js";
19
19
 
20
20
  const __filename = fileURLToPath(import.meta.url);
21
21
  const __dirname = path.dirname(__filename);
@@ -59,7 +59,7 @@ export async function startEsbuildDev(options = {}) {
59
59
  __dirname,
60
60
  "../core/server-function-proxy.js"
61
61
  ),
62
- runtime: path.resolve(__dirname, "react-refresh/react-refresh-runtime.mjs"),
62
+ runtime: path.resolve(__dirname, "react-refresh/react-refresh-runtime.js"),
63
63
  "react-refresh-entry": path.resolve(
64
64
  __dirname,
65
65
  "react-refresh/react-refresh-entry.js"
@@ -1,12 +1,12 @@
1
1
  import { TsconfigPathsPlugin } from "@esbuild-plugins/tsconfig-paths";
2
- import reactClientManifestPlugin from "../plugins-esbuild/react-client-manifest-plugin.mjs";
3
- import serverFunctionsPlugin from "../plugins-esbuild/server-functions-plugin.mjs";
4
- import cssProcessorPlugin from "../plugins-esbuild/css-processor-plugin.mjs";
5
- import assetsPlugin from "../plugins-esbuild/assets-plugin.mjs";
2
+ import reactClientManifestPlugin from "../plugins-esbuild/react-client-manifest-plugin.js";
3
+ import serverFunctionsPlugin from "../plugins-esbuild/server-functions-plugin.js";
4
+ import cssProcessorPlugin from "../plugins-esbuild/css-processor-plugin.js";
5
+ import assetsPlugin from "../plugins-esbuild/assets-plugin.js";
6
6
  import copyStaticFiles from "esbuild-copy-static-files";
7
- import manifestGeneratorPlugin from "../plugins-esbuild/manifest-generator-plugin.mjs";
8
- import writePlugin from "../plugins-esbuild/write-plugin.mjs";
9
- import babelReactCompilerPlugin from "../plugins-esbuild/babel-react-compiler-plugin.mjs";
7
+ import manifestGeneratorPlugin from "../plugins-esbuild/manifest-generator-plugin.js";
8
+ import writePlugin from "../plugins-esbuild/write-plugin.js";
9
+ import babelReactCompilerPlugin from "../plugins-esbuild/babel-react-compiler-plugin.js";
10
10
  import { existsSync } from "node:fs";
11
11
 
12
12
  const manifestData = {};
@@ -1,11 +1,11 @@
1
- import reactClientManifestPlugin from "../plugins-esbuild/react-client-manifest-plugin.mjs";
2
- import serverFunctionsPlugin from "../plugins-esbuild/server-functions-plugin.mjs";
3
- import cssProcessorPlugin from "../plugins-esbuild/css-processor-plugin.mjs";
4
- import esmHmrPlugin from "../react-refresh/esm-hmr-plugin.mjs";
5
- import stableChunkNamesAndMapsPlugin from "../plugins-esbuild/stable-chunk-names-and-maps-plugin.mjs";
6
- import assetsPlugin from "../plugins-esbuild/assets-plugin.mjs";
7
- import skipMissingEntryPointsPlugin from "../plugins-esbuild/skip-missing-entry-points-plugin.mjs";
8
- import { swcRedirectPlugin } from "./swc-disk-cache.mjs";
1
+ import reactClientManifestPlugin from "../plugins-esbuild/react-client-manifest-plugin.js";
2
+ import serverFunctionsPlugin from "../plugins-esbuild/server-functions-plugin.js";
3
+ import cssProcessorPlugin from "../plugins-esbuild/css-processor-plugin.js";
4
+ import esmHmrPlugin from "../react-refresh/esm-hmr-plugin.js";
5
+ import stableChunkNamesAndMapsPlugin from "../plugins-esbuild/stable-chunk-names-and-maps-plugin.js";
6
+ import assetsPlugin from "../plugins-esbuild/assets-plugin.js";
7
+ import skipMissingEntryPointsPlugin from "../plugins-esbuild/skip-missing-entry-points-plugin.js";
8
+ import { swcRedirectPlugin } from "./swc-disk-cache.js";
9
9
  import fs from "node:fs";
10
10
  import path from "node:path";
11
11