-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathgenerate.mjs
More file actions
92 lines (78 loc) · 2.86 KB
/
generate.mjs
File metadata and controls
92 lines (78 loc) · 2.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
import { resolve } from 'node:path';
import { JSX_IMPORTS, ROOT } from '../constants.mjs';
/**
* Creates an ES Module `import` statement as a string, based on parameters.
*
* @param {string|null} importName - The identifier to import.
* @param {string} source - The module path.
* @param {boolean} [useDefault=true] - Whether to use default import (true) or named import (false).
* @returns {string} The generated import statement.
*/
export const createImportDeclaration = (
importName,
source,
useDefault = true
) => {
// Escape backslashes to prevent treating them as escape characters
source = source.replaceAll('\\', '\\\\');
// Side-effect-only import (e.g., CSS files)
if (!importName) {
return `import "${source}";`;
}
// Default import: import Name from "source"
if (useDefault) {
return `import ${importName} from "${source}";`;
}
// Named import: import { Name } from "source"
return `import { ${importName} } from "${source}";`;
};
/**
* Factory function that creates server and client program generators.
*
* Returns two functions that wrap JSX component code:
* - `buildClientProgram`: Wraps component for client-side hydration
* - `buildServerProgram`: Wraps component for server-side rendering
*/
export default () => {
// Generate import statements for all JSX components
// TODO: Optimize by conditionally including server-only or client-only imports
const baseImports = Object.values(JSX_IMPORTS).map(
({ name, source, isDefaultExport = true }) =>
createImportDeclaration(name, source, isDefaultExport)
);
/**
* Builds a client-side hydration program.
*
* @param {string} componentCode - JSX component code expression.
* @returns {string} Complete client-side JavaScript program.
*/
const buildClientProgram = componentCode => {
return [
// Import all JSX components
...baseImports,
// Import CSS styles for client-side rendering
createImportDeclaration(null, resolve(ROOT, './ui/index.css')),
// Import Preact's hydrate function (named import)
createImportDeclaration('hydrate', 'preact', false),
// Hydrate the component into the root element
`hydrate(${componentCode}, document.getElementById("root"));`,
].join('');
};
/**
* Builds a server-side rendering (SSR) program.
*
* @param {string} componentCode - JSX component code expression.
* @returns {string} Complete server-side JavaScript program.
*/
const buildServerProgram = componentCode => {
return [
// Import all JSX components
...baseImports,
// Import Preact's SSR render function (named import)
createImportDeclaration('render', 'preact-render-to-string', false),
// Render component to HTML string and return it
`return render(${componentCode});`,
].join('\n');
};
return { buildClientProgram, buildServerProgram };
};