dinou 6.0.0 → 6.0.1

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/CHANGELOG.md CHANGED
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/).
7
7
 
8
+ ## [6.0.1] - 2026-09-14
9
+
10
+ ### Fixed
11
+ - **ESM Loader Module Harmonization (Dev Mode)**: Fixed module instance bifurcation in Node.js by synchronizing URL resolution between static ESM imports (`babel-esm-loader.js`) and dynamic Server Function imports (`import-module.js`) using consistent `?mtime` cache-busting. Server Functions and SSR now share the exact same in-memory module instances and state across page reloads without requiring `globalThis` or disk persistence.
12
+ - **Loader Query Param Sanitization**: Stripped query parameters from `parentURL` and `specifier` in `get-abs-path-with-ext.js` to prevent path resolution and extension lookup issues on relative imports decorated with `?mtime`.
13
+ - **Asset & CSS Loader Safe Resolution**: Ensured asset and CSS hooks in `babel-esm-loader.js` strip query strings before calling `fileURLToPath` and Node's `require()`.
14
+ - **Loader Return URL Consistency**: Updated `babel-esm-loader.js` `load` hooks to preserve the incoming resolved module URL across all code paths, avoiding cache mismatches in Node's module graph.
15
+
8
16
  ## [6.0.0] - 2026-09-13
9
17
 
10
18
  ### Changed
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # **Dinou**
2
2
 
