create-frootjs 0.0.0-stage → 1.0.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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +68 -2
  3. package/dist/generator.d.ts +21 -0
  4. package/dist/generator.d.ts.map +1 -0
  5. package/dist/generator.js +62 -0
  6. package/dist/generator.js.map +1 -0
  7. package/dist/index.d.ts +7 -0
  8. package/dist/index.d.ts.map +1 -0
  9. package/dist/index.js +215 -0
  10. package/dist/index.js.map +1 -0
  11. package/dist/templates/fullstack.d.ts +7 -0
  12. package/dist/templates/fullstack.d.ts.map +1 -0
  13. package/dist/templates/fullstack.js +224 -0
  14. package/dist/templates/fullstack.js.map +1 -0
  15. package/dist/templates/index.d.ts +10 -0
  16. package/dist/templates/index.d.ts.map +1 -0
  17. package/dist/templates/index.js +26 -0
  18. package/dist/templates/index.js.map +1 -0
  19. package/dist/templates/minimal.d.ts +7 -0
  20. package/dist/templates/minimal.d.ts.map +1 -0
  21. package/dist/templates/minimal.js +89 -0
  22. package/dist/templates/minimal.js.map +1 -0
  23. package/dist/templates/modular.d.ts +7 -0
  24. package/dist/templates/modular.d.ts.map +1 -0
  25. package/dist/templates/modular.js +300 -0
  26. package/dist/templates/modular.js.map +1 -0
  27. package/dist/templates/mvc.d.ts +7 -0
  28. package/dist/templates/mvc.d.ts.map +1 -0
  29. package/dist/templates/mvc.js +239 -0
  30. package/dist/templates/mvc.js.map +1 -0
  31. package/dist/templates/openapi.d.ts +7 -0
  32. package/dist/templates/openapi.d.ts.map +1 -0
  33. package/dist/templates/openapi.js +206 -0
  34. package/dist/templates/openapi.js.map +1 -0
  35. package/dist/templates/streaming.d.ts +7 -0
  36. package/dist/templates/streaming.d.ts.map +1 -0
  37. package/dist/templates/streaming.js +211 -0
  38. package/dist/templates/streaming.js.map +1 -0
  39. package/dist/templates/types.d.ts +17 -0
  40. package/dist/templates/types.d.ts.map +1 -0
  41. package/dist/templates/types.js +47 -0
  42. package/dist/templates/types.js.map +1 -0
  43. package/dist/templates/websocket.d.ts +7 -0
  44. package/dist/templates/websocket.d.ts.map +1 -0
  45. package/dist/templates/websocket.js +198 -0
  46. package/dist/templates/websocket.js.map +1 -0
  47. package/dist/ui.d.ts +73 -0
  48. package/dist/ui.d.ts.map +1 -0
  49. package/dist/ui.js +236 -0
  50. package/dist/ui.js.map +1 -0
  51. package/package.json +45 -4
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 OrbitNorth LLC
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,69 @@
1
- # Temporary Holding Version
1
+ # create-frootjs
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The official CLI project generator for Froot applications.
4
+
5
+ Quickly spin up production-ready Froot projects with your choice of architectural patterns, complete with TypeScript configuration, onion middleware, and developer tooling.
6
+
7
+ ## Quick Start
8
+
9
+ Run any of the following commands in your terminal:
10
+
11
+ ```bash
12
+ # Using npm
13
+ npm create frootjs@latest
14
+
15
+ # Using pnpm
16
+ pnpm create frootjs
17
+
18
+ # Using yarn
19
+ yarn create frootjs
20
+
21
+ # Using bun
22
+ bun create frootjs
23
+ ```
24
+
25
+ Or invoke the binary directly:
26
+
27
+ ```bash
28
+ npx create-frootjs my-app
29
+ ```
30
+
31
+ ## Available Architectural Templates
32
+
33
+ | Template | Flag | Description |
34
+ | :--- | :--- | :--- |
35
+ | **MVC / Layered** | `--template mvc` | Enterprise layered pattern: routes, controllers, services, models, and middleware |
36
+ | **Modular (NestJS-style)** | `--template modular` | Feature-based domain modules (`src/modules/*`), auth guard, and error filters |
37
+ | **Streaming & SSE** | `--template streaming` | Server-Sent Events metrics, AI token streaming simulation, and HTML live client |
38
+ | **WebSocket Hub** | `--template websocket` | Cross-runtime WebSockets, pub/sub rooms hub, and interactive chat client |
39
+ | **OpenAPI 3.1 & Docs** | `--template openapi` | Auto-generated OpenAPI 3.1 JSON and Scalar interactive reference UI at `/docs` |
40
+ | **Fullstack JSX & SSR** | `--template fullstack` | Native JSX components, typed layout middleware, and zero-JS server rendering |
41
+ | **Minimal Starter** | `--template minimal` | Lean single-file API starter with JSON endpoints and CORS |
42
+
43
+ ## CLI Options
44
+
45
+ ```
46
+ Usage:
47
+ npx create-frootjs [project-directory] [options]
48
+
49
+ Options:
50
+ -t, --template <name> Template architecture (mvc, modular, streaming, websocket, openapi, fullstack, minimal)
51
+ --pm <manager> Package manager to use: pnpm | npm | yarn | bun
52
+ --git / --no-git Initialize a git repository
53
+ --install / --no-install Automatically install project dependencies
54
+ -y, --yes Accept all defaults non-interactively
55
+ -v, --version Display CLI version
56
+ -h, --help Display help information
57
+ ```
58
+
59
+ ### Non-Interactive Automation Example
60
+
61
+ For CI/CD or scripted setups:
62
+
63
+ ```bash
64
+ npx create-frootjs my-api --template modular --pm pnpm --git --install
65
+ ```
66
+
67
+ ## License
68
+
69
+ MIT (c) OrbitNorth LLC
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Project Scaffolding Engine
3
+ * Writes template files to disk, initializes git, and executes dependency installation.
4
+ */
5
+ import { TemplateDefinition } from './templates/index.js';
6
+ export interface ScaffoldOptions {
7
+ targetDir: string;
8
+ projectName: string;
9
+ template: TemplateDefinition;
10
+ pkgManager: 'pnpm' | 'npm' | 'yarn' | 'bun';
11
+ gitInit: boolean;
12
+ installDeps: boolean;
13
+ }
14
+ export interface ScaffoldResult {
15
+ targetDir: string;
16
+ filesWritten: number;
17
+ gitInitialized: boolean;
18
+ depsInstalled: boolean;
19
+ }
20
+ export declare function scaffoldProject(options: ScaffoldOptions): Promise<ScaffoldResult>;
21
+ //# sourceMappingURL=generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.d.ts","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAK1D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,UAAU,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,CAAC;IAC5C,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAuDvF"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Project Scaffolding Engine
3
+ * Writes template files to disk, initializes git, and executes dependency installation.
4
+ */
5
+ import * as fs from 'node:fs/promises';
6
+ import * as path from 'node:path';
7
+ import { exec } from 'node:child_process';
8
+ import { promisify } from 'node:util';
9
+ import { c, printSuccess, printInfo, printWarning } from './ui.js';
10
+ const execAsync = promisify(exec);
11
+ export async function scaffoldProject(options) {
12
+ const { targetDir, projectName, template, pkgManager, gitInit, installDeps } = options;
13
+ // 1. Ensure target directory exists
14
+ await fs.mkdir(targetDir, { recursive: true });
15
+ // 2. Generate files map from template
16
+ const files = template.generate(projectName);
17
+ const fileKeys = Object.keys(files);
18
+ // 3. Write each file to destination
19
+ for (const relativePath of fileKeys) {
20
+ const filePath = path.join(targetDir, relativePath);
21
+ const dir = path.dirname(filePath);
22
+ await fs.mkdir(dir, { recursive: true });
23
+ await fs.writeFile(filePath, files[relativePath], 'utf8');
24
+ }
25
+ printSuccess(`Created ${c.bold}${fileKeys.length}${c.reset} files from template ${c.emerald}${template.name}${c.reset}`);
26
+ // 4. Git initialization
27
+ let gitInitialized = false;
28
+ if (gitInit) {
29
+ try {
30
+ await execAsync('git init', { cwd: targetDir });
31
+ gitInitialized = true;
32
+ printSuccess(`Initialized git repository`);
33
+ }
34
+ catch {
35
+ printWarning(`Could not initialize git repository (is git installed?)`);
36
+ }
37
+ }
38
+ // 5. Dependency installation
39
+ let depsInstalled = false;
40
+ if (installDeps) {
41
+ printInfo(`Installing dependencies using ${c.bold}${pkgManager}${c.reset}...`);
42
+ try {
43
+ // Use .cmd extension on Windows when running npm/pnpm/yarn
44
+ const isWin = process.platform === 'win32';
45
+ const cmd = isWin && pkgManager !== 'bun' ? `${pkgManager}.cmd` : pkgManager;
46
+ await execAsync(`${cmd} install`, { cwd: targetDir });
47
+ depsInstalled = true;
48
+ printSuccess(`Dependencies installed successfully`);
49
+ }
50
+ catch (err) {
51
+ const errMsg = err instanceof Error ? err.message : String(err);
52
+ printWarning(`Dependency installation skipped or failed: ${errMsg}`);
53
+ }
54
+ }
55
+ return {
56
+ targetDir,
57
+ filesWritten: fileKeys.length,
58
+ gitInitialized,
59
+ depsInstalled,
60
+ };
61
+ }
62
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * create-frootjs CLI Project Generator
4
+ * Interactive, zero-dependency CLI tool for scaffolding modern Froot web applications.
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;GAGG"}
package/dist/index.js ADDED
@@ -0,0 +1,215 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * create-frootjs CLI Project Generator
4
+ * Interactive, zero-dependency CLI tool for scaffolding modern Froot web applications.
5
+ */
6
+ import * as path from 'node:path';
7
+ import * as fs from 'node:fs';
8
+ import { printBanner, printStep, printError, printNextSteps, promptText, promptSelect, promptConfirm, c, } from './ui.js';
9
+ import { TEMPLATES, TEMPLATE_LIST, getTemplate } from './templates/index.js';
10
+ import { scaffoldProject } from './generator.js';
11
+ const VERSION = '1.0.2';
12
+ function parseCliArgs(argv) {
13
+ const args = {};
14
+ const raw = argv.slice(2);
15
+ for (let i = 0; i < raw.length; i++) {
16
+ const item = raw[i];
17
+ if (item === '--help' || item === '-h') {
18
+ args.help = true;
19
+ }
20
+ else if (item === '--version' || item === '-v') {
21
+ args.version = true;
22
+ }
23
+ else if (item === '--yes' || item === '-y') {
24
+ args.yes = true;
25
+ }
26
+ else if (item === '--git') {
27
+ args.git = true;
28
+ }
29
+ else if (item === '--no-git') {
30
+ args.git = false;
31
+ }
32
+ else if (item === '--install') {
33
+ args.install = true;
34
+ }
35
+ else if (item === '--no-install') {
36
+ args.install = false;
37
+ }
38
+ else if (item === '--template' || item === '-t') {
39
+ args.template = raw[++i];
40
+ }
41
+ else if (item.startsWith('--template=')) {
42
+ args.template = item.split('=')[1];
43
+ }
44
+ else if (item === '--pm') {
45
+ args.pkgManager = raw[++i];
46
+ }
47
+ else if (item.startsWith('--pm=')) {
48
+ args.pkgManager = item.split('=')[1];
49
+ }
50
+ else if (!item.startsWith('-') && !args.targetDir) {
51
+ args.targetDir = item;
52
+ }
53
+ }
54
+ return args;
55
+ }
56
+ function printUsage() {
57
+ console.log(`
58
+ ${c.bold}Usage:${c.reset}
59
+ npm create frootjs [project-directory] [options]
60
+ npx create-frootjs [project-directory] [options]
61
+
62
+ ${c.bold}Options:${c.reset}
63
+ -t, --template <name> Template architecture:
64
+ • mvc MVC / Layered Architecture
65
+ • modular Modular Architecture (NestJS-style)
66
+ • streaming Real-Time Streaming & SSE
67
+ • websocket WebSocket & Real-Time Pub/Sub
68
+ • openapi OpenAPI 3.1 & Interactive Docs
69
+ • fullstack Fullstack JSX & SSR
70
+ • minimal Minimal Starter (Single-file)
71
+ --pm <manager> Package manager: pnpm | npm | yarn | bun
72
+ --git / --no-git Initialize a git repository
73
+ --install / --no-install Automatically install dependencies
74
+ -y, --yes Accept all defaults non-interactively
75
+ -v, --version Display version
76
+ -h, --help Display help information
77
+ `);
78
+ }
79
+ /** Detect which package manager invoked create-frootjs */
80
+ function detectCurrentPackageManager() {
81
+ const userAgent = process.env.npm_config_user_agent || '';
82
+ if (userAgent.startsWith('pnpm'))
83
+ return 'pnpm';
84
+ if (userAgent.startsWith('yarn'))
85
+ return 'yarn';
86
+ if (userAgent.startsWith('bun'))
87
+ return 'bun';
88
+ return 'npm';
89
+ }
90
+ async function main() {
91
+ const args = parseCliArgs(process.argv);
92
+ if (args.version) {
93
+ console.log(`create-frootjs v${VERSION}`);
94
+ return;
95
+ }
96
+ if (args.help) {
97
+ printBanner(VERSION);
98
+ printUsage();
99
+ return;
100
+ }
101
+ printBanner(VERSION);
102
+ // 1. Resolve Project Directory & Name
103
+ let targetDir = args.targetDir;
104
+ if (!targetDir) {
105
+ if (args.yes) {
106
+ targetDir = 'froot-app';
107
+ }
108
+ else {
109
+ printStep(1, 4, 'Project location');
110
+ targetDir = await promptText('Where would you like to create your project?', 'my-froot-app', (input) => {
111
+ if (!input.trim())
112
+ return 'Project name cannot be empty';
113
+ return true;
114
+ });
115
+ console.log();
116
+ }
117
+ }
118
+ const resolvedTarget = path.resolve(process.cwd(), targetDir);
119
+ const projectName = path.basename(resolvedTarget);
120
+ // Verify if directory already exists with files
121
+ if (fs.existsSync(resolvedTarget)) {
122
+ const existingFiles = fs.readdirSync(resolvedTarget);
123
+ if (existingFiles.length > 0 && !args.yes) {
124
+ printStep(1, 4, 'Target directory warning');
125
+ const proceed = await promptConfirm(`Target directory "${targetDir}" is not empty. Continue anyway?`, false);
126
+ console.log();
127
+ if (!proceed) {
128
+ printError('Aborted by user.');
129
+ process.exit(1);
130
+ }
131
+ }
132
+ }
133
+ // 2. Select Template
134
+ let selectedTemplate = args.template ? getTemplate(args.template) : undefined;
135
+ if (args.template && !selectedTemplate) {
136
+ printError(`Unknown template "${args.template}".`);
137
+ console.log(`Available templates: ${Object.keys(TEMPLATES).join(', ')}`);
138
+ process.exit(1);
139
+ }
140
+ if (!selectedTemplate) {
141
+ if (args.yes) {
142
+ selectedTemplate = TEMPLATES['mvc'];
143
+ }
144
+ else {
145
+ printStep(2, 4, 'Choose architectural template');
146
+ const choice = await promptSelect('Select the project template that fits your architecture:', TEMPLATE_LIST.map((t) => ({
147
+ value: t.id,
148
+ label: t.name,
149
+ hint: t.description,
150
+ })));
151
+ selectedTemplate = getTemplate(choice);
152
+ console.log();
153
+ }
154
+ }
155
+ // 3. Package Manager Selection
156
+ const detectedPm = detectCurrentPackageManager();
157
+ let pkgManager = args.pkgManager || detectedPm;
158
+ if (!args.pkgManager && !args.yes) {
159
+ printStep(3, 4, 'Package manager');
160
+ pkgManager = await promptSelect('Which package manager do you want to use?', [
161
+ { value: 'pnpm', label: 'pnpm', hint: 'Fast, disk space efficient' },
162
+ { value: 'npm', label: 'npm', hint: 'Standard Node package manager' },
163
+ { value: 'yarn', label: 'yarn', hint: 'Classic or Modern Yarn' },
164
+ { value: 'bun', label: 'bun', hint: 'Ultra-fast all-in-one toolkit' },
165
+ ]);
166
+ console.log();
167
+ }
168
+ // 4. Git Initialization & Install Preferences
169
+ let gitInit = args.git;
170
+ let installDeps = args.install;
171
+ if (!args.yes) {
172
+ printStep(4, 4, 'Project setup preferences');
173
+ if (gitInit === undefined) {
174
+ gitInit = await promptConfirm('Initialize a new git repository?', true);
175
+ }
176
+ if (installDeps === undefined) {
177
+ installDeps = await promptConfirm(`Install dependencies now with ${pkgManager}?`, true);
178
+ }
179
+ console.log();
180
+ }
181
+ else {
182
+ if (gitInit === undefined)
183
+ gitInit = true;
184
+ if (installDeps === undefined)
185
+ installDeps = true;
186
+ }
187
+ // 5. Scaffold Project
188
+ try {
189
+ const result = await scaffoldProject({
190
+ targetDir: resolvedTarget,
191
+ projectName,
192
+ template: selectedTemplate,
193
+ pkgManager,
194
+ gitInit: Boolean(gitInit),
195
+ installDeps: Boolean(installDeps),
196
+ });
197
+ // 6. Print stylized next steps card
198
+ printNextSteps({
199
+ projectDir: targetDir,
200
+ pkgManager,
201
+ hasInstalled: result.depsInstalled,
202
+ port: 3000,
203
+ });
204
+ }
205
+ catch (err) {
206
+ const msg = err instanceof Error ? err.message : String(err);
207
+ printError(`Scaffolding failed: ${msg}`);
208
+ process.exit(1);
209
+ }
210
+ }
211
+ main().catch((err) => {
212
+ printError(String(err));
213
+ process.exit(1);
214
+ });
215
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Fullstack JSX & Server-Side Rendering (SSR) Template
3
+ * Native JSX components rendered on the server with zero client JavaScript overhead.
4
+ */
5
+ import { TemplateDefinition } from './types.js';
6
+ export declare const fullstackTemplate: TemplateDefinition;
7
+ //# sourceMappingURL=fullstack.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullstack.d.ts","sourceRoot":"","sources":["../../src/templates/fullstack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,kBAAkB,EAAsD,MAAM,YAAY,CAAC;AAEpG,eAAO,MAAM,iBAAiB,EAAE,kBAoO/B,CAAC"}
@@ -0,0 +1,224 @@
1
+ /**
2
+ * Fullstack JSX & Server-Side Rendering (SSR) Template
3
+ * Native JSX components rendered on the server with zero client JavaScript overhead.
4
+ */
5
+ import { COMMON_GITIGNORE, COMMON_TSCONFIG } from './types.js';
6
+ export const fullstackTemplate = {
7
+ id: 'fullstack',
8
+ name: 'Fullstack JSX & Server-Side Rendering',
9
+ description: 'Native JSX components, typed layouts, and zero-JS HTML server rendering',
10
+ generate: (projectName) => {
11
+ return {
12
+ 'package.json': JSON.stringify({
13
+ name: projectName,
14
+ version: '1.0.0',
15
+ type: 'module',
16
+ scripts: {
17
+ dev: 'node --experimental-strip-types src/server.tsx',
18
+ build: 'tsc',
19
+ start: 'node dist/server.js',
20
+ },
21
+ dependencies: {
22
+ frootjs: '^1.0.1',
23
+ },
24
+ devDependencies: {
25
+ '@types/node': '^22.10.0',
26
+ typescript: '^5.8.0',
27
+ },
28
+ }, null, 2) + '\n',
29
+ 'tsconfig.json': COMMON_TSCONFIG,
30
+ '.gitignore': COMMON_GITIGNORE,
31
+ 'README.md': `# ${projectName}
32
+
33
+ Froot application built with the **Fullstack JSX & Server-Side Rendering (SSR)** pattern.
34
+
35
+ ## Features
36
+
37
+ - **Native JSX / TSX**: Pure server-rendered JSX without React runtime baggage
38
+ - **Layout Middleware**: Automatic HTML wrapper layout with \`jsxRenderer()\`
39
+ - **Zero Client JS**: Ultra-fast initial page loads and 100% SEO-friendly markup
40
+
41
+ ## Getting Started
42
+
43
+ \`\`\`bash
44
+ # 1. Install dependencies
45
+ pnpm install
46
+
47
+ # 2. Run in development mode
48
+ pnpm run dev
49
+
50
+ # 3. View in browser
51
+ http://localhost:3000
52
+ \`\`\`
53
+ `,
54
+ 'src/components/Layout.tsx': `import type { FC, PropsWithChildren } from 'frootjs/jsx';
55
+
56
+ export interface LayoutProps {
57
+ title?: string;
58
+ }
59
+
60
+ export const Layout: FC<PropsWithChildren<LayoutProps>> = ({ title = 'Froot JSX App', children }) => {
61
+ return (
62
+ <html lang="en">
63
+ <head>
64
+ <meta charSet="UTF-8" />
65
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
+ <title>{title}</title>
67
+ <style>{\`
68
+ * { box-sizing: border-box; margin: 0; padding: 0; }
69
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #0f172a; color: #f8fafc; line-height: 1.6; }
70
+ header { background: #1e293b; border-bottom: 1px solid #334155; padding: 1rem 2rem; display: flex; justify-content: space-between; align-items: center; }
71
+ .logo { font-size: 1.3rem; font-weight: bold; color: #10b981; text-decoration: none; }
72
+ nav a { color: #94a3b8; text-decoration: none; margin-left: 1.5rem; font-weight: 500; }
73
+ nav a:hover { color: #f8fafc; }
74
+ main { max-width: 900px; margin: 2rem auto; padding: 0 1.5rem; }
75
+ footer { text-align: center; padding: 2rem; color: #64748b; font-size: 0.9rem; border-top: 1px solid #1e293b; margin-top: 4rem; }
76
+ \`}</style>
77
+ </head>
78
+ <body>
79
+ <header>
80
+ <a href="/" className="logo">Froot JSX</a>
81
+ <nav>
82
+ <a href="/">Home</a>
83
+ <a href="/about">About</a>
84
+ <a href="/features">Features</a>
85
+ </nav>
86
+ </header>
87
+ <main>{children}</main>
88
+ <footer>
89
+ <p>Powered by Froot Server-Side Rendering Engine</p>
90
+ </footer>
91
+ </body>
92
+ </html>
93
+ );
94
+ };
95
+ `,
96
+ 'src/components/Card.tsx': `import type { FC, PropsWithChildren } from 'frootjs/jsx';
97
+
98
+ export interface CardProps {
99
+ title: string;
100
+ badge?: string;
101
+ }
102
+
103
+ export const Card: FC<PropsWithChildren<CardProps>> = ({ title, badge, children }) => {
104
+ return (
105
+ <div style={{
106
+ background: '#1e293b',
107
+ border: '1px solid #334155',
108
+ borderRadius: '8px',
109
+ padding: '1.5rem',
110
+ marginBottom: '1.25rem',
111
+ }}>
112
+ <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '0.75rem' }}>
113
+ <h3 style={{ color: '#38bdf8', fontSize: '1.2rem' }}>{title}</h3>
114
+ {badge ? (
115
+ <span style={{
116
+ background: '#064e3b',
117
+ color: '#34d399',
118
+ fontSize: '0.75rem',
119
+ padding: '0.2rem 0.6rem',
120
+ borderRadius: '9999px',
121
+ fontWeight: 600,
122
+ }}>
123
+ {badge}
124
+ </span>
125
+ ) : null}
126
+ </div>
127
+ <div>{children}</div>
128
+ </div>
129
+ );
130
+ };
131
+ `,
132
+ 'src/pages/Home.tsx': `import type { FC } from 'frootjs/jsx';
133
+ import { Card } from '../components/Card.js';
134
+
135
+ export const HomePage: FC = () => {
136
+ return (
137
+ <div>
138
+ <div style={{ marginBottom: '2rem' }}>
139
+ <h1 style={{ fontSize: '2.25rem', color: '#10b981', marginBottom: '0.5rem' }}>
140
+ Server-Side Rendered JSX
141
+ </h1>
142
+ <p style={{ color: '#94a3b8', fontSize: '1.1rem' }}>
143
+ Blazing fast HTML generated on the server with TypeScript-native JSX components.
144
+ </p>
145
+ </div>
146
+
147
+ <Card title="Zero Client Runtime" badge="Performance">
148
+ <p>No heavy virtual DOM diffing in the browser. Pure, pre-rendered semantic HTML delivered instantly.</p>
149
+ </Card>
150
+
151
+ <Card title="Type-Safe Views" badge="DX">
152
+ <p>Full TypeScript compiler checking for props, children, styles, and HTML attributes.</p>
153
+ </Card>
154
+
155
+ <Card title="Streaming & Islands Ready" badge="Architecture">
156
+ <p>Seamlessly compose asynchronous server components and stream output as it becomes available.</p>
157
+ </Card>
158
+ </div>
159
+ );
160
+ };
161
+ `,
162
+ 'src/pages/About.tsx': `import type { FC } from 'frootjs/jsx';
163
+
164
+ export const AboutPage: FC = () => {
165
+ return (
166
+ <div style={{ background: '#1e293b', padding: '2rem', borderRadius: '8px', border: '1px solid #334155' }}>
167
+ <h1 style={{ color: '#10b981', marginBottom: '1rem' }}>About This Application</h1>
168
+ <p style={{ marginBottom: '1rem' }}>
169
+ This project showcases Froot's built-in JSX rendering pipeline. Unlike traditional React or Next.js setups,
170
+ Froot renders JSX straight to HTML strings without requiring React, ReactDOM, or a Node.js bundling step.
171
+ </p>
172
+ <p style={{ color: '#94a3b8' }}>
173
+ It achieves sub-millisecond page render times while maintaining full component composition.
174
+ </p>
175
+ </div>
176
+ );
177
+ };
178
+ `,
179
+ 'src/server.tsx': `import { Froot } from 'frootjs';
180
+ import { jsxRenderer } from 'frootjs/jsx';
181
+ import { Layout } from './components/Layout.js';
182
+ import { HomePage } from './pages/Home.js';
183
+ import { AboutPage } from './pages/About.js';
184
+
185
+ export const app = new Froot();
186
+
187
+ // Wrap all HTML responses in the global Layout shell
188
+ app.use('*', jsxRenderer(({ children }) => {
189
+ return <Layout>{children}</Layout>;
190
+ }));
191
+
192
+ // Route handlers
193
+ app.get('/', (c) => {
194
+ return c.render(<HomePage />);
195
+ });
196
+
197
+ app.get('/about', (c) => {
198
+ return c.render(<AboutPage />);
199
+ });
200
+
201
+ app.get('/features', (c) => {
202
+ return c.render(
203
+ <div>
204
+ <h1 style={{ color: '#10b981', marginBottom: '1rem' }}>Framework Features</h1>
205
+ <ul style={{ paddingLeft: '1.5rem', color: '#cbd5e1' }}>
206
+ <li>RADIX tree router with O(K) lookup</li>
207
+ <li>Auto-generated OpenAPI 3.1 & Scalar docs</li>
208
+ <li>Native JSX & async component support</li>
209
+ <li>Full WebCrypto authentication ecosystem</li>
210
+ <li>Universal WebSockets & pub/sub hub</li>
211
+ </ul>
212
+ </div>
213
+ );
214
+ });
215
+
216
+ const PORT = Number(process.env.PORT) || 3000;
217
+ app.listen(PORT, () => {
218
+ console.log(\`Fullstack JSX server running on http://localhost:\${PORT}\`);
219
+ });
220
+ `,
221
+ };
222
+ },
223
+ };
224
+ //# sourceMappingURL=fullstack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fullstack.js","sourceRoot":"","sources":["../../src/templates/fullstack.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAuC,gBAAgB,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAEpG,MAAM,CAAC,MAAM,iBAAiB,GAAuB;IACnD,EAAE,EAAE,WAAW;IACf,IAAI,EAAE,uCAAuC;IAC7C,WAAW,EAAE,yEAAyE;IACtF,QAAQ,EAAE,CAAC,WAAmB,EAAmB,EAAE;QACjD,OAAO;YACL,cAAc,EAAE,IAAI,CAAC,SAAS,CAC5B;gBACE,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,OAAO;gBAChB,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE;oBACP,GAAG,EAAE,gDAAgD;oBACrD,KAAK,EAAE,KAAK;oBACZ,KAAK,EAAE,qBAAqB;iBAC7B;gBACD,YAAY,EAAE;oBACZ,OAAO,EAAE,QAAQ;iBAClB;gBACD,eAAe,EAAE;oBACf,aAAa,EAAE,UAAU;oBACzB,UAAU,EAAE,QAAQ;iBACrB;aACF,EACD,IAAI,EACJ,CAAC,CACF,GAAG,IAAI;YAER,eAAe,EAAE,eAAe;YAChC,YAAY,EAAE,gBAAgB;YAE9B,WAAW,EAAE,KAAK,WAAW;;;;;;;;;;;;;;;;;;;;;;CAsBlC;YAEK,2BAA2B,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyClC;YAEK,yBAAyB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmChC;YAEK,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B3B;YAEK,qBAAqB,EAAE;;;;;;;;;;;;;;;;CAgB5B;YAEK,gBAAgB,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAyCvB;SACI,CAAC;IACJ,CAAC;CACF,CAAC"}