dinou 6.1.1 → 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 +94 -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 +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 +173 -94
  121. package/package.json +110 -108
  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
@@ -0,0 +1,261 @@
1
+ // dinou/core/manifest-provider.js
2
+ // Universal provider for RSC Client Manifest and Server Functions Manifest.
3
+ // Supports in-memory injection for Edge/Cloudflare Workers and disk fallback for Node.js.
4
+
5
+ const path = require("path");
6
+ const fs = require("fs");
7
+
8
+ let cachedClientManifest = null;
9
+ let cachedServerFunctionsManifest = null;
10
+
11
+ function isDevMode() {
12
+ return (
13
+ process.env.DINOU_DEV === "true" ||
14
+ (typeof globalThis !== "undefined" && Boolean(globalThis.__DINOU_DEV__)) ||
15
+ process.env.NODE_ENV !== "production"
16
+ );
17
+ }
18
+
19
+ function getOutputFolder() {
20
+ return isDevMode() ? ".dinou/public" : ".dinou/dist3";
21
+ }
22
+
23
+ function getClientManifestPath() {
24
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
25
+ const outputFolder = getOutputFolder();
26
+ return path.resolve(
27
+ process.cwd(),
28
+ isWebpack
29
+ ? `${outputFolder}/react-client-manifest.json`
30
+ : `.dinou/react_client_manifest/react-client-manifest.json`
31
+ );
32
+ }
33
+
34
+ function getServerFunctionsManifestPath() {
35
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
36
+ const outputFolder = getOutputFolder();
37
+ return path.resolve(
38
+ process.cwd(),
39
+ isWebpack
40
+ ? `${outputFolder}/server-functions-manifest.json`
41
+ : `.dinou/server_functions_manifest/server-functions-manifest.json`
42
+ );
43
+ }
44
+
45
+ function isManifestReady() {
46
+ if (typeof globalThis !== "undefined" && globalThis.__DINOU_CLIENT_MANIFEST__) {
47
+ return true;
48
+ }
49
+ try {
50
+ const p = getClientManifestPath();
51
+ return fs.existsSync(p) && fs.readFileSync(p, "utf8").trim().length > 2;
52
+ } catch (e) {
53
+ return false;
54
+ }
55
+ }
56
+
57
+ function createDevClientManifestProxy(target) {
58
+ if (!target || typeof target !== "object") return target;
59
+ if (target.__isDinouDevProxy) return target;
60
+
61
+ return new Proxy(target, {
62
+ get(obj, prop, receiver) {
63
+ if (prop === "__isDinouDevProxy") return true;
64
+ if (typeof prop !== "string") {
65
+ return Reflect.get(obj, prop, receiver);
66
+ }
67
+ if (prop in obj) {
68
+ return obj[prop];
69
+ }
70
+
71
+ // 1. Try drive-letter / url casing variations
72
+ let altProp = null;
73
+ if (prop.startsWith("file:///c:/")) {
74
+ altProp = "file:///C:/" + prop.slice(11);
75
+ } else if (prop.startsWith("file:///C:/")) {
76
+ altProp = "file:///c:/" + prop.slice(11);
77
+ }
78
+ if (altProp && altProp in obj) {
79
+ return obj[altProp];
80
+ }
81
+
82
+ // 2. Check in-memory base module entry
83
+ const hashIdx = prop.lastIndexOf("#");
84
+ const baseUri = hashIdx !== -1 ? prop.slice(0, hashIdx) : prop;
85
+ const expName = hashIdx !== -1 ? prop.slice(hashIdx + 1) : "default";
86
+
87
+ let altBaseUri = null;
88
+ if (baseUri.startsWith("file:///c:/")) {
89
+ altBaseUri = "file:///C:/" + baseUri.slice(11);
90
+ } else if (baseUri.startsWith("file:///C:/")) {
91
+ altBaseUri = "file:///c:/" + baseUri.slice(11);
92
+ }
93
+
94
+ if (hashIdx !== -1) {
95
+ const baseEntry = obj[baseUri] || (altBaseUri && obj[altBaseUri]);
96
+ if (baseEntry && baseEntry.id) {
97
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
98
+ const entry = {
99
+ ...baseEntry,
100
+ name: expName,
101
+ chunks: isWebpack ? (baseEntry.chunks || []) : expName,
102
+ };
103
+ obj[prop] = entry;
104
+ return entry;
105
+ }
106
+ }
107
+
108
+ // 3. Check if disk manifest has been updated
109
+ try {
110
+ const p = getClientManifestPath();
111
+ if (fs.existsSync(p)) {
112
+ const fresh = JSON.parse(fs.readFileSync(p, "utf8"));
113
+ if (fresh[prop]) {
114
+ const entry = { ...fresh[prop] };
115
+ if (hashIdx !== -1) {
116
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
117
+ entry.name = expName;
118
+ if (!isWebpack) entry.chunks = expName;
119
+ }
120
+ obj[prop] = entry;
121
+ return entry;
122
+ }
123
+ if (altProp && fresh[altProp]) {
124
+ const entry = { ...fresh[altProp] };
125
+ if (hashIdx !== -1) {
126
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
127
+ entry.name = expName;
128
+ if (!isWebpack) entry.chunks = expName;
129
+ }
130
+ obj[prop] = entry;
131
+ return entry;
132
+ }
133
+ if (hashIdx !== -1) {
134
+ const baseEntry = fresh[baseUri] || (altBaseUri && fresh[altBaseUri]);
135
+ if (baseEntry) {
136
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
137
+ const entry = {
138
+ ...baseEntry,
139
+ name: expName,
140
+ chunks: isWebpack ? (baseEntry.chunks || []) : expName,
141
+ };
142
+ obj[prop] = entry;
143
+ return entry;
144
+ }
145
+ }
146
+ }
147
+ } catch (e) {}
148
+
149
+ // 4. Fallback for client files in src/ during hot edits
150
+ if (baseUri.startsWith("file:///")) {
151
+ try {
152
+ const { fileURLToPath } = require("url");
153
+ const localPath = fileURLToPath(baseUri);
154
+ if (fs.existsSync(localPath)) {
155
+ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
156
+ const fallbackEntry = {
157
+ id: baseUri,
158
+ chunks: isWebpack ? [] : expName,
159
+ name: expName,
160
+ };
161
+ obj[prop] = fallbackEntry;
162
+ if (!obj[baseUri]) {
163
+ obj[baseUri] = { id: baseUri, chunks: isWebpack ? [] : "default", name: "*" };
164
+ }
165
+ return fallbackEntry;
166
+ }
167
+ } catch (e) {}
168
+ }
169
+
170
+ return Reflect.get(obj, prop, receiver);
171
+ },
172
+ });
173
+ }
174
+
175
+ function getClientManifest() {
176
+ if (typeof globalThis !== "undefined" && globalThis.__DINOU_CLIENT_MANIFEST__) {
177
+ const manifest = globalThis.__DINOU_CLIENT_MANIFEST__;
178
+ if (isDevMode() && !manifest.__isDinouDevProxy) {
179
+ globalThis.__DINOU_CLIENT_MANIFEST__ = createDevClientManifestProxy(manifest);
180
+ return globalThis.__DINOU_CLIENT_MANIFEST__;
181
+ }
182
+ return manifest;
183
+ }
184
+ const isDevelopment = isDevMode();
185
+ if (!isDevelopment && cachedClientManifest) {
186
+ return cachedClientManifest;
187
+ }
188
+ try {
189
+ const p = getClientManifestPath();
190
+ if (fs.existsSync(p)) {
191
+ const parsed = JSON.parse(fs.readFileSync(p, "utf8"));
192
+ if (!isDevelopment) cachedClientManifest = parsed;
193
+ return isDevelopment ? createDevClientManifestProxy(parsed) : parsed;
194
+ }
195
+ } catch (e) {}
196
+ return cachedClientManifest || (isDevelopment ? createDevClientManifestProxy({}) : {});
197
+ }
198
+
199
+ function setClientManifest(manifest) {
200
+ cachedClientManifest = manifest;
201
+ if (typeof globalThis !== "undefined") {
202
+ globalThis.__DINOU_CLIENT_MANIFEST__ = isDevMode()
203
+ ? createDevClientManifestProxy(manifest)
204
+ : manifest;
205
+ }
206
+ }
207
+
208
+ function getServerFunctionsManifest() {
209
+ if (typeof globalThis !== "undefined" && globalThis.__DINOU_SERVER_FUNCTIONS_MANIFEST__) {
210
+ const raw = globalThis.__DINOU_SERVER_FUNCTIONS_MANIFEST__;
211
+ if (raw instanceof Map) return raw;
212
+ const parsed = {};
213
+ for (const key in raw) {
214
+ parsed[key] = raw[key] instanceof Set ? raw[key] : new Set(raw[key]);
215
+ }
216
+ return parsed;
217
+ }
218
+
219
+ const isDevelopment = isDevMode();
220
+ const p = getServerFunctionsManifestPath();
221
+
222
+ if (isDevelopment) {
223
+ if (fs.existsSync(p)) {
224
+ try {
225
+ const raw = JSON.parse(fs.readFileSync(p, "utf8"));
226
+ const parsed = {};
227
+ for (const key in raw) {
228
+ parsed[key] = new Set(raw[key]);
229
+ }
230
+ return parsed;
231
+ } catch (e) {}
232
+ }
233
+ return null;
234
+ }
235
+
236
+ if (!cachedServerFunctionsManifest && fs.existsSync(p)) {
237
+ try {
238
+ const raw = JSON.parse(fs.readFileSync(p, "utf8"));
239
+ cachedServerFunctionsManifest = {};
240
+ for (const key in raw) {
241
+ cachedServerFunctionsManifest[key] = new Set(raw[key]);
242
+ }
243
+ } catch (e) {}
244
+ }
245
+ return cachedServerFunctionsManifest;
246
+ }
247
+
248
+ function setServerFunctionsManifest(manifest) {
249
+ cachedServerFunctionsManifest = manifest;
250
+ if (typeof globalThis !== "undefined") {
251
+ globalThis.__DINOU_SERVER_FUNCTIONS_MANIFEST__ = manifest;
252
+ }
253
+ }
254
+
255
+ module.exports = {
256
+ isManifestReady,
257
+ getClientManifest,
258
+ setClientManifest,
259
+ getServerFunctionsManifest,
260
+ setServerFunctionsManifest,
261
+ };
@@ -26,6 +26,10 @@ export function isExternalUrl(href) {
26
26
  }
