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.
- package/CHANGELOG.md +106 -0
- package/README.md +9352 -1081
- package/cli.js +314 -91
- package/dinou/adapters/bun.js +62 -0
- package/dinou/adapters/cloudflare.js +65 -0
- package/dinou/adapters/deno.js +48 -0
- package/dinou/adapters/netlify.js +85 -0
- package/dinou/adapters/node.mjs +31 -0
- package/dinou/bun/build.mjs +1077 -0
- package/dinou/cloudflare/build.mjs +1121 -0
- package/dinou/cloudflare/shims/child_process.js +14 -0
- package/dinou/cloudflare/shims/empty.js +2 -0
- package/dinou/cloudflare/shims/fs.js +99 -0
- package/dinou/cloudflare/shims/os.js +29 -0
- package/dinou/config.js +1 -0
- package/dinou/config.mjs +2 -0
- package/dinou/constants.js +29 -4
- package/dinou/core/babel-esm-loader.js +66 -37
- package/dinou/core/bailout-proxy.js +61 -0
- package/dinou/core/build-static-pages.js +322 -165
- package/dinou/core/cache-revalidate.js +471 -144
- package/dinou/core/cache-slot.js +387 -0
- package/dinou/core/client-redirect.jsx +12 -7
- package/dinou/core/client-webpack.jsx +457 -82
- package/dinou/core/client.jsx +452 -82
- package/dinou/core/config.js +11 -0
- package/dinou/core/dinou-paths.js +52 -0
- package/dinou/core/edge-ssr.js +122 -0
- package/dinou/core/export-static.mjs +64 -0
- package/dinou/core/generate-route-types.js +252 -0
- package/dinou/core/generate-static-page.js +55 -94
- package/dinou/core/generate-static-rsc.js +47 -15
- package/dinou/core/generate-static.js +212 -10
- package/dinou/core/generating-isg.js +5 -0
- package/dinou/core/get-asset-from-manifest.js +9 -3
- package/dinou/core/get-error-jsx.js +221 -41
- package/dinou/core/get-file-path-and-dynamic-params.js +9 -13
- package/dinou/core/get-jsx.js +175 -96
- package/dinou/core/handler.js +2303 -0
- package/dinou/core/http-adapter.js +115 -0
- package/dinou/core/import-module.js +83 -53
- package/dinou/core/layout-functions.js +183 -0
- package/dinou/core/link.jsx +18 -6
- package/dinou/core/load-dinou-config.js +60 -0
- package/dinou/core/manifest-provider.js +261 -0
- package/dinou/core/navigation-utils.js +4 -0
- package/dinou/core/navigation.js +50 -39
- package/dinou/core/parse-exports.js +252 -2
- package/dinou/core/ppr-context.js +105 -0
- package/dinou/core/ppr-runtime.js +263 -0
- package/dinou/core/redirect.jsx +20 -19
- package/dinou/core/render-jsx-to-client-jsx.js +91 -87
- package/dinou/core/request-context.js +47 -13
- package/dinou/core/resolve-module-ppr.js +34 -0
- package/dinou/core/revalidating.js +28 -9
- package/dinou/core/route-generator.js +107 -0
- package/dinou/core/rsc-renderer.js +90 -0
- package/dinou/core/run-ssg.js +19 -0
- package/dinou/core/scan-dependency-components.js +218 -0
- package/dinou/core/server-function-proxy-webpack.js +3 -0
- package/dinou/core/server-function-proxy.js +3 -0
- package/dinou/core/slot.js +302 -0
- package/dinou/core/status-manifest.js +41 -1
- package/dinou/core/storage-adapter.js +522 -0
- package/dinou/core/url-resolver.js +16 -16
- package/dinou/core/vfs.js +139 -68
- package/dinou/deno/build.mjs +1112 -0
- package/dinou/deno/seed-kv.js +115 -0
- package/dinou/esbuild/build.mjs +51 -1
- package/dinou/esbuild/dev.mjs +290 -224
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild-prod.mjs +3 -2
- package/dinou/esbuild/helpers-esbuild/get-config-esbuild.mjs +104 -16
- package/dinou/esbuild/helpers-esbuild/get-esbuild-entries.mjs +31 -19
- package/dinou/esbuild/helpers-esbuild/strip-namespace.mjs +9 -0
- package/dinou/esbuild/helpers-esbuild/swc-disk-cache.mjs +225 -0
- package/dinou/esbuild/helpers-esbuild/update-manifest-for-module.mjs +7 -0
- package/dinou/esbuild/helpers-esbuild/write.mjs +111 -2
- package/dinou/esbuild/plugins-esbuild/assets-plugin.mjs +236 -161
- package/dinou/esbuild/plugins-esbuild/css-processor-plugin.mjs +101 -5
- package/dinou/esbuild/plugins-esbuild/react-client-manifest-plugin.mjs +63 -24
- package/dinou/esbuild/plugins-esbuild/server-functions-plugin.mjs +177 -56
- package/dinou/esbuild/plugins-esbuild/skip-missing-entry-points-plugin.mjs +3 -0
- package/dinou/esbuild/plugins-esbuild/stable-chunk-names-and-maps-plugin.mjs +182 -137
- package/dinou/esbuild/plugins-postcss/postcss-extract-plugin.js +38 -11
- package/dinou/esbuild/react-refresh/esm-hmr/client.mjs +55 -8
- package/dinou/esbuild/react-refresh/esm-hmr/server.js +1 -1
- package/dinou/esbuild/react-refresh/esm-hmr-plugin.mjs +238 -101
- package/dinou/esbuild/react-refresh/is-react-refresh-boundary.mjs +18 -4
- package/dinou/index.d.ts +315 -11
- package/dinou/index.js +12 -6
- package/dinou/index.mjs +9 -0
- package/dinou/node/build.mjs +195 -0
- package/dinou/node/bundle-dual-engine.mjs +1012 -0
- package/dinou/node/dev.mjs +2589 -0
- package/dinou/node/port-selector.mjs +164 -0
- package/dinou/node/terminal-status.mjs +345 -0
- package/dinou/package.json +16 -14
- package/dinou/rollup/react-refresh/esm-hmr/client.js +66 -10
- package/dinou/rollup/react-refresh/esm-hmr/server.js +1 -1
- package/dinou/rollup/react-refresh/is-react-refresh-boundary.js +24 -5
- package/dinou/rollup/react-refresh/react-refresh-runtime.js +13 -6
- package/dinou/rollup/react-refresh/react-refresh-wrap-modules.js +56 -11
- package/dinou/rollup/react-refresh/rollup-plugin-esm-hmr.js +176 -48
- package/dinou/rollup/rollup-plugins/dinou-asset-plugin.js +9 -5
- package/dinou/rollup/rollup-plugins/rollup-plugin-memory.js +66 -0
- package/dinou/rollup/rollup-plugins/rollup-plugin-react-client-manifest.js +468 -123
- package/dinou/rollup/rollup-plugins/rollup-plugin-server-functions.js +44 -12
- package/dinou/rollup/rollup-plugins/rollup-plugin-swc.js +100 -0
- package/dinou/rollup/rollup.config.js +155 -43
- package/dinou/server.d.ts +114 -12
- package/dinou/server.js +35 -10
- package/dinou/server.mjs +30 -9
- package/dinou/webpack/helpers/get-webpack-entries.js +14 -19
- package/dinou/webpack/loaders/server-functions-loader.js +22 -1
- package/dinou/webpack/loaders/swc-loader.js +76 -0
- package/dinou/webpack/plugins/manifest-generator-plugin.js +1 -0
- package/dinou/webpack/plugins/server-functions-plugin.js +75 -19
- package/dinou/webpack/plugins/webpack-memory-plugin.js +66 -0
- package/dinou/webpack/webpack.config.js +227 -29
- package/eject.js +113 -34
- package/package.json +18 -16
- package/dinou/core/asset-require-hook.js +0 -58
- package/dinou/core/client-error-webpack.jsx +0 -432
- package/dinou/core/client-error.jsx +0 -432
- package/dinou/core/concurrency-manager.js +0 -48
- package/dinou/core/context-proxy.js +0 -68
- package/dinou/core/generate-static-pages.js +0 -130
- package/dinou/core/generate-static-rscs.js +0 -151
- package/dinou/core/get-ssg-metadata.js +0 -31
- package/dinou/core/register-loader.mjs +0 -11
- package/dinou/core/register-paths.js +0 -27
- package/dinou/core/render-app-to-html.js +0 -430
- package/dinou/core/render-html.js +0 -407
- package/dinou/core/server.js +0 -1542
- 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
|
+
};
|
package/dinou/core/navigation.js
CHANGED
|
@@ -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
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
|
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
|
|
175
|
+
if (typeof window !== "undefined" && window.location && window.location.search) {
|
|
176
|
+
return new URLSearchParams(window.location.search);
|
|
177
|
+
}
|
|
167
178
|
|
|
168
|
-
|
|
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
|
|
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
|
-
|
|
18
|
+
traverseFn(ast, {
|
|
13
19
|
ExportDefaultDeclaration() {
|
|
14
20
|
exports.add("default");
|
|
15
21
|
},
|
|
@@ -40,4 +46,248 @@ 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
|
+
ExportDefaultDeclaration(p) {
|
|
157
|
+
function checkObject(objNode) {
|
|
158
|
+
if (!objNode || objNode.type !== "ObjectExpression") return;
|
|
159
|
+
for (const prop of objNode.properties || []) {
|
|
160
|
+
const key = prop.key?.name || prop.key?.value;
|
|
161
|
+
if (key === "ppr") {
|
|
162
|
+
const val = prop.value;
|
|
163
|
+
if (val?.type === "BooleanLiteral") pprValue = val.value;
|
|
164
|
+
else if (val?.type === "StringLiteral") pprValue = val.value !== "false";
|
|
165
|
+
else if (val?.type === "Identifier") pprValue = val.name === "true";
|
|
166
|
+
else if (val?.type === "ArrowFunctionExpression" || val?.type === "FunctionExpression") {
|
|
167
|
+
if (val.body?.type === "BooleanLiteral") pprValue = val.body.value;
|
|
168
|
+
else if (val.body?.type === "BlockStatement") {
|
|
169
|
+
for (const s of val.body.body || []) {
|
|
170
|
+
if (s.type === "ReturnStatement" && s.argument) {
|
|
171
|
+
if (s.argument.type === "BooleanLiteral") pprValue = s.argument.value;
|
|
172
|
+
else if (s.argument.type === "StringLiteral") pprValue = s.argument.value !== "false";
|
|
173
|
+
else if (s.argument.type === "Identifier") pprValue = s.argument.name === "true";
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (pprValue === null) pprValue = true;
|
|
178
|
+
} else {
|
|
179
|
+
pprValue = true;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const decl = p.node.declaration;
|
|
186
|
+
if (!decl) return;
|
|
187
|
+
if (decl.type === "ObjectExpression") {
|
|
188
|
+
checkObject(decl);
|
|
189
|
+
} else if (decl.type === "Identifier") {
|
|
190
|
+
const binding = p.scope?.getBinding(decl.name);
|
|
191
|
+
if (binding && binding.path?.node?.init?.type === "ObjectExpression") {
|
|
192
|
+
checkObject(binding.path.node.init);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
return pprValue;
|
|
199
|
+
} catch (e) {
|
|
200
|
+
// Regex fallback
|
|
201
|
+
const matchConst = code.match(/(?:export\s+const|export\s+let|export\s+var)\s+ppr\s*=\s*(true|false|"[^"]*"|'[^']*')/);
|
|
202
|
+
if (matchConst) {
|
|
203
|
+
const val = matchConst[1].trim();
|
|
204
|
+
return val !== "false" && val !== '"false"' && val !== "'false'";
|
|
205
|
+
}
|
|
206
|
+
const matchFunc = code.match(/(?:export\s+(?:async\s+)?function\s+ppr\s*\([^)]*\)\s*\{[\s\S]*?return\s+(true|false))/);
|
|
207
|
+
if (matchFunc) {
|
|
208
|
+
return matchFunc[1] === "true";
|
|
209
|
+
}
|
|
210
|
+
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))/);
|
|
211
|
+
if (matchArrow) {
|
|
212
|
+
const val = matchArrow[1] || matchArrow[2];
|
|
213
|
+
return val === "true";
|
|
214
|
+
}
|
|
215
|
+
const matchProp = code.match(/\bppr\s*:\s*(true|false|"[^"]*"|'[^']*')/);
|
|
216
|
+
if (matchProp) {
|
|
217
|
+
const val = matchProp[1].trim();
|
|
218
|
+
return val !== "false" && val !== '"false"' && val !== "'false'";
|
|
219
|
+
}
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function parsePprConfig(code) {
|
|
225
|
+
if (!code || typeof code !== "string") return null;
|
|
226
|
+
if (!code.includes("ppr")) return null;
|
|
227
|
+
|
|
228
|
+
if (swc && typeof swc.parseSync === "function") {
|
|
229
|
+
try {
|
|
230
|
+
const ast = swc.parseSync(code, { syntax: "typescript", tsx: true });
|
|
231
|
+
for (const item of ast.body) {
|
|
232
|
+
if (item.type === "ExportDeclaration" || item.type === "ExportNamedDeclaration") {
|
|
233
|
+
const d = item.declaration;
|
|
234
|
+
if (!d) continue;
|
|
235
|
+
|
|
236
|
+
if (d.type === "FunctionDeclaration") {
|
|
237
|
+
const name = d.identifier?.value || d.identifier?.name;
|
|
238
|
+
if (name === "ppr") {
|
|
239
|
+
for (const stmt of d.body?.stmts || []) {
|
|
240
|
+
if (stmt.type === "ReturnStatement" && stmt.argument) {
|
|
241
|
+
if (stmt.argument.type === "BooleanLiteral") return Boolean(stmt.argument.value);
|
|
242
|
+
if (stmt.argument.type === "StringLiteral") return stmt.argument.value !== "false";
|
|
243
|
+
if (stmt.argument.type === "Identifier") return stmt.argument.value === "true";
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
return true;
|
|
247
|
+
}
|
|
248
|
+
} else if (d.type === "VariableDeclaration") {
|
|
249
|
+
for (const v of d.declarations) {
|
|
250
|
+
const name = v.id?.value || v.id?.name;
|
|
251
|
+
if (name === "ppr") {
|
|
252
|
+
if (v.init) {
|
|
253
|
+
if (v.init.type === "BooleanLiteral") return Boolean(v.init.value);
|
|
254
|
+
if (v.init.type === "StringLiteral") return v.init.value !== "false";
|
|
255
|
+
if (v.init.type === "Identifier") return v.init.value === "true";
|
|
256
|
+
if (v.init.type === "ArrowFunctionExpression" || v.init.type === "FunctionExpression") {
|
|
257
|
+
if (v.init.body.type === "BooleanLiteral") return Boolean(v.init.body.value);
|
|
258
|
+
if (v.init.body.type === "BlockStatement") {
|
|
259
|
+
for (const s of v.init.body.stmts || []) {
|
|
260
|
+
if (s.type === "ReturnStatement" && s.argument) {
|
|
261
|
+
if (s.argument.type === "BooleanLiteral") return Boolean(s.argument.value);
|
|
262
|
+
if (s.argument.type === "StringLiteral") return s.argument.value !== "false";
|
|
263
|
+
if (s.argument.type === "Identifier") return s.argument.value === "true";
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return true;
|
|
268
|
+
}
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
return true;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// If SWC didn't find named ppr, fall through to Babel for default export & scope analysis
|
|
278
|
+
} catch (e) {
|
|
279
|
+
// Fallback to Babel
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
return parsePprConfigWithBabel(code);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const { resolveModulePpr } = require("./resolve-module-ppr");
|
|
287
|
+
|
|
288
|
+
parseExports.parsePprConfig = parsePprConfig;
|
|
289
|
+
parseExports.hasPpr = (code) => parsePprConfig(code) === true;
|
|
290
|
+
parseExports.resolveModulePpr = resolveModulePpr;
|
|
291
|
+
|
|
43
292
|
module.exports = parseExports;
|
|
293
|
+
|