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,302 @@
1
+ "use client";
2
+
3
+ import React from "react";
4
+
5
+ const createContext = React.createContext;
6
+ const useContext = React.useContext;
7
+ const useMemo = React.useMemo;
8
+ const useState = React.useState;
9
+ const useEffect = React.useEffect;
10
+ const startTransition = React.startTransition;
11
+ const use = React.use;
12
+ const createElement = React.createElement;
13
+ const Suspense = React.Suspense;
14
+ const Component = typeof React.Component === "function" ? React.Component : class {};
15
+
16
+ export const DinouPageContext =
17
+ typeof globalThis !== "undefined" && globalThis.__DINOU_PAGE_CONTEXT__
18
+ ? globalThis.__DINOU_PAGE_CONTEXT__
19
+ : (typeof createContext === "function"
20
+ ? (typeof globalThis !== "undefined"
21
+ ? (globalThis.__DINOU_PAGE_CONTEXT__ = createContext(null))
22
+ : createContext(null))
23
+ : null);
24
+
25
+ export function cleanErrorStack(stack) {
26
+ if (!stack || typeof stack !== "string") return "";
27
+ const lines = stack.split("\n");
28
+ const filtered = [];
29
+
30
+ for (const line of lines) {
31
+ if (!line.trim().startsWith("at ")) {
32
+ filtered.push(line);
33
+ continue;
34
+ }
35
+
36
+ if (
37
+ line.includes("resolveErrorDev") ||
38
+ line.includes("resolveErrorModel") ||
39
+ line.includes("processFullStringRow") ||
40
+ line.includes("processFullBinaryRow") ||
41
+ line.includes("processBinaryChunk") ||
42
+ line.includes("buildFakeCallStack") ||
43
+ line.includes("createFakeFunction") ||
44
+ line.includes("initializeFakeTask") ||
45
+ line.includes("getRootTask") ||
46
+ line.includes("progress (http") ||
47
+ line.includes("__hmr_client__") ||
48
+ (line.includes("http://") && line.includes("/chunk-"))
49
+ ) {
50
+ continue;
51
+ }
52
+
53
+ if (
54
+ line.includes("node_modules/@roggc/react-server-dom-esm") ||
55
+ line.includes("node_modules/react-dom") ||
56
+ line.includes("node_modules/react/") ||
57
+ line.includes("node:internal") ||
58
+ line.includes("asyncRenderJSXToClientJSX") ||
59
+ line.includes("renderModelDestructive") ||
60
+ line.includes("renderHtmlStream") ||
61
+ line.includes("pipeRSC")
62
+ ) {
63
+ continue;
64
+ }
65
+
66
+ filtered.push(line);
67
+ }
68
+
69
+ return (filtered.length > 0 ? filtered : lines).join("\n").trim();
70
+ }
71
+
72
+ export function DefaultDevError({ error }) {
73
+ const isDev = process.env.NODE_ENV !== "production";
74
+ return createElement(
75
+ "div",
76
+ {
77
+ style: {
78
+ fontFamily: "system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif",
79
+ padding: "32px",
80
+ maxWidth: "960px",
81
+ margin: "40px auto",
82
+ backgroundColor: "#fff1f2",
83
+ border: "1px solid #fecdd3",
84
+ borderRadius: "12px",
85
+ color: "#9f1239",
86
+ boxShadow: "0 10px 25px -5px rgba(0, 0, 0, 0.1)",
87
+ },
88
+ },
89
+ createElement(
90
+ "div",
91
+ { style: { display: "flex", alignItems: "center", gap: "10px", marginBottom: "12px" } },
92
+ createElement(
93
+ "span",
94
+ { style: { background: "#e11d48", color: "white", padding: "2px 8px", borderRadius: "9999px", fontSize: "12px", fontWeight: "bold" } },
95
+ isDev ? "Dinou Dev Error" : "Application Error"
96
+ ),
97
+ createElement(
98
+ "h2",
99
+ { style: { margin: 0, fontSize: "1.25rem", fontWeight: 700, color: "#881337" } },
100
+ error?.message || "Unhandled Application Error"
101
+ )
102
+ ),
103
+ isDev && createElement(
104
+ "p",
105
+ { style: { margin: "0 0 16px 0", fontSize: "0.875rem", color: "#9f1239", lineHeight: 1.5 } },
106
+ "An unhandled error occurred during rendering. You can provide a custom error UI by creating an ",
107
+ createElement("code", { style: { background: "#ffe4e6", padding: "2px 6px", borderRadius: "4px", fontWeight: 600 } }, "error.tsx"),
108
+ " file in your route folder."
109
+ ),
110
+ isDev && error?.stack && createElement(
111
+ "pre",
112
+ {
113
+ style: {
114
+ background: "#0f172a",
115
+ color: "#f8fafc",
116
+ padding: "16px",
117
+ borderRadius: "8px",
118
+ overflowX: "auto",
119
+ fontSize: "0.8125rem",
120
+ lineHeight: 1.6,
121
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace",
122
+ },
123
+ },
124
+ cleanErrorStack(error.stack)
125
+ )
126
+ );
127
+ }
128
+
129
+ function SlotErrorRenderer({ error, reset }) {
130
+ const getErrorRSC = typeof globalThis !== "undefined" ? globalThis.__DINOU_GET_ERROR_RSC_PAYLOAD__ : null;
131
+ const errorPromise = useMemo(() => {
132
+ if (typeof getErrorRSC === "function") {
133
+ const route = typeof window !== "undefined" ? window.location.pathname + window.location.search : "";
134
+ return getErrorRSC(route, error);
135
+ }
136
+ return null;
137
+ }, [error]);
138
+
139
+ if (!errorPromise) {
140
+ return createElement(DefaultDevError, { error });
141
+ }
142
+
143
+ const element = use ? use(errorPromise) : errorPromise;
144
+ if (!element) {
145
+ return createElement(DefaultDevError, { error });
146
+ }
147
+
148
+ if (React.isValidElement(element)) {
149
+ if (typeof element.type === "string") {
150
+ return React.cloneElement(element);
151
+ }
152
+ return React.cloneElement(element, { error, reset });
153
+ }
154
+
155
+ return element;
156
+ }
157
+
158
+ class InnerErrorBoundary extends Component {
159
+ constructor(props) {
160
+ super(props);
161
+ this.state = { hasError: false, error: null };
162
+ }
163
+
164
+ static getDerivedStateFromError(error) {
165
+ return { hasError: true, error };
166
+ }
167
+
168
+ componentDidCatch(error, errorInfo) {
169
+ console.error("[Dinou] Inner Error Boundary caught error:", error, errorInfo);
170
+ }
171
+
172
+ render() {
173
+ if (this.state.hasError) {
174
+ return createElement(DefaultDevError, { error: this.state.error });
175
+ }
176
+ return this.props.children;
177
+ }
178
+ }
179
+
180
+ class SlotErrorBoundary extends Component {
181
+ constructor(props) {
182
+ super(props);
183
+ this.state = { hasError: false, error: null };
184
+ }
185
+
186
+ static getDerivedStateFromError(error) {
187
+ return { hasError: true, error };
188
+ }
189
+
190
+ componentDidCatch(error, errorInfo) {
191
+ console.error("[Dinou] Page Error caught in Slot:", error, errorInfo);
192
+ }
193
+
194
+ componentDidUpdate(prevProps) {
195
+ if (
196
+ this.state.hasError &&
197
+ (prevProps.resetKey !== this.props.resetKey || prevProps.pagePromise !== this.props.pagePromise)
198
+ ) {
199
+ this.setState({ hasError: false, error: null });
200
+ }
201
+ }
202
+
203
+ render() {
204
+ if (this.state.hasError) {
205
+ const reset = () => this.setState({ hasError: false, error: null });
206
+ return createElement(
207
+ InnerErrorBoundary,
208
+ null,
209
+ createElement(
210
+ Suspense,
211
+ { fallback: null },
212
+ createElement(SlotErrorRenderer, { error: this.state.error, reset })
213
+ )
214
+ );
215
+ }
216
+ return this.props.children;
217
+ }
218
+ }
219
+
220
+ function PageConsumer({ pagePromise }) {
221
+ if (pagePromise && pagePromise.status === "rejected") {
222
+ throw pagePromise.reason;
223
+ }
224
+ return use ? use(pagePromise) : pagePromise;
225
+ }
226
+
227
+ export function DinouPageSlot() {
228
+ if (typeof useContext !== "function" || !DinouPageContext) {
229
+ return null;
230
+ }
231
+ const slotContext = useContext(DinouPageContext);
232
+ if (!slotContext) {
233
+ return null;
234
+ }
235
+ const pagePromise =
236
+ slotContext && slotContext.pagePromise !== undefined
237
+ ? slotContext.pagePromise
238
+ : slotContext;
239
+ const resetKey =
240
+ slotContext && slotContext.resetKey !== undefined
241
+ ? slotContext.resetKey
242
+ : pagePromise;
243
+
244
+ return createElement(
245
+ SlotErrorBoundary,
246
+ { resetKey, pagePromise },
247
+ createElement(PageConsumer, { pagePromise })
248
+ );
249
+ }
250
+
251
+ function SlotConsumer({ slotPromise, fallback }) {
252
+ if (slotPromise && slotPromise.status === "rejected") {
253
+ throw slotPromise.reason;
254
+ }
255
+ return use ? use(slotPromise) : (slotPromise || fallback);
256
+ }
257
+
258
+ export function DinouCacheSlotBoundary({ id, children }) {
259
+ if (typeof useState !== "function") {
260
+ return children;
261
+ }
262
+ const [slotPromise, setSlotPromise] = useState(null);
263
+
264
+ useEffect(() => {
265
+ const handleRefresh = (e) => {
266
+ if (!e || !e.detail || e.detail.id === id || e.detail.id === "*") {
267
+ if (
268
+ typeof window !== "undefined" &&
269
+ typeof window.__DINOU_FETCH_SLOT__ === "function"
270
+ ) {
271
+ const promise = window.__DINOU_FETCH_SLOT__(id, e.detail?.options);
272
+ if (promise) {
273
+ if (typeof startTransition === "function") {
274
+ startTransition(() => {
275
+ setSlotPromise(promise);
276
+ });
277
+ } else {
278
+ setSlotPromise(promise);
279
+ }
280
+ }
281
+ }
282
+ }
283
+ };
284
+ window.addEventListener("dinou:refresh-slot", handleRefresh);
285
+ return () => window.removeEventListener("dinou:refresh-slot", handleRefresh);
286
+ }, [id]);
287
+
288
+ if (slotPromise) {
289
+ return createElement(
290
+ SlotErrorBoundary,
291
+ { resetKey: slotPromise, pagePromise: slotPromise },
292
+ createElement(
293
+ Suspense,
294
+ { fallback: children },
295
+ createElement(SlotConsumer, { slotPromise, fallback: children })
296
+ )
297
+ );
298
+ }
299
+ return children;
300
+ }
301
+
302
+ export default DinouPageSlot;
@@ -1,14 +1,54 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
1
4
  const statusMap = new Map();