27
27
 
28
28
  export function resolveUrl(href, currentPathname) {
29
+ if (!href) {
30
+ return "";
31
+ }
32
+
29
33
  if (isExternalUrl(href)) {
30
34
  return href;
31
35
  }
@@ -62,7 +62,7 @@ export function useRouter() {
62
62
  replace: () => { },
63
63
  back: () => { },
64
64
  forward: () => { },
65
- refresh: () => { },
65
+ refresh: (options) => { },
66
66
  };
67
67
  }
68
68
 
@@ -86,29 +86,42 @@ export function useRouter() {
86
86
  * Refresh the current route.
87
87
  * Makes a new request to the server for the current URL, clearing the cache,
88
88
  * and re-renders the server component without a full browser reload.
89
+ * Pass `{ layout: true }` to also invalidate and re-render the layout.
89
90
  */
90
- refresh: () => context.refresh(),
91
+ refresh: (options) => context.refresh(options),
92
+
93
+ /**
94
+ * Refresh a specific DinouCacheSlot without re-rendering the rest of the page.
95
+ * @param {string} slotId The ID or tag of the slot to refresh.
96
+ * @param {object} [options] Optional configuration ({ fresh?: boolean }).
97
+ */
98
+ refreshSlot: (slotId, options) => refreshSlot(slotId, options),
91
99
  };
