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,14 @@
1
+ // dinou/cloudflare/shims/child_process.js
2
+ export const fork = () => {
3
+ return {
4
+ on: () => {},
5
+ stdout: { on: () => {} },
6
+ stderr: { on: () => {} },
7
+ stdio: [null, null, null, null, { write: () => {}, end: () => {} }],
8
+ kill: () => {},
9
+ };
10
+ };
11
+ export const spawn = () => ({ on: () => {} });
12
+ export const exec = () => {};
13
+ export const execSync = () => "";
14
+ export default { fork, spawn, exec, execSync };
@@ -0,0 +1,2 @@
1
+ // dinou/cloudflare/shims/empty.js
2
+ export default {};
@@ -0,0 +1,99 @@
1
+ // dinou/cloudflare/shims/fs.js
2
+ function getVfs() {
3
+ return (typeof globalThis !== "undefined" && globalThis.__DINOU_VFS__) || {};
4
+ }
5
+
6
+ function lookupVfs(vfs, p) {
7
+ if (!vfs || !p) return null;
8
+ if (vfs[p]) return vfs[p];
9
+
10
+ const s = String(p).split("\\").join("/");
11
+ if (vfs[s]) return vfs[s];
12
+
13
+ if (s.length > 2 && s[1] === ":") {
14
+ const noDrive = s.slice(2);
15
+ if (vfs[noDrive]) return vfs[noDrive];
16
+ }
17
+
18
+ const idx = s.indexOf("/src");
19
+ if (idx !== -1) {
20
+ const fromSlash = s.slice(idx);
21
+ if (vfs[fromSlash]) return vfs[fromSlash];
22
+ const noSlash = fromSlash.slice(1);
23
+ if (vfs[noSlash]) return vfs[noSlash];
24
+ } else if (s.startsWith("src/") || s === "src") {
25
+ if (vfs[s]) return vfs[s];
26
+ if (vfs["/" + s]) return vfs["/" + s];
27
+ }
28
+
29
+ const trimmed = s.replace(/^\/+/, "");
30
+ if (vfs[trimmed]) return vfs[trimmed];
31
+ if (vfs["/" + trimmed]) return vfs["/" + trimmed];
32
+
33
+ return null;
34
+ }
35
+
36
+ export const existsSync = (p) => {
37
+ const vfs = getVfs();
38
+ return lookupVfs(vfs, p) !== null;
39
+ };
40
+
41
+ export const readFileSync = (p) => {
42
+ const vfs = getVfs();
43
+ const entry = lookupVfs(vfs, p);
44
+ if (entry && typeof entry.content === "string") {
45
+ return entry.content;
46
+ }
47
+ return "";
48
+ };
49
+
50
+ export const readdirSync = (p, options) => {
51
+ const vfs = getVfs();
52
+ const entry = lookupVfs(vfs, p);
53
+ if (!entry || entry.type !== "directory" || !Array.isArray(entry.children)) {
54
+ return [];
55
+ }
56
+ if (options && options.withFileTypes) {
57
+ return entry.children.map((c) => ({
58
+ name: c.name,
59
+ isDirectory: () => !!c.isDirectory,
60
+ isFile: () => !c.isDirectory,
61
+ }));
62
+ }
63
+ return entry.children.map((c) => c.name);
64
+ };
65
+
66
+ export const statSync = (p) => {
67
+ const vfs = getVfs();
68
+ const entry = lookupVfs(vfs, p);
69
+ const isDir = entry && entry.type === "directory";
70
+ const isF = entry && entry.type === "file";
71
+ return {
72
+ isDirectory: () => !!isDir,
73
+ isFile: () => !!isF,
74
+ };
75
+ };
76
+
77
+ export const mkdirSync = () => {};
78
+ export const writeFileSync = () => {};
79
+ export const rmSync = () => {};
80
+
81
+ export const promises = {
82
+ readFile: async (p) => readFileSync(p),
83
+ writeFile: async () => {},
84
+ readdir: async (p, opts) => readdirSync(p, opts),
85
+ stat: async (p) => statSync(p),
86
+ mkdir: async () => {},
87
+ rm: async () => {},
88
+ };
89
+
90
+ export default {
91
+ existsSync,
92
+ readFileSync,
93
+ readdirSync,
94
+ statSync,
95
+ mkdirSync,
96
+ writeFileSync,
97
+ rmSync,
98
+ promises,
99
+ };
@@ -0,0 +1,29 @@
1
+ // dinou/cloudflare/shims/os.js
2
+ export const cpus = () => [{ model: "Cloudflare Workers Edge vCPU", speed: 2000 }];
3
+ export const freemem = () => 128 * 1024 * 1024;
4
+ export const totalmem = () => 128 * 1024 * 1024;
5
+ export const platform = () => "workerd";
6
+ export const arch = () => "x64";
7
+ export const homedir = () => "/";
8
+ export const tmpdir = () => "/tmp";
9
+ export const hostname = () => "cloudflare-worker";
10
+ export const type = () => "Linux";
11
+ export const release = () => "edge";
12
+ export const uptime = () => 0;
13
+ export const loadavg = () => [0, 0, 0];
14
+ export const networkInterfaces = () => ({});
15
+ export default {
16
+ cpus,
17
+ freemem,
18
+ totalmem,
19
+ platform,
20
+ arch,
21
+ homedir,
22
+ tmpdir,
23
+ hostname,
24
+ type,
25
+ release,
26
+ uptime,
27
+ loadavg,
28
+ networkInterfaces,
29
+ };
@@ -0,0 +1 @@
1
+ module.exports = require("./core/config.js");
@@ -0,0 +1,2 @@
1
+ export * from "./core/config.js";
2
+ export { default } from "./core/config.js";
@@ -1,7 +1,32 @@
1
- const useClientRegex =
2
- /^\s*(?:(?:\/\/[^\n]*\n\s*)|(?:\/\*[\s\S]*?\*\/\s*))*['"]use client['"]/;
1
+ function hasDirective(code, directive) {
2
+ if (typeof code !== "string" || !code.includes(directive)) return false;
3
+ const header = code
4
+ .slice(0, 2000)
5
+ .replace(/\/\/[^\r\n]*/g, "")
6
+ .replace(/\/\*[\s\S]*?\*\//g, "")
7
+ .trim();
8
+ return (
9
+ header.startsWith(`"${directive}"`) ||
10
+ header.startsWith(`'${directive}'`)
11
+ );
12
+ }
3
13
 
4
- const useServerRegex =
5
- /^\s*(?:(?:\/\/[^\n]*\n\s*)|(?:\/\*[\s\S]*?\*\/\s*))*['"]use server['"]/;
14
+ const useClientRegex = {
15
+ test(code) {
16
+ return hasDirective(code, "use client");
17
+ },
18
+ [Symbol.match](str) {
19
+ return this.test(str) ? [str] : null;
20
+ },
21
+ };
22
+
23
+ const useServerRegex = {
24
+ test(code) {
25
+ return hasDirective(code, "use server");
26
+ },
27
+ [Symbol.match](str) {
28
+ return this.test(str) ? [str] : null;
29
+ },
30
+ };
6
31
 
7
32
  module.exports = { useClientRegex, useServerRegex };
@@ -14,27 +14,38 @@ const isWebpack = process.env.DINOU_BUILD_TOOL === "webpack";
14
14
 
15
15
  let reactServerPath, reactDomServerPath, reactJsxRuntimePath, reactJsxDevRuntimePath;
16
16
 
17
- if (!isWebpack) {
18
- const reactPkgJson = require.resolve("react/package.json");
19
- reactServerPath = path.join(path.dirname(reactPkgJson), "react.react-server.js");
20
- reactJsxRuntimePath = path.join(path.dirname(reactPkgJson), "jsx-runtime.react-server.js");
21
- reactJsxDevRuntimePath = path.join(path.dirname(reactPkgJson), "jsx-dev-runtime.react-server.js");
22
-
23
- const reactDomPkgJson = require.resolve("react-dom/package.json");
24
- reactDomServerPath = path.join(path.dirname(reactDomPkgJson), "react-dom.react-server.js");
25
- }
17
+ const reactPkgJson = require.resolve("react/package.json");
18
+ reactServerPath = path.join(path.dirname(reactPkgJson), "react.react-server.js");
19
+ reactJsxRuntimePath = path.join(path.dirname(reactPkgJson), "jsx-runtime.react-server.js");
20
+ reactJsxDevRuntimePath = path.join(path.dirname(reactPkgJson), "jsx-dev-runtime.react-server.js");
21
+
22
+ const reactDomPkgJson = require.resolve("react-dom/package.json");
23
+ reactDomServerPath = path.join(path.dirname(reactDomPkgJson), "react-dom.react-server.js");
24
+
25
+ let roggcServerNodePath, webpackServerNodePath;
26
+ try {
27
+ const roggcPkg = require.resolve("@roggc/react-server-dom-esm/package.json");
28
+ roggcServerNodePath = path.join(path.dirname(roggcPkg), "server.node.js");
29
+ } catch (e) {}
30
+
31
+ try {
32
+ const wpPkg = require.resolve("react-server-dom-webpack/package.json");
33
+ webpackServerNodePath = path.join(path.dirname(wpPkg), "server.node.js");
34
+ } catch (e) {}
26
35
 
27
36
  Module._resolveFilename = function (request, parent, isMain, options) {
28
- if (!isWebpack) {
29
- if (request === "react") {
30
- return reactServerPath;
31
- } else if (request === "react-dom") {
32
- return reactDomServerPath;
33
- } else if (request === "react/jsx-runtime") {
34
- return reactJsxRuntimePath;
35
- } else if (request === "react/jsx-dev-runtime") {
36
- return reactJsxDevRuntimePath;
37
- }
37
+ if (request === "react") {
38
+ return reactServerPath;
39
+ } else if (request === "react-dom") {
40
+ return reactDomServerPath;
41
+ } else if (request === "react/jsx-runtime") {
42
+ return reactJsxRuntimePath;
43
+ } else if (request === "react/jsx-dev-runtime") {
44
+ return reactJsxDevRuntimePath;
45
+ } else if (request === "@roggc/react-server-dom-esm/server" && roggcServerNodePath) {
46
+ return roggcServerNodePath;
47
+ } else if (request === "react-server-dom-webpack/server" && webpackServerNodePath) {
48
+ return webpackServerNodePath;
38
49
  }
39
50
  return originalResolveFilename.call(this, request, parent, isMain, options);
40
51
  };
@@ -51,6 +62,27 @@ function getMtimeParam(absPath) {
51
62
  }
52
63
 
53
64
  exports.resolve = async function resolve(specifier, context, defaultResolve) {
65
+ if (process.env.DINOU_PROCESS !== "ssr-html") {
66
+ if (specifier === "react") {
67
+ return { url: pathToFileURL(reactServerPath).href, shortCircuit: true };
68
+ }
69
+ if (specifier === "react/jsx-runtime") {
70
+ return { url: pathToFileURL(reactJsxRuntimePath).href, shortCircuit: true };
71
+ }
72
+ if (specifier === "react/jsx-dev-runtime") {
73
+ return { url: pathToFileURL(reactJsxDevRuntimePath).href, shortCircuit: true };
74
+ }
75
+ if (specifier === "react-dom") {
76
+ return { url: pathToFileURL(reactDomServerPath).href, shortCircuit: true };
77
+ }
78
+ if (specifier === "@roggc/react-server-dom-esm/server" && roggcServerNodePath) {
79
+ return { url: pathToFileURL(roggcServerNodePath).href, shortCircuit: true };
80
+ }
81
+ if (specifier === "react-server-dom-webpack/server" && webpackServerNodePath) {
82
+ return { url: pathToFileURL(webpackServerNodePath).href, shortCircuit: true };
83
+ }
84
+ }
85
+
54
86
  const absPathWithExt = getAbsPathWithExt(specifier, context);
55
87
  if (absPathWithExt) {
56
88
  let url = pathToFileURL(absPathWithExt).href;
@@ -122,20 +154,17 @@ exports.load = async function load(url, context, defaultLoad) {
122
154
  return defaultLoad(url, context, defaultLoad);
123
155
  }
124
156
 
125
- const isReactServer = process.execArgv.some(arg => arg.includes("react-server"));
157
+ const isReactServer = process.env.DINOU_PROCESS !== "ssr-html";
126
158
  if (isReactServer && hasUseClient) {
127
159
  const parseExports = require("./parse-exports.js");
128
160
  const exports = parseExports(source);
129
- let newSrc = "";
130
- if (isWebpack) {
131
- newSrc += 'import { registerClientReference } from "react-server-dom-webpack/server";\n';
132
- } else {
133
- const packageJsonPath = require.resolve("@roggc/react-server-dom-esm/package.json");
134
- const serverNodePath = path.join(path.dirname(packageJsonPath), "server.node.js");
135
- const serverNodeUrl = pathToFileURL(serverNodePath).href;
136
- newSrc += `import pkg from ${JSON.stringify(serverNodeUrl)};\n`;
137
- newSrc += 'const {registerClientReference} = pkg;\n';
138
- }
161
+ const clientPkgPath = isWebpack
162
+ ? require.resolve("react-server-dom-webpack/package.json")
163
+ : require.resolve("@roggc/react-server-dom-esm/package.json");
164
+ const clientServerNodePath = path.join(path.dirname(clientPkgPath), "server.node.js");
165
+ const clientServerNodeUrl = pathToFileURL(clientServerNodePath).href;
166
+ let newSrc = `import pkg from ${JSON.stringify(clientServerNodeUrl)};\n`;
167
+ newSrc += 'const {registerClientReference} = pkg;\n';
139
168
  for (const name of exports) {
140
169
  if (name === 'default') {
141
170
  newSrc += 'export default ';
@@ -180,13 +209,13 @@ exports.load = async function load(url, context, defaultLoad) {
180
209
 
181
210
  let newSrc = code + "\n\n";
182
211
 
183
- if (!isWebpack) {
184
- const packageJsonPath = require.resolve("@roggc/react-server-dom-esm/package.json");
185
- const serverNodePath = path.join(path.dirname(packageJsonPath), "server.node.js");
186
- const serverNodeUrl = pathToFileURL(serverNodePath).href;
187
- newSrc += `import pkgServer from ${JSON.stringify(serverNodeUrl)};\n`;
188
- newSrc += 'const {registerServerReference} = pkgServer;\n';
189
- }
212
+ const serverPkgPath = isWebpack
213
+ ? require.resolve("react-server-dom-webpack/package.json")
214
+ : require.resolve("@roggc/react-server-dom-esm/package.json");
215
+ const serverNodePath = path.join(path.dirname(serverPkgPath), "server.node.js");
216
+ const serverNodeUrl = pathToFileURL(serverNodePath).href;
217
+ newSrc += `import pkgServer from ${JSON.stringify(serverNodeUrl)};\n`;
218
+ newSrc += 'const {registerServerReference} = pkgServer;\n';
190
219
 
191
220
  const relativeFileUrl = "file:///" + rel.replace(/\\/g, "/");
192
221
  for (const name of exports) {
@@ -0,0 +1,61 @@
1
+ const { isPprBuildActive, isInsideSuspense, markDynamicAccess } = require("./ppr-context.js");
2
+
3
+ function triggerBailout(label, onBailout) {
4
+ if (isPprBuildActive() && isInsideSuspense()) {
5
+ markDynamicAccess(label);
6
+ } else if (typeof onBailout === "function") {
7
+ onBailout();
8
+ }
9
+ }
10
+
11
+ /**
12
+ * Creates a transparent proxy that spies on property accesses
13
+ * to detect dynamic usage and trigger a bailout callback.
14
+ *
15
+ * @param {Object} target - The object to proxy (cookies, headers, query...)
16
+ * @param {string} label - Name for logging/debugging
17
+ * @param {Function} onBailout - Callback invoked when property access occurs
18
+ * @returns {Proxy}
19
+ */
20
+ function createBailoutProxy(target, label = "Context", onBailout) {
21
+ const safeTarget = target || {};
22
+
23
+ return new Proxy(safeTarget, {
24
+ get(t, prop, receiver) {
25
+ if (
26
+ typeof prop === "symbol" ||
27
+ prop === "inspect" ||
28
+ prop === "valueOf" ||
29
+ prop === "toString" ||
30
+ prop === "constructor" ||
31
+ prop === "prototype"
32
+ ) {
33
+ return Reflect.get(t, prop, receiver);
34
+ }
35
+
36
+ triggerBailout(label, onBailout);
37
+
38
+ return Reflect.get(t, prop, receiver);
39
+ },
40
+
41
+ ownKeys(t) {
42
+ triggerBailout(label, onBailout);
43
+ return Reflect.ownKeys(t);
44
+ },
45
+
46
+ has(t, prop) {
47
+ if (
48
+ typeof prop !== "symbol" &&
49
+ prop !== "constructor" &&
50
+ prop !== "prototype"
51
+ ) {
52
+ triggerBailout(label, onBailout);
53
+ }
54
+ return Reflect.has(t, prop);
55
+ },
56
+ });
57
+ }
58
+
59
+ module.exports = {
60
+ createBailoutProxy,
61
+ };