5
+ let isLoaded = false;
6
+
7
+ function loadFromFile() {
8
+ if (isLoaded) return;
9
+ try {
10
+ const filePath = path.resolve(process.cwd(), ".dinou/dist2/status-manifest.json");
11
+ if (fs.existsSync(filePath)) {
12
+ const data = JSON.parse(fs.readFileSync(filePath, "utf8"));
13
+ for (const [k, v] of Object.entries(data)) {
14
+ statusMap.set(k, v);
15
+ }
16
+ }
17
+ } catch (e) {}
18
+ isLoaded = true;
19
+ }
20
+
21
+ function saveToFile() {
22
+ try {
23
+ const dist2 = path.resolve(process.cwd(), ".dinou/dist2");
24
+ if (!fs.existsSync(dist2)) {
25
+ fs.mkdirSync(dist2, { recursive: true });
26
+ }
27
+ const filePath = path.join(dist2, "status-manifest.json");
28
+ const obj = Object.fromEntries(statusMap.entries());
29
+ fs.writeFileSync(filePath, JSON.stringify(obj, null, 2), "utf8");
30
+ } catch (e) {}
31
+ }
2
32
 
3
33
  function getStatus(reqPath) {
4
- return statusMap.get(reqPath)?.status;
34
+ loadFromFile();
35
+ // Also check without trailing slash or with trailing slash
36
+ const clean = reqPath.endsWith("/") ? reqPath.slice(0, -1) : reqPath;
37
+ const withSlash = clean + "/";
38
+ return (
39
+ statusMap.get(reqPath)?.status ??
40
+ statusMap.get(clean)?.status ??
41
+ statusMap.get(withSlash)?.status
42
+ );
5
43
  }
6
44
 
7
45
  function updateStatus(reqPath, status) {
46
+ loadFromFile();
8
47
  const current = statusMap.get(reqPath)?.status;
9
48
  if (current === status) return;
10
49
 
11
50
  statusMap.set(reqPath, { status });
51
+ saveToFile();
12
52
  }
13
53
 
14
54
  module.exports = { getStatus, updateStatus };