92
100
  }
93
101
 
102
+ export function refreshSlot(slotId, options) {
103
+ if (typeof window !== "undefined") {
104
+ if (typeof window.__DINOU_REFRESH_SLOT__ === "function") {
105
+ window.__DINOU_REFRESH_SLOT__(slotId, options);
106
+ } else {
107
+ window.dispatchEvent(
108
+ new CustomEvent("dinou:refresh-slot", { detail: { id: slotId, options } })
109
+ );
110
+ }
111
+ }
112
+ }
113
+
114
+ const DINOU_CONTEXT_KEY = Symbol.for("dinou.request.context.storage");
115
+
94
116
  export function usePathname() {
95
117
  // 🟢 1. SERVER LOGIC (SSR)
96
118
  if (typeof window === "undefined") {
97
119
  try {
98
- const dynamicRequire =
99
- typeof __dinou_require__ !== "undefined"
100
- ? __dinou_require__
101
- : typeof module !== "undefined" && typeof module.require === "function"
102
- ? module.require.bind(module)
103
- : null;
104
- if (dynamicRequire) {
105
- const { getContext } = dynamicRequire(
106
- /* webpackIgnore: true */ "./request-context.js"
107
- );
108
- const ctx = getContext();
109
- if (ctx && ctx.req) {
110
- return normalizePath(ctx.req.path);
111
- }
120
+ const storage = globalThis[DINOU_CONTEXT_KEY];
121
+ const ctx = (storage && typeof storage.getStore === "function" ? storage.getStore() : null)
122
+ || globalThis[Symbol.for("dinou.request.context.current")];
123
+ if (ctx && ctx.req) {
124
+ return normalizePath(ctx.req.path);
112
125
  }
113
126
  } catch (e) {
114
127
  console.log("error getContext usePathname", e);
@@ -134,37 +147,35 @@ export function useSearchParams() {
134
147
  // 🟢 1. SERVER LOGIC
135
148
  if (typeof window === "undefined") {
136
149
  try {
137
- const dynamicRequire =
138
- typeof __dinou_require__ !== "undefined"
139
- ? __dinou_require__
140
- : typeof module !== "undefined" && typeof module.require === "function"
141
- ? module.require.bind(module)
142
- : null;
143
- if (dynamicRequire) {
144
- const { getContext } = dynamicRequire(
145
- /* webpackIgnore: true */ "./request-context.js"
146
- );
147
- const ctx = getContext();
148
- if (ctx && ctx.req && ctx.req.query) {
149
- const params = new URLSearchParams();
150
- Object.entries(ctx.req.query).forEach(([key, val]) => {
151
- if (Array.isArray(val)) val.forEach((v) => params.append(key, v));
152
- else if (val) params.append(key, val);
153
- });
154
- return params;
155
- }
150
+ const storage = globalThis[DINOU_CONTEXT_KEY];
151
+ const ctx = storage && typeof storage.getStore === "function" ? storage.getStore() : null;
152
+ if (ctx && ctx.req && ctx.req.query) {
153
+ const params = new URLSearchParams();
154
+ Object.entries(ctx.req.query).forEach(([key, val]) => {
155
+ if (Array.isArray(val)) val.forEach((v) => params.append(key, v));
156
+ else if (val) params.append(key, val);
157
+ });
158
+ return params;
156
159
  }
157
160
  } catch (e) { }
161
+ return new URLSearchParams();
158
162
  }
159
163
 
160
164
  // 🔵 2. CLIENT LOGIC
161
165
  const context = useContext(RouterContext);
162
166
 
163
167
  // ⚠️ CRITICAL CHANGE: We extract .url
164
- const fullRoute = typeof context === "string" ? context : context.url;
168
+ const fullRoute = typeof context === "string" ? context : context?.url;
169
+
170
+ if (typeof fullRoute === "string" && fullRoute.includes("?")) {
171
+ const searchPart = (fullRoute.split("?")[1] || "").split("#")[0];
172
+ return new URLSearchParams(searchPart);
173
+ }
165
174
 
166
- if (typeof fullRoute !== "string") return new URLSearchParams();
175
+ if (typeof window !== "undefined" && window.location && window.location.search) {
176
+ return new URLSearchParams(window.location.search);
177
+ }
167
178
 
168
- const searchPart = (fullRoute.split("?")[1] || "").split("#")[0];
169
- return new URLSearchParams(searchPart);
179
+ return new URLSearchParams();
170
180
  }
181
+
@@ -1,15 +1,21 @@
1
+ let swc = null;
2
+ try {
3
+ swc = require("@swc/core");
4
+ } catch (e) {}
5
+
1
6
  const parser = require("@babel/parser");
2
7
  const traverse = require("@babel/traverse");
3
8
 
4
- function parseExports(code) {
9
+ function parseExportsWithBabel(code) {
5
10
  const ast = parser.parse(code, {
6
11
  sourceType: "module",
7
12
  plugins: ["jsx", "typescript"],
8
13
  });
9
14
 
10
15
  const exports = new Set();
16
+ const traverseFn = typeof traverse === "function" ? traverse : (traverse.default || traverse);
11
17
 
12
- traverse.default(ast, {
18
+ traverseFn(ast, {
13
19
  ExportDefaultDeclaration() {
14
20
  exports.add("default");
15
21
  },
@@ -40,4 +46,203 @@ function parseExports(code) {
40
46
  return [...exports];
41
47
  }
42
48
 
49
+ function parseExports(code) {
50
+ if (swc && typeof swc.parseSync === "function") {
51
+ try {
52
+ const ast = swc.parseSync(code, { syntax: "typescript", tsx: true });
53
+ const exports = new Set();
54
+ for (const item of ast.body) {
55
+ if (item.type === "ExportDefaultDeclaration" || item.type === "ExportDefaultExpression") {
56
+ exports.add("default");
57
+ } else if (item.type === "ExportDeclaration") {
58
+ const d = item.declaration;
59
+ if (!d) continue;
60
+ if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
61
+ if (d.identifier?.value) exports.add(d.identifier.value);
62
+ } else if (d.type === "VariableDeclaration") {
63
+ for (const v of d.declarations) {
64
+ if (v.id.type === "Identifier") exports.add(v.id.value);
65
+ }
66
+ }
67
+ } else if (item.type === "ExportNamedDeclaration") {
68
+ const d = item.declaration;
69
+ if (d) {
70
+ if (d.type === "FunctionDeclaration" || d.type === "ClassDeclaration") {
71
+ if (d.identifier?.value) exports.add(d.identifier.value);
72
+ } else if (d.type === "VariableDeclaration") {
73
+ for (const v of d.declarations) {
74
+ if (v.id.type === "Identifier") exports.add(v.id.value);
75
+ }
76
+ }
77
+ }
78
+ if (item.specifiers) {
79
+ for (const s of item.specifiers) {
80
+ const name = s.exported?.value || s.orig?.value;
81
+ if (name) exports.add(name);
82
+ }
83
+ }
84
+ }
85
+ }
86
+ return [...exports];
87
+ } catch (e) {
88
+ // Fallback to Babel
89
+ }
90
+ }
91
+
92
+ return parseExportsWithBabel(code);
93
+ }
94
+
95
+ function parsePprConfigWithBabel(code) {
96
+ try {
97
+ const ast = parser.parse(code, {
98
+ sourceType: "module",
99
+ plugins: ["jsx", "typescript"],
100
+ });
101
+
102
+ let pprValue = null;
103
+ const traverseFn = typeof traverse === "function" ? traverse : (traverse.default || traverse);
104
+
105
+ traverseFn(ast, {
106
+ ExportNamedDeclaration(p) {
107
+ const decl = p.node.declaration;
108
+ if (!decl) return;
109
+
110
+ if (decl.type === "FunctionDeclaration") {
111
+ if (decl.id && decl.id.name === "ppr") {
112
+ for (const s of decl.body?.body || []) {
113
+ if (s.type === "ReturnStatement" && s.argument) {
114
+ if (s.argument.type === "BooleanLiteral") pprValue = s.argument.value;
115
+ else if (s.argument.type === "StringLiteral") pprValue = s.argument.value !== "false";
116
+ else if (s.argument.type === "Identifier") pprValue = s.argument.name === "true";
117
+ }
118
+ }
119
+ if (pprValue === null) pprValue = true;
120
+ }
121
+ } else if (decl.type === "VariableDeclaration") {
122
+ for (const d of decl.declarations) {
123
+ if (d.id && d.id.type === "Identifier") {
124
+ if (d.id.name === "ppr") {
125
+ if (d.init) {
126
+ if (d.init.type === "BooleanLiteral") {
127
+ pprValue = d.init.value;
128
+ } else if (d.init.type === "StringLiteral") {
129
+ pprValue = d.init.value !== "false";
130
+ } else if (d.init.type === "Identifier") {
131
+ pprValue = d.init.name === "true";
132
+ } else if (d.init.type === "ArrowFunctionExpression" || d.init.type === "FunctionExpression") {
133
+ if (d.init.body.type === "BooleanLiteral") {
134
+ pprValue = d.init.body.value;
135
+ } else if (d.init.body.type === "BlockStatement") {
136
+ for (const s of d.init.body.body || []) {
137
+ if (s.type === "ReturnStatement" && s.argument) {
138
+ if (s.argument.type === "BooleanLiteral") pprValue = s.argument.value;
139
+ else if (s.argument.type === "StringLiteral") pprValue = s.argument.value !== "false";
140
+ else if (s.argument.type === "Identifier") pprValue = s.argument.name === "true";
141
+ }
142
+ }
143
+ }
144
+ if (pprValue === null) pprValue = true;
145
+ } else {
146
+ pprValue = true;
147
+ }
148
+ } else {
149
+ pprValue = true;
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ },
156
+ });
157
+
158
+ return pprValue;
159
+ } catch (e) {
160
+ // Regex fallback
161
+ const matchConst = code.match(/(?:export\s+const|export\s+let|export\s+var)\s+ppr\s*=\s*(true|false|"[^"]*"|'[^']*')/);
162
+ if (matchConst) {
163
+ const val = matchConst[1].trim();
164
+ return val !== "false" && val !== '"false"' && val !== "'false'";
165
+ }
166
+ const matchFunc = code.match(/(?:export\s+(?:async\s+)?function\s+ppr\s*\([^)]*\)\s*\{[\s\S]*?return\s+(true|false))/);
167
+ if (matchFunc) {
168
+ return matchFunc[1] === "true";
169
+ }
170
+ const matchArrow = code.match(/(?:export\s+const|export\s+let|export\s+var)\s+ppr\s*=\s*(?:async\s*)?(?:\([^)]*\)|[a-zA-Z_$][a-zA-Z0-9_$]*)\s*=>\s*(?:\{[\s\S]*?return\s+(true|false)|(true|false))/);
171
+ if (matchArrow) {
172
+ const val = matchArrow[1] || matchArrow[2];
173
+ return val === "true";
174
+ }
175
+ return null;
176
+ }
177
+ }
178
+
179
+ function parsePprConfig(code) {
180
+ if (!code || typeof code !== "string") return null;
181
+ if (!code.includes("ppr")) return null;
182
+
183
+ if (swc && typeof swc.parseSync === "function") {
184
+ try {
185
+ const ast = swc.parseSync(code, { syntax: "typescript", tsx: true });
186
+ for (const item of ast.body) {
187
+ if (item.type === "ExportDeclaration" || item.type === "ExportNamedDeclaration") {
188
+ const d = item.declaration;
189
+ if (!d) continue;
190
+
191
+ if (d.type === "FunctionDeclaration") {
192
+ const name = d.identifier?.value || d.identifier?.name;
193
+ if (name === "ppr") {
194
+ for (const stmt of d.body?.stmts || []) {
195
+ if (stmt.type === "ReturnStatement" && stmt.argument) {
196
+ if (stmt.argument.type === "BooleanLiteral") return Boolean(stmt.argument.value);
197
+ if (stmt.argument.type === "StringLiteral") return stmt.argument.value !== "false";
198
+ if (stmt.argument.type === "Identifier") return stmt.argument.value === "true";
199
+ }
200
+ }
201
+ return true;
202
+ }
203
+ } else if (d.type === "VariableDeclaration") {
204
+ for (const v of d.declarations) {
205
+ const name = v.id?.value || v.id?.name;
206
+ if (name === "ppr") {
207
+ if (v.init) {
208
+ if (v.init.type === "BooleanLiteral") return Boolean(v.init.value);
209
+ if (v.init.type === "StringLiteral") return v.init.value !== "false";
210
+ if (v.init.type === "Identifier") return v.init.value === "true";
211
+ if (v.init.type === "ArrowFunctionExpression" || v.init.type === "FunctionExpression") {
212
+ if (v.init.body.type === "BooleanLiteral") return Boolean(v.init.body.value);
213
+ if (v.init.body.type === "BlockStatement") {
214
+ for (const s of v.init.body.stmts || []) {
215
+ if (s.type === "ReturnStatement" && s.argument) {
216
+ if (s.argument.type === "BooleanLiteral") return Boolean(s.argument.value);
217
+ if (s.argument.type === "StringLiteral") return s.argument.value !== "false";
218
+ if (s.argument.type === "Identifier") return s.argument.value === "true";
219
+ }
220
+ }
221
+ }
222
+ return true;
223
+ }
224
+ return true;
225
+ }
226
+ return true;
227
+ }
228
+ }
229
+ }
230
+ }
231
+ }
232
+ return null;
233
+ } catch (e) {
234
+ // Fallback to Babel
235
+ }
236
+ }
237
+
238
+ return parsePprConfigWithBabel(code);
239
+ }
240
+
241
+ const { resolveModulePpr } = require("./resolve-module-ppr");
242
+
243
+ parseExports.parsePprConfig = parsePprConfig;
244
+ parseExports.hasPpr = (code) => parsePprConfig(code) === true;
245
+ parseExports.resolveModulePpr = resolveModulePpr;
246
+
43
247
  module.exports = parseExports;
248
+