3
- [![Documentation](https://img.shields.io/badge/docs-dinou.dev-blue?style=flat-square)](https://dinou.dev) [![Version](https://img.shields.io/badge/version-5.1.0-orange?style=flat-square)](https://www.npmjs.com/package/dinou)
3
+ [![Documentation](https://img.shields.io/badge/docs-dinou.dev-blue?style=flat-square)](https://dinou.dev) [![Version](https://img.shields.io/badge/version-6.0.1-orange?style=flat-square)](https://www.npmjs.com/package/dinou)
4
4
 
5
5
  ### **Lightweight-Ejectable Full-Stack React 19 Framework**
6
6
 
@@ -41,10 +41,22 @@ Module._resolveFilename = function (request, parent, isMain, options) {
41
41
 
42
42
  require("./css-require-hook.js")();
43
43
 
44
+ function getMtimeParam(absPath) {
45
+ try {
46
+ const stats = fs.statSync(absPath);
47
+ return Math.round(stats.mtimeMs);
48
+ } catch (e) {
49
+ return Date.now();
50
+ }
51
+ }
52
+
44
53
  exports.resolve = async function resolve(specifier, context, defaultResolve) {
45
54
  const absPathWithExt = getAbsPathWithExt(specifier, context);
46
55
  if (absPathWithExt) {
47
- const url = pathToFileURL(absPathWithExt).href;
56
+ let url = pathToFileURL(absPathWithExt).href;
57
+ if (process.env.NODE_ENV !== "production") {
58
+ url += `?mtime=${getMtimeParam(absPathWithExt)}`;
59
+ }
48
60
 
49
61
  return {
50
62
  url,
@@ -63,7 +75,7 @@ exports.load = async function load(url, context, defaultLoad) {
63
75
 
64
76
  if (assetExts.includes(ext)) {
65
77
  // Return a tiny stub that mimics what asset-require-hook would do
66
- const filepath = fileURLToPath(url);
78
+ const filepath = fileURLToPath(url.split("?")[0]);
67
79
  const localName = path.basename(filepath, ext);
68
80
  const hashedName = createScopedName(localName, filepath);
69
81
  const virtualExport = `export default "/assets/${hashedName}${ext}";`;
@@ -77,7 +89,7 @@ exports.load = async function load(url, context, defaultLoad) {
77
89
  }
78
90
 
79
91
  if (ext === ".css") {
80
- const mod = require(fileURLToPath(url));
92
+ const mod = require(fileURLToPath(url.split("?")[0]));
81
93
  const source = `export default ${JSON.stringify(mod)};`;
82
94
  return { format: "module", source, shortCircuit: true, url };
83
95
  }
@@ -145,7 +157,7 @@ exports.load = async function load(url, context, defaultLoad) {
145
157
  format: "module",
146
158
  source: newSrc,
147
159
  shortCircuit: true,
148
- url: urlToReturn,
160
+ url,
149
161
  };
150
162
  }
151
163
 
@@ -187,7 +199,7 @@ exports.load = async function load(url, context, defaultLoad) {
187
199
  format: "module",
188
200
  source: newSrc,
189
201
  shortCircuit: true,
190
- url: urlToReturn,
202
+ url,
191
203
  };
192
204
  }
193
205
 
@@ -216,7 +228,7 @@ exports.load = async function load(url, context, defaultLoad) {
216
228
  format: "module",
217
229
  source: code,
218
230
  shortCircuit: true,
219
- url: urlToReturn,
231
+ url,
220
232
  };
221
233
  }
222
234
 
@@ -78,22 +78,26 @@ function tryExtensions(filePath) {
78
78
  }
79
79
 
80
80
  exports.getAbsPathWithExt = function getAbsPathWithExt(specifier, context) {
81
+ const cleanSpecifier = specifier ? specifier.split("?")[0] : specifier;
82
+ if (!cleanSpecifier) return null;
83
+
81
84
  if (aliasMap.size > 0) {
82
85
  for (const [alias, info] of aliasMap.entries()) {
83
- if (specifier.startsWith(alias)) {
86
+ if (cleanSpecifier.startsWith(alias)) {
84
87
  const absPath = path.resolve(
85
88
  info.resolvedTargetBase,
86
- specifier.slice(alias.length)
89
+ cleanSpecifier.slice(alias.length)
87
90
  );
88
91
  return tryExtensions(absPath);
89
92
  }
90
93
  }
91
94
  }
92
95
 
93
- if (specifier.startsWith("./") || specifier.startsWith("../")) {
94
- const parentURL = context.parentURL || pathToFileURL(process.cwd()).href;
95
- const parentDir = path.dirname(fileURLToPath(parentURL));
96
- const absPath = path.resolve(parentDir, specifier);
96
+ if (cleanSpecifier.startsWith("./") || cleanSpecifier.startsWith("../")) {
97
+ const parentURL = context?.parentURL || pathToFileURL(process.cwd()).href;
98
+ const cleanParentURL = parentURL.split("?")[0];
99
+ const parentDir = path.dirname(fileURLToPath(cleanParentURL));
100
+ const absPath = path.resolve(parentDir, cleanSpecifier);
97
101
  return tryExtensions(absPath);
98
102
  }
99
103
 
@@ -1,43 +1,53 @@
1
- const { pathToFileURL } = require("url");
2
- const path = require("path");
3
- const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
4
-
5
- async function importModule(modulePath) {
6
- const absPath = path.isAbsolute(modulePath)
7
- ? modulePath
8
- : path.resolve(process.cwd(), modulePath);
9
-
10
- if (!isWebpack) {
11
- let fileUrl = pathToFileURL(absPath).href;
12
- if (process.env.NODE_ENV !== "production") {
13
- fileUrl += `?t=${Date.now()}`;
14
- }
15
- const mod = await import(fileUrl);
16
- return mod;
17
- }
18
-
19
- try {
20
- if (process.env.NODE_ENV !== "production") {
21
- try {
22
- const resolved = require.resolve(absPath);
23
- delete require.cache[resolved];
24
- } catch (e) {}
25
- }
26
- return require(absPath);
27
- } catch (err) {
28
- if (
29
- err.code === "ERR_REQUIRE_ESM" ||
30
- /require\(\) of ES Module/.test(err.message)
31
- ) {
32
- let fileUrl = pathToFileURL(absPath).href;
33
- if (process.env.NODE_ENV !== "production") {
34
- fileUrl += `?t=${Date.now()}`;
35
- }
36
- const mod = await import(fileUrl);
37
- return mod;
38
- }
39
- throw err;
40
- }
41
- }
42
-
43
- module.exports = importModule;
1
+ const { pathToFileURL } = require("url");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
5
+
6
+ function getMtimeParam(absPath) {
7
+ try {
8
+ const stats = fs.statSync(absPath);
9
+ return Math.round(stats.mtimeMs);
10
+ } catch (e) {
11
+ return Date.now();
12
+ }
13
+ }
14
+
15
+ async function importModule(modulePath) {
16
+ const absPath = path.isAbsolute(modulePath)
17
+ ? modulePath
18
+ : path.resolve(process.cwd(), modulePath);
19
+
20
+ if (!isWebpack) {
21
+ let fileUrl = pathToFileURL(absPath).href;
22
+ if (process.env.NODE_ENV !== "production") {
23
+ fileUrl += `?mtime=${getMtimeParam(absPath)}`;
24
+ }
25
+ const mod = await import(fileUrl);
26
+ return mod;
27
+ }
28
+
29
+ try {
30
+ if (process.env.NODE_ENV !== "production") {
31
+ try {
32
+ const resolved = require.resolve(absPath);
33
+ delete require.cache[resolved];
34
+ } catch (e) {}
35
+ }
36
+ return require(absPath);
37
+ } catch (err) {
38
+ if (
39
+ err.code === "ERR_REQUIRE_ESM" ||
40
+ /require\(\) of ES Module/.test(err.message)
41
+ ) {
42
+ let fileUrl = pathToFileURL(absPath).href;
43
+ if (process.env.NODE_ENV !== "production") {
44
+ fileUrl += `?mtime=${getMtimeParam(absPath)}`;
45
+ }
46
+ const mod = await import(fileUrl);
47
+ return mod;
48
+ }
49
+ throw err;
50
+ }
51
+ }
52
+
53
+ module.exports = importModule;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinou-ejected",
3
- "version": "6.0.0",
3
+ "version": "6.0.1",
4
4
  "main": "index.js",
5
5
  "private": true,
6
6
  "exports": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dinou",
3
- "version": "6.0.0",
3
+ "version": "6.0.1",
4
4
  "description": "Lightweight-Ejectable Full-Stack React 19 Framework with support for React Server Components (RSC), Server Functions, Server-Side Rendering (SSR), Static Generation (SSG), Incremental Static Generation (ISG), and Incremental Static Regeneration (ISR)",
5
5
  "main": "index.js",
6
6
  "bin": {