heliumts 0.2.2
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/LICENSE +21 -0
- package/README.md +356 -0
- package/dist/bin/helium.d.ts +3 -0
- package/dist/bin/helium.d.ts.map +1 -0
- package/dist/bin/helium.js +236 -0
- package/dist/bin/helium.js.map +1 -0
- package/dist/client/Router.d.ts +83 -0
- package/dist/client/Router.d.ts.map +1 -0
- package/dist/client/Router.js +329 -0
- package/dist/client/Router.js.map +1 -0
- package/dist/client/cache.d.ts +8 -0
- package/dist/client/cache.d.ts.map +1 -0
- package/dist/client/cache.js +82 -0
- package/dist/client/cache.js.map +1 -0
- package/dist/client/index.d.ts +10 -0
- package/dist/client/index.d.ts.map +1 -0
- package/dist/client/index.js +9 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/prefetch.d.ts +12 -0
- package/dist/client/prefetch.d.ts.map +1 -0
- package/dist/client/prefetch.js +33 -0
- package/dist/client/prefetch.js.map +1 -0
- package/dist/client/routerManifest.d.ts +28 -0
- package/dist/client/routerManifest.d.ts.map +1 -0
- package/dist/client/routerManifest.js +242 -0
- package/dist/client/routerManifest.js.map +1 -0
- package/dist/client/rpcClient.d.ts +33 -0
- package/dist/client/rpcClient.d.ts.map +1 -0
- package/dist/client/rpcClient.js +383 -0
- package/dist/client/rpcClient.js.map +1 -0
- package/dist/client/transitions.d.ts +85 -0
- package/dist/client/transitions.d.ts.map +1 -0
- package/dist/client/transitions.js +92 -0
- package/dist/client/transitions.js.map +1 -0
- package/dist/client/types.d.ts +6 -0
- package/dist/client/types.d.ts.map +1 -0
- package/dist/client/types.js +2 -0
- package/dist/client/types.js.map +1 -0
- package/dist/client/useCall.d.ts +31 -0
- package/dist/client/useCall.d.ts.map +1 -0
- package/dist/client/useCall.js +40 -0
- package/dist/client/useCall.js.map +1 -0
- package/dist/client/useFetch.d.ts +34 -0
- package/dist/client/useFetch.d.ts.map +1 -0
- package/dist/client/useFetch.js +152 -0
- package/dist/client/useFetch.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/runtime/protocol.d.ts +25 -0
- package/dist/runtime/protocol.d.ts.map +1 -0
- package/dist/runtime/protocol.js +2 -0
- package/dist/runtime/protocol.js.map +1 -0
- package/dist/server/config.d.ts +216 -0
- package/dist/server/config.d.ts.map +1 -0
- package/dist/server/config.js +130 -0
- package/dist/server/config.js.map +1 -0
- package/dist/server/context.d.ts +38 -0
- package/dist/server/context.d.ts.map +1 -0
- package/dist/server/context.js +2 -0
- package/dist/server/context.js.map +1 -0
- package/dist/server/defineHTTPRequest.d.ts +49 -0
- package/dist/server/defineHTTPRequest.d.ts.map +1 -0
- package/dist/server/defineHTTPRequest.js +34 -0
- package/dist/server/defineHTTPRequest.js.map +1 -0
- package/dist/server/defineMethod.d.ts +20 -0
- package/dist/server/defineMethod.d.ts.map +1 -0
- package/dist/server/defineMethod.js +23 -0
- package/dist/server/defineMethod.js.map +1 -0
- package/dist/server/devServer.d.ts +15 -0
- package/dist/server/devServer.d.ts.map +1 -0
- package/dist/server/devServer.js +219 -0
- package/dist/server/devServer.js.map +1 -0
- package/dist/server/handlerLoader.d.ts +1 -0
- package/dist/server/handlerLoader.d.ts.map +1 -0
- package/dist/server/handlerLoader.js +2 -0
- package/dist/server/handlerLoader.js.map +1 -0
- package/dist/server/httpRouter.d.ts +17 -0
- package/dist/server/httpRouter.d.ts.map +1 -0
- package/dist/server/httpRouter.js +227 -0
- package/dist/server/httpRouter.js.map +1 -0
- package/dist/server/index.d.ts +11 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +13 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/middleware.d.ts +30 -0
- package/dist/server/middleware.d.ts.map +1 -0
- package/dist/server/middleware.js +23 -0
- package/dist/server/middleware.js.map +1 -0
- package/dist/server/prodServer.d.ts +27 -0
- package/dist/server/prodServer.d.ts.map +1 -0
- package/dist/server/prodServer.js +301 -0
- package/dist/server/prodServer.js.map +1 -0
- package/dist/server/rateLimiter.d.ts +36 -0
- package/dist/server/rateLimiter.d.ts.map +1 -0
- package/dist/server/rateLimiter.js +113 -0
- package/dist/server/rateLimiter.js.map +1 -0
- package/dist/server/rpcRegistry.d.ts +34 -0
- package/dist/server/rpcRegistry.d.ts.map +1 -0
- package/dist/server/rpcRegistry.js +231 -0
- package/dist/server/rpcRegistry.js.map +1 -0
- package/dist/server/security.d.ts +5 -0
- package/dist/server/security.d.ts.map +1 -0
- package/dist/server/security.js +59 -0
- package/dist/server/security.js.map +1 -0
- package/dist/server/serializer.d.ts +9 -0
- package/dist/server/serializer.d.ts.map +1 -0
- package/dist/server/serializer.js +40 -0
- package/dist/server/serializer.js.map +1 -0
- package/dist/utils/envLoader.d.ts +27 -0
- package/dist/utils/envLoader.d.ts.map +1 -0
- package/dist/utils/envLoader.js +68 -0
- package/dist/utils/envLoader.js.map +1 -0
- package/dist/utils/ipExtractor.d.ts +59 -0
- package/dist/utils/ipExtractor.d.ts.map +1 -0
- package/dist/utils/ipExtractor.js +126 -0
- package/dist/utils/ipExtractor.js.map +1 -0
- package/dist/utils/logger.d.ts +2 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +24 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/vite/heliumPlugin.d.ts +3 -0
- package/dist/vite/heliumPlugin.d.ts.map +1 -0
- package/dist/vite/heliumPlugin.js +294 -0
- package/dist/vite/heliumPlugin.js.map +1 -0
- package/dist/vite/index.d.ts +3 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +3 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/vite/paths.d.ts +8 -0
- package/dist/vite/paths.d.ts.map +1 -0
- package/dist/vite/paths.js +8 -0
- package/dist/vite/paths.js.map +1 -0
- package/dist/vite/scanner.d.ts +35 -0
- package/dist/vite/scanner.d.ts.map +1 -0
- package/dist/vite/scanner.js +167 -0
- package/dist/vite/scanner.js.map +1 -0
- package/dist/vite/ssg.d.ts +22 -0
- package/dist/vite/ssg.d.ts.map +1 -0
- package/dist/vite/ssg.js +547 -0
- package/dist/vite/ssg.js.map +1 -0
- package/dist/vite/virtualServerModule.d.ts +6 -0
- package/dist/vite/virtualServerModule.d.ts.map +1 -0
- package/dist/vite/virtualServerModule.js +82 -0
- package/dist/vite/virtualServerModule.js.map +1 -0
- package/package.json +103 -0
package/dist/vite/ssg.js
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { log } from "../utils/logger.js";
|
|
4
|
+
import { scanServerExports } from "./scanner.js";
|
|
5
|
+
import { generateClientModule } from "./virtualServerModule.js";
|
|
6
|
+
/**
|
|
7
|
+
* Remove string literals from content to avoid false positives when checking for patterns
|
|
8
|
+
* This removes template literals, single-quoted strings, and double-quoted strings
|
|
9
|
+
*/
|
|
10
|
+
function stripStringLiterals(content) {
|
|
11
|
+
// Remove template literals (backtick strings) - handle nested expressions
|
|
12
|
+
let result = content;
|
|
13
|
+
// Remove template literals with their content (simplified - doesn't handle all edge cases but good enough)
|
|
14
|
+
result = result.replace(/`(?:[^`\\]|\\.)*`/g, '""');
|
|
15
|
+
// Remove double-quoted strings
|
|
16
|
+
result = result.replace(/"(?:[^"\\]|\\.)*"/g, '""');
|
|
17
|
+
// Remove single-quoted strings
|
|
18
|
+
result = result.replace(/'(?:[^'\\]|\\.)*'/g, "''");
|
|
19
|
+
// Also remove JSX text content between tags (but not the tags themselves)
|
|
20
|
+
// This helps with cases like <code>useState</code>
|
|
21
|
+
result = result.replace(/>([^<]+)</g, "><");
|
|
22
|
+
return result;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Validate if a page file can be truly statically generated
|
|
26
|
+
* Checks for React hooks and helium imports that would prevent static generation
|
|
27
|
+
*/
|
|
28
|
+
function validateSSGPage(filePath) {
|
|
29
|
+
const rawContent = fs.readFileSync(filePath, "utf-8");
|
|
30
|
+
const warnings = [];
|
|
31
|
+
// Strip string literals and JSX text to avoid false positives
|
|
32
|
+
const content = stripStringLiterals(rawContent);
|
|
33
|
+
// Check for React hooks (common ones)
|
|
34
|
+
const hookPatterns = [
|
|
35
|
+
/\buse(State|Effect|Context|Reducer|Callback|Memo|Ref|ImperativeHandle|LayoutEffect|DebugValue)\s*\(/,
|
|
36
|
+
/\buse[A-Z]\w+\s*\(/, // Custom hooks (useXxx) - must be followed by ( to be a call
|
|
37
|
+
];
|
|
38
|
+
const hasHooks = hookPatterns.some((pattern) => pattern.test(content));
|
|
39
|
+
if (hasHooks) {
|
|
40
|
+
warnings.push("Page uses React hooks which may cause hydration issues");
|
|
41
|
+
}
|
|
42
|
+
// Check for heliumts/client imports - use raw content since imports should be at top level
|
|
43
|
+
const hasClientImports = /^import\s+.*from\s+['"]heliumts\/client['"]/m.test(rawContent);
|
|
44
|
+
if (hasClientImports) {
|
|
45
|
+
warnings.push("Page imports from 'heliumts/client' which requires client-side execution");
|
|
46
|
+
}
|
|
47
|
+
// Check for heliumts/server imports - use raw content since imports should be at top level
|
|
48
|
+
const hasServerImports = /^import\s+.*from\s+['"]heliumts\/server['"]/m.test(rawContent);
|
|
49
|
+
if (hasServerImports) {
|
|
50
|
+
warnings.push("Page imports from 'heliumts/server' which may cause runtime issues");
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
hasHooks,
|
|
54
|
+
hasClientImports,
|
|
55
|
+
hasServerImports,
|
|
56
|
+
warnings,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Scan pages directory and find all pages with "use ssg" directive
|
|
61
|
+
*/
|
|
62
|
+
export function scanSSGPages(root) {
|
|
63
|
+
const pagesDir = path.join(root, "src", "pages");
|
|
64
|
+
if (!fs.existsSync(pagesDir)) {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
const ssgPages = [];
|
|
68
|
+
function walkDirectory(dir) {
|
|
69
|
+
const items = fs.readdirSync(dir);
|
|
70
|
+
for (const item of items) {
|
|
71
|
+
const fullPath = path.join(dir, item);
|
|
72
|
+
const stat = fs.statSync(fullPath);
|
|
73
|
+
if (stat.isDirectory()) {
|
|
74
|
+
walkDirectory(fullPath);
|
|
75
|
+
}
|
|
76
|
+
else if (/\.(tsx|jsx|ts|js)$/.test(item)) {
|
|
77
|
+
const content = fs.readFileSync(fullPath, "utf-8");
|
|
78
|
+
// Check for "use ssg"; directive at the top of the file
|
|
79
|
+
if (/^\s*["']use ssg["']\s*;/m.test(content)) {
|
|
80
|
+
const relativePath = path.relative(path.join(root, "src"), fullPath);
|
|
81
|
+
const urlPath = filePathToUrlPath(relativePath);
|
|
82
|
+
// Validate the page for SSG compatibility
|
|
83
|
+
const validation = validateSSGPage(fullPath);
|
|
84
|
+
const warnings = [...validation.warnings];
|
|
85
|
+
// Also check all layouts for this page
|
|
86
|
+
const layoutPaths = findLayoutPathsForPage(fullPath, root);
|
|
87
|
+
for (const layoutPath of layoutPaths) {
|
|
88
|
+
const layoutValidation = validateSSGPage(layoutPath);
|
|
89
|
+
if (layoutValidation.warnings.length > 0) {
|
|
90
|
+
const layoutRelative = path.relative(path.join(root, "src"), layoutPath);
|
|
91
|
+
warnings.push(`Layout ${layoutRelative} has issues:`);
|
|
92
|
+
for (const warning of layoutValidation.warnings) {
|
|
93
|
+
warnings.push(` └─ ${warning}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
ssgPages.push({
|
|
98
|
+
filePath: fullPath,
|
|
99
|
+
urlPath,
|
|
100
|
+
relativePath,
|
|
101
|
+
warnings,
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
walkDirectory(pagesDir);
|
|
108
|
+
return ssgPages;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Convert file path to URL path
|
|
112
|
+
* pages/index.tsx -> /
|
|
113
|
+
* pages/about.tsx -> /about
|
|
114
|
+
* pages/blog/post.tsx -> /blog/post
|
|
115
|
+
* pages/(website)/contact.tsx -> /contact
|
|
116
|
+
* pages/(portal)/dashboard.tsx -> /dashboard
|
|
117
|
+
*/
|
|
118
|
+
function filePathToUrlPath(relativePath) {
|
|
119
|
+
// Remove 'pages/' prefix and file extension
|
|
120
|
+
let urlPath = relativePath.replace(/^pages\//, "").replace(/\.(tsx|jsx|ts|js)$/, "");
|
|
121
|
+
// Remove route groups (folders in parentheses)
|
|
122
|
+
// E.g., (website)/contact -> /contact
|
|
123
|
+
urlPath = urlPath.replace(/\([^)]+\)\//g, "");
|
|
124
|
+
// Handle index files
|
|
125
|
+
if (urlPath.endsWith("/index") || urlPath === "index") {
|
|
126
|
+
urlPath = urlPath.replace(/\/index$/, "").replace(/^index$/, "");
|
|
127
|
+
}
|
|
128
|
+
// Ensure leading slash
|
|
129
|
+
if (!urlPath.startsWith("/")) {
|
|
130
|
+
urlPath = "/" + urlPath;
|
|
131
|
+
}
|
|
132
|
+
// Root path
|
|
133
|
+
if (urlPath === "/") {
|
|
134
|
+
return "/";
|
|
135
|
+
}
|
|
136
|
+
return urlPath;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Convert URL path to output file path
|
|
140
|
+
* / -> __index.html (special case - renamed later to prevent conflicts)
|
|
141
|
+
* /about -> about.html
|
|
142
|
+
* /blog/post -> blog/post.html
|
|
143
|
+
*/
|
|
144
|
+
function urlPathToOutputPath(urlPath) {
|
|
145
|
+
if (urlPath === "/") {
|
|
146
|
+
return "__index.html";
|
|
147
|
+
}
|
|
148
|
+
// Remove leading slash and add .html extension
|
|
149
|
+
const cleanPath = urlPath.replace(/^\//, "");
|
|
150
|
+
return `${cleanPath}.html`;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Find all layout file paths for a given page path (from root to leaf)
|
|
154
|
+
*/
|
|
155
|
+
function findLayoutPathsForPage(pagePath, root) {
|
|
156
|
+
const pagesDir = path.join(root, "src", "pages");
|
|
157
|
+
const relativePath = path.relative(pagesDir, pagePath);
|
|
158
|
+
const pathParts = path
|
|
159
|
+
.dirname(relativePath)
|
|
160
|
+
.split(path.sep)
|
|
161
|
+
.filter((p) => p !== ".");
|
|
162
|
+
const layoutPaths = [];
|
|
163
|
+
// Check for _layout.tsx from root to leaf (maintains nesting order)
|
|
164
|
+
// Start with root layout
|
|
165
|
+
const rootLayoutPath = path.join(pagesDir, "_layout.tsx");
|
|
166
|
+
if (fs.existsSync(rootLayoutPath)) {
|
|
167
|
+
layoutPaths.push(rootLayoutPath);
|
|
168
|
+
}
|
|
169
|
+
// Then check nested layouts
|
|
170
|
+
for (let i = 1; i <= pathParts.length; i++) {
|
|
171
|
+
const dirPath = path.join(pagesDir, ...pathParts.slice(0, i));
|
|
172
|
+
const layoutPath = path.join(dirPath, "_layout.tsx");
|
|
173
|
+
if (fs.existsSync(layoutPath)) {
|
|
174
|
+
layoutPaths.push(layoutPath);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return layoutPaths;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Find all layout components for a given page path (from root to leaf)
|
|
181
|
+
* Note: Layouts cannot use routing features during SSG since they're pre-rendered
|
|
182
|
+
*/
|
|
183
|
+
async function findLayoutsForPage(pagePath, root, viteServer) {
|
|
184
|
+
const layoutPaths = findLayoutPathsForPage(pagePath, root);
|
|
185
|
+
const layouts = [];
|
|
186
|
+
for (const layoutPath of layoutPaths) {
|
|
187
|
+
try {
|
|
188
|
+
const layoutModule = await viteServer.ssrLoadModule(layoutPath);
|
|
189
|
+
if (layoutModule.default) {
|
|
190
|
+
layouts.push(layoutModule.default);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (error) {
|
|
194
|
+
log("warn", `Could not load layout at ${layoutPath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return layouts;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Render a page component to static HTML using Vite SSR with timeout
|
|
201
|
+
*/
|
|
202
|
+
async function renderPageToHTML(page, root, htmlTemplate, viteServer, timeout = 10000) {
|
|
203
|
+
// Create timeout promise
|
|
204
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
205
|
+
setTimeout(() => {
|
|
206
|
+
reject(new Error(`Rendering timeout after ${timeout}ms - page may contain hooks or async operations`));
|
|
207
|
+
}, timeout);
|
|
208
|
+
});
|
|
209
|
+
// Create render promise
|
|
210
|
+
const renderPromise = (async () => {
|
|
211
|
+
try {
|
|
212
|
+
// Dynamically import React and ReactDOMServer
|
|
213
|
+
const React = (await import("react")).default;
|
|
214
|
+
const ReactDOMServer = await import("react-dom/server");
|
|
215
|
+
// Use Vite's SSR loader to load the page component
|
|
216
|
+
const pageModule = await viteServer.ssrLoadModule(page.filePath);
|
|
217
|
+
const PageComponent = pageModule.default;
|
|
218
|
+
if (!PageComponent) {
|
|
219
|
+
throw new Error(`No default export found in ${page.relativePath}`);
|
|
220
|
+
}
|
|
221
|
+
// Find all layouts (from root to leaf)
|
|
222
|
+
const layouts = await findLayoutsForPage(page.filePath, root, viteServer);
|
|
223
|
+
// Build the component tree: layouts wrap the page, innermost to outermost
|
|
224
|
+
let element = React.createElement(PageComponent);
|
|
225
|
+
// Wrap with layouts from innermost to outermost (reverse order)
|
|
226
|
+
for (let i = layouts.length - 1; i >= 0; i--) {
|
|
227
|
+
element = React.createElement(layouts[i], { children: element });
|
|
228
|
+
}
|
|
229
|
+
// Load RouterContext from our stub
|
|
230
|
+
const heliumClient = await viteServer.ssrLoadModule("heliumts/client");
|
|
231
|
+
const RouterContext = heliumClient.RouterContext;
|
|
232
|
+
// Mock Router Context with the page's URL
|
|
233
|
+
const routerValue = {
|
|
234
|
+
path: page.urlPath,
|
|
235
|
+
params: {},
|
|
236
|
+
searchParams: new URLSearchParams(),
|
|
237
|
+
push: () => { },
|
|
238
|
+
replace: () => { },
|
|
239
|
+
on: () => () => { },
|
|
240
|
+
status: 200,
|
|
241
|
+
};
|
|
242
|
+
// Wrap with RouterContext
|
|
243
|
+
if (RouterContext) {
|
|
244
|
+
element = React.createElement(RouterContext.Provider, { value: routerValue }, element);
|
|
245
|
+
}
|
|
246
|
+
// Render to static HTML
|
|
247
|
+
const markup = ReactDOMServer.renderToString(element);
|
|
248
|
+
// Inject the markup into the HTML template with the SSG marker
|
|
249
|
+
const finalHtml = htmlTemplate.replace(/<div\s+id="root"[^>]*>(.*?)<\/div>/s, `<div id="root" data-ssg-page="${page.urlPath}">${markup}</div>`);
|
|
250
|
+
return finalHtml;
|
|
251
|
+
}
|
|
252
|
+
catch (error) {
|
|
253
|
+
log("error", `Failed to render ${page.relativePath}:`, error);
|
|
254
|
+
throw error; // Don't fallback, let the caller handle the error
|
|
255
|
+
}
|
|
256
|
+
})();
|
|
257
|
+
// Race between timeout and render
|
|
258
|
+
return Promise.race([renderPromise, timeoutPromise]);
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Generate static HTML files for all SSG pages
|
|
262
|
+
*/
|
|
263
|
+
export async function generateStaticPages(context, root, htmlTemplate, distDir) {
|
|
264
|
+
// Scan for SSG pages
|
|
265
|
+
const ssgPages = scanSSGPages(root);
|
|
266
|
+
if (ssgPages.length === 0) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
log("info", `Generating ${ssgPages.length} static page(s) for SSG...`);
|
|
270
|
+
// Check for dynamic routes (not supported yet)
|
|
271
|
+
const dynamicPages = ssgPages.filter((p) => p.relativePath.includes("["));
|
|
272
|
+
if (dynamicPages.length > 0) {
|
|
273
|
+
log("warn", `Skipping ${dynamicPages.length} dynamic route(s) - not yet supported:\n` + dynamicPages.map((p) => ` - ${p.relativePath}`).join("\n"));
|
|
274
|
+
}
|
|
275
|
+
// Filter out dynamic routes
|
|
276
|
+
const staticPages = ssgPages.filter((p) => !p.relativePath.includes("["));
|
|
277
|
+
// Display warnings for pages that may not be truly static
|
|
278
|
+
const pagesWithWarnings = staticPages.filter((p) => p.warnings.length > 0);
|
|
279
|
+
if (pagesWithWarnings.length > 0) {
|
|
280
|
+
log("warn", "");
|
|
281
|
+
log("warn", "⚠️ SSG Warning: The following pages may not be fully static:");
|
|
282
|
+
for (const page of pagesWithWarnings) {
|
|
283
|
+
log("warn", ` ${page.relativePath}:`);
|
|
284
|
+
for (const warning of page.warnings) {
|
|
285
|
+
log("warn", ` - ${warning}`);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
log("warn", " These pages will be pre-rendered but may require client-side hydration.");
|
|
289
|
+
log("warn", "");
|
|
290
|
+
}
|
|
291
|
+
// Precompute RPC client stubs for SSG (mirrors helium Vite plugin)
|
|
292
|
+
const { methods } = scanServerExports(root);
|
|
293
|
+
const serverStubCode = `// Auto-generated SSG RPC stub\n${generateClientModule(methods)}\n`;
|
|
294
|
+
// Create a stub for heliumts/client that provides mock Router and hooks
|
|
295
|
+
const clientStubCode = `
|
|
296
|
+
// Auto-generated SSG client stub
|
|
297
|
+
import React from 'react';
|
|
298
|
+
|
|
299
|
+
// Mock RouterContext
|
|
300
|
+
export const RouterContext = React.createContext({
|
|
301
|
+
path: '/',
|
|
302
|
+
params: {},
|
|
303
|
+
searchParams: new URLSearchParams(),
|
|
304
|
+
push: () => {},
|
|
305
|
+
replace: () => {},
|
|
306
|
+
on: () => () => {},
|
|
307
|
+
status: 200,
|
|
308
|
+
isNavigating: false,
|
|
309
|
+
isPending: false,
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// Mock useRouter hook
|
|
313
|
+
export function useRouter() {
|
|
314
|
+
const ctx = React.useContext(RouterContext);
|
|
315
|
+
if (!ctx) {
|
|
316
|
+
console.warn('useRouter called outside RouterContext during SSG');
|
|
317
|
+
return {
|
|
318
|
+
path: '/',
|
|
319
|
+
params: {},
|
|
320
|
+
searchParams: new URLSearchParams(),
|
|
321
|
+
push: () => {},
|
|
322
|
+
replace: () => {},
|
|
323
|
+
on: () => () => {},
|
|
324
|
+
status: 200,
|
|
325
|
+
isNavigating: false,
|
|
326
|
+
isPending: false,
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
return ctx;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
// Mock AppRouter component (alias for Router)
|
|
333
|
+
export function AppRouter({ children }) {
|
|
334
|
+
return React.createElement(React.Fragment, null, children);
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// Mock Router component
|
|
338
|
+
export function Router({ children }) {
|
|
339
|
+
return React.createElement(React.Fragment, null, children);
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Mock Link component
|
|
343
|
+
export function Link({ href, children, prefetch, ...props }) {
|
|
344
|
+
return React.createElement('a', { href, ...props }, children);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Mock Redirect component
|
|
348
|
+
export function Redirect({ to, replace }) {
|
|
349
|
+
return null;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
// Mock useCall hook
|
|
353
|
+
export function useCall(serverFn) {
|
|
354
|
+
return async (...args) => {
|
|
355
|
+
console.warn('useCall called during SSG - this will not execute');
|
|
356
|
+
return null;
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
// Mock useFetch hook
|
|
361
|
+
export function useFetch(serverFn, ...args) {
|
|
362
|
+
console.warn('useFetch called during SSG - returning null');
|
|
363
|
+
return { data: null, loading: false, error: null, refetch: async () => {} };
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// Re-export cache (mock)
|
|
367
|
+
export const cache = {
|
|
368
|
+
get: () => null,
|
|
369
|
+
set: () => {},
|
|
370
|
+
delete: () => {},
|
|
371
|
+
clear: () => {},
|
|
372
|
+
};
|
|
373
|
+
|
|
374
|
+
// Mock PageTransition and useDeferredNavigation (also available from heliumts/client/transitions)
|
|
375
|
+
export function useDeferredNavigation() {
|
|
376
|
+
return {
|
|
377
|
+
path: '/',
|
|
378
|
+
deferredPath: '/',
|
|
379
|
+
isStale: false,
|
|
380
|
+
isPending: false,
|
|
381
|
+
isTransitioning: false,
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
export function PageTransition({ children, loadingClassName, loadingStyle, fallback }) {
|
|
386
|
+
return React.createElement('div', null, children);
|
|
387
|
+
}
|
|
388
|
+
`;
|
|
389
|
+
// Create a stub for heliumts/client/transitions
|
|
390
|
+
const transitionsStubCode = `
|
|
391
|
+
// Auto-generated SSG transitions stub
|
|
392
|
+
import React from 'react';
|
|
393
|
+
|
|
394
|
+
// Mock useDeferredNavigation hook - returns static values for SSG
|
|
395
|
+
export function useDeferredNavigation() {
|
|
396
|
+
return {
|
|
397
|
+
path: '/',
|
|
398
|
+
deferredPath: '/',
|
|
399
|
+
isStale: false,
|
|
400
|
+
isPending: false,
|
|
401
|
+
isTransitioning: false,
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// Mock PageTransition component - renders children without transition logic
|
|
406
|
+
export function PageTransition({ children, loadingClassName, loadingStyle, fallback }) {
|
|
407
|
+
// During SSG, just render the children without any transition logic
|
|
408
|
+
return React.createElement('div', null, children);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
export default {
|
|
412
|
+
useDeferredNavigation,
|
|
413
|
+
PageTransition,
|
|
414
|
+
};
|
|
415
|
+
`;
|
|
416
|
+
// Create a stub for heliumts/client/prefetch
|
|
417
|
+
const prefetchStubCode = `
|
|
418
|
+
// Auto-generated SSG prefetch stub
|
|
419
|
+
export function prefetchRoute() {
|
|
420
|
+
// No-op during SSG
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
export function clearPrefetchCache() {
|
|
424
|
+
// No-op during SSG
|
|
425
|
+
}
|
|
426
|
+
`;
|
|
427
|
+
// Write stub files to node_modules/.helium
|
|
428
|
+
const heliumInternalDir = path.join(root, "node_modules", ".helium");
|
|
429
|
+
if (!fs.existsSync(heliumInternalDir)) {
|
|
430
|
+
fs.mkdirSync(heliumInternalDir, { recursive: true });
|
|
431
|
+
}
|
|
432
|
+
const ssgServerStubPath = path.join(heliumInternalDir, "ssg-server-stub.mjs");
|
|
433
|
+
const ssgClientStubPath = path.join(heliumInternalDir, "ssg-client-stub.mjs");
|
|
434
|
+
const ssgTransitionsStubPath = path.join(heliumInternalDir, "ssg-transitions-stub.mjs");
|
|
435
|
+
const ssgPrefetchStubPath = path.join(heliumInternalDir, "ssg-prefetch-stub.mjs");
|
|
436
|
+
fs.writeFileSync(ssgServerStubPath, serverStubCode, "utf-8");
|
|
437
|
+
fs.writeFileSync(ssgClientStubPath, clientStubCode, "utf-8");
|
|
438
|
+
fs.writeFileSync(ssgTransitionsStubPath, transitionsStubCode, "utf-8");
|
|
439
|
+
fs.writeFileSync(ssgPrefetchStubPath, prefetchStubCode, "utf-8");
|
|
440
|
+
// Create a temporary Vite server for SSR rendering
|
|
441
|
+
const { createServer } = await import("vite");
|
|
442
|
+
const heliumPlugin = (await import("./heliumPlugin.js")).default;
|
|
443
|
+
const viteServer = await createServer({
|
|
444
|
+
root,
|
|
445
|
+
server: { middlewareMode: true },
|
|
446
|
+
appType: "custom",
|
|
447
|
+
logLevel: "error",
|
|
448
|
+
plugins: [heliumPlugin()],
|
|
449
|
+
resolve: {
|
|
450
|
+
alias: [
|
|
451
|
+
// Most specific aliases first - heliumts/client/transitions and heliumts/client/prefetch
|
|
452
|
+
{ find: /^heliumts\/client\/transitions$/, replacement: ssgTransitionsStubPath },
|
|
453
|
+
{ find: /^heliumts\/client\/prefetch$/, replacement: ssgPrefetchStubPath },
|
|
454
|
+
// Then heliumts/client and heliumts/server
|
|
455
|
+
{ find: /^heliumts\/client$/, replacement: ssgClientStubPath },
|
|
456
|
+
{ find: /^heliumts\/server$/, replacement: ssgServerStubPath },
|
|
457
|
+
],
|
|
458
|
+
},
|
|
459
|
+
ssr: {
|
|
460
|
+
external: ["react", "react-dom"],
|
|
461
|
+
// Don't externalize heliumts packages - we want to use our stubs
|
|
462
|
+
noExternal: ["heliumts"],
|
|
463
|
+
},
|
|
464
|
+
});
|
|
465
|
+
try {
|
|
466
|
+
// Generate HTML for each static page
|
|
467
|
+
const zlib = await import("zlib");
|
|
468
|
+
let successCount = 0;
|
|
469
|
+
let failureCount = 0;
|
|
470
|
+
let hasIndexSSG = false;
|
|
471
|
+
// Calculate max path length for proper alignment (min 35, max 80)
|
|
472
|
+
const maxPathLength = Math.min(80, Math.max(35, ...staticPages.map((p) => urlPathToOutputPath(p.urlPath).length)));
|
|
473
|
+
for (const page of staticPages) {
|
|
474
|
+
try {
|
|
475
|
+
// Render the page component to static HTML using Vite SSR with 10s timeout
|
|
476
|
+
const html = await renderPageToHTML(page, root, htmlTemplate, viteServer, 10000);
|
|
477
|
+
const outputPath = urlPathToOutputPath(page.urlPath);
|
|
478
|
+
const fullOutputPath = path.join(distDir, outputPath);
|
|
479
|
+
// Track if the root page (/) has SSG
|
|
480
|
+
if (page.urlPath === "/") {
|
|
481
|
+
hasIndexSSG = true;
|
|
482
|
+
}
|
|
483
|
+
// Ensure directory exists
|
|
484
|
+
const outputDir = path.dirname(fullOutputPath);
|
|
485
|
+
if (!fs.existsSync(outputDir)) {
|
|
486
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
487
|
+
}
|
|
488
|
+
// Write the HTML file
|
|
489
|
+
fs.writeFileSync(fullOutputPath, html, "utf-8");
|
|
490
|
+
// Calculate file size and gzipped size
|
|
491
|
+
const size = Buffer.byteLength(html, "utf-8");
|
|
492
|
+
const sizeKB = (size / 1024).toFixed(2);
|
|
493
|
+
// Calculate gzipped size
|
|
494
|
+
const gzipped = zlib.gzipSync(html);
|
|
495
|
+
const gzipSizeKB = (gzipped.length / 1024).toFixed(2);
|
|
496
|
+
log("info", ` ${outputPath.padEnd(maxPathLength)} ${sizeKB.padStart(8)} kB │ gzip: ${gzipSizeKB.padStart(7)} kB`);
|
|
497
|
+
successCount++;
|
|
498
|
+
}
|
|
499
|
+
catch (error) {
|
|
500
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
501
|
+
if (errorMsg.includes("timeout")) {
|
|
502
|
+
log("error", ` ✗ ${page.relativePath} - ${errorMsg}`);
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
log("error", ` ✗ ${page.relativePath} - Failed to generate:`, error);
|
|
506
|
+
}
|
|
507
|
+
// Write a fallback HTML file with empty root div (client will hydrate)
|
|
508
|
+
const outputPath = urlPathToOutputPath(page.urlPath);
|
|
509
|
+
const fullOutputPath = path.join(distDir, outputPath);
|
|
510
|
+
const outputDir = path.dirname(fullOutputPath);
|
|
511
|
+
if (!fs.existsSync(outputDir)) {
|
|
512
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
513
|
+
}
|
|
514
|
+
const fallbackHtml = htmlTemplate.replace(/<div\s+id="root"[^>]*>.*?<\/div>/s, `<div id="root" data-ssg-failed="${page.urlPath}"></div>`);
|
|
515
|
+
fs.writeFileSync(fullOutputPath, fallbackHtml, "utf-8");
|
|
516
|
+
failureCount++;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
// If index page has SSG, we need to handle it specially:
|
|
520
|
+
// 1. Rename __index.html to index.ssg.html (the SSG version)
|
|
521
|
+
// 2. Create a clean blank index.html as fallback for non-root routes
|
|
522
|
+
if (hasIndexSSG) {
|
|
523
|
+
const tempIndexPath = path.join(distDir, "__index.html");
|
|
524
|
+
const ssgIndexPath = path.join(distDir, "index.ssg.html");
|
|
525
|
+
const indexPath = path.join(distDir, "index.html");
|
|
526
|
+
// Move __index.html to index.ssg.html
|
|
527
|
+
if (fs.existsSync(tempIndexPath)) {
|
|
528
|
+
fs.renameSync(tempIndexPath, ssgIndexPath);
|
|
529
|
+
}
|
|
530
|
+
// Create a blank index.html as the SPA fallback
|
|
531
|
+
const blankIndexHtml = htmlTemplate.replace(/<div\s+id="root"[^>]*>.*?<\/div>/s, '<div id="root"></div>');
|
|
532
|
+
fs.writeFileSync(indexPath, blankIndexHtml, "utf-8");
|
|
533
|
+
log("info", ` ${"index.ssg.html".padEnd(maxPathLength)} (SSG root page)`);
|
|
534
|
+
log("info", ` ${"index.html".padEnd(maxPathLength)} (blank SPA fallback)`);
|
|
535
|
+
}
|
|
536
|
+
// Summary
|
|
537
|
+
if (failureCount > 0) {
|
|
538
|
+
log("warn", "");
|
|
539
|
+
log("warn", `SSG completed with ${successCount} success(es) and ${failureCount} failure(s).`);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
finally {
|
|
543
|
+
// Always close the Vite server, even if generation fails
|
|
544
|
+
await viteServer.close();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
//# sourceMappingURL=ssg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ssg.js","sourceRoot":"","sources":["../../src/vite/ssg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { HTTPHandlerExport, MethodExport, MiddlewareExport } from "./scanner.js";
|
|
2
|
+
export declare function generateServerManifest(methods: MethodExport[], httpHandlers: HTTPHandlerExport[], middleware?: MiddlewareExport): string;
|
|
3
|
+
export declare function generateClientModule(methods: MethodExport[]): string;
|
|
4
|
+
export declare function generateTypeDefinitions(methods: MethodExport[], root: string): string;
|
|
5
|
+
export declare function generateEntryModule(): string;
|
|
6
|
+
//# sourceMappingURL=virtualServerModule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"virtualServerModule.d.ts","sourceRoot":"","sources":["../../src/vite/virtualServerModule.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAEjF,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,YAAY,EAAE,iBAAiB,EAAE,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,MAAM,CAwBxI;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,MAAM,CAIpE;AAED,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAqCrF;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAkB5C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
export function generateServerManifest(methods, httpHandlers, middleware) {
|
|
3
|
+
const methodImports = methods.map((m, i) => `import { ${m.name} as method_${i} } from '${m.filePath}';`).join("\n");
|
|
4
|
+
const httpImports = httpHandlers.map((h, i) => `import { ${h.name} as http_${i} } from '${h.filePath}';`).join("\n");
|
|
5
|
+
const middlewareImport = middleware ? `import ${middleware.name === "default" ? "middleware" : `{ ${middleware.name} as middleware }`} from '${middleware.filePath}';` : "";
|
|
6
|
+
const methodRegistrations = methods.map((m, i) => ` registry.register('${m.name}', method_${i});`).join("\n");
|
|
7
|
+
const httpExports = httpHandlers.map((h, i) => ` { name: '${h.name}', handler: http_${i} },`).join("\n");
|
|
8
|
+
return `
|
|
9
|
+
${methodImports}
|
|
10
|
+
${httpImports}
|
|
11
|
+
${middlewareImport}
|
|
12
|
+
|
|
13
|
+
export function registerAll(registry) {
|
|
14
|
+
${methodRegistrations}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const httpHandlers = [
|
|
18
|
+
${httpExports}
|
|
19
|
+
];
|
|
20
|
+
|
|
21
|
+
export const middlewareHandler = ${middleware ? "middleware" : "null"};
|
|
22
|
+
`;
|
|
23
|
+
}
|
|
24
|
+
export function generateClientModule(methods) {
|
|
25
|
+
const exports = methods.map((m) => `export const ${m.name} = { __id: '${m.name}' };`).join("\n");
|
|
26
|
+
return exports;
|
|
27
|
+
}
|
|
28
|
+
export function generateTypeDefinitions(methods, root) {
|
|
29
|
+
const methodsWithSuffix = methods.map((m, i) => ({
|
|
30
|
+
...m,
|
|
31
|
+
alias: `${m.name}_${i}${Math.random().toString(36).substring(2, 8)}`,
|
|
32
|
+
}));
|
|
33
|
+
const imports = methodsWithSuffix
|
|
34
|
+
.map((m) => {
|
|
35
|
+
let relPath = path.relative(path.join(root, "src"), m.filePath);
|
|
36
|
+
if (!relPath.startsWith(".")) {
|
|
37
|
+
relPath = "../" + relPath;
|
|
38
|
+
}
|
|
39
|
+
relPath = relPath.replace(/\.ts$/, "");
|
|
40
|
+
return `import type { ${m.name} as ${m.alias} } from '${relPath}';`;
|
|
41
|
+
})
|
|
42
|
+
.join("\n");
|
|
43
|
+
const exports = methodsWithSuffix
|
|
44
|
+
.map((m) => {
|
|
45
|
+
return `export const ${m.name}: import('heliumts/client').MethodStub<
|
|
46
|
+
Parameters<typeof ${m.alias}['handler']>[0],
|
|
47
|
+
Awaited<ReturnType<typeof ${m.alias}['handler']>>
|
|
48
|
+
>;`;
|
|
49
|
+
})
|
|
50
|
+
.join("\n");
|
|
51
|
+
return `/* eslint-disable */
|
|
52
|
+
/**
|
|
53
|
+
* Auto generated file - DO NOT EDIT!
|
|
54
|
+
* # Helium Server Type Definitions
|
|
55
|
+
**/
|
|
56
|
+
${imports}
|
|
57
|
+
|
|
58
|
+
declare module 'heliumts/server' {
|
|
59
|
+
${exports}
|
|
60
|
+
}
|
|
61
|
+
`;
|
|
62
|
+
}
|
|
63
|
+
export function generateEntryModule() {
|
|
64
|
+
return `
|
|
65
|
+
import React from 'react';
|
|
66
|
+
import { createRoot } from 'react-dom/client';
|
|
67
|
+
import { AppRouter } from 'heliumts/client';
|
|
68
|
+
import App from '/src/App';
|
|
69
|
+
|
|
70
|
+
const rootEl = document.getElementById('root');
|
|
71
|
+
if (!rootEl) {
|
|
72
|
+
throw new Error('Root element not found. Helium requires a <div id=\"root\"></div> in your HTML.');
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
createRoot(rootEl).render(
|
|
76
|
+
<React.StrictMode>
|
|
77
|
+
<AppRouter AppShell={App} />
|
|
78
|
+
</React.StrictMode>
|
|
79
|
+
);
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=virtualServerModule.js.map
|