zylaris 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.
- package/LICENSE +21 -0
- package/README.md +558 -0
- package/Zylaris.js.png +0 -0
- package/examples/default/index.html +13 -0
- package/examples/default/package.json +23 -0
- package/examples/default/src/app/about/page.tsx +18 -0
- package/examples/default/src/app/counter/page.tsx +22 -0
- package/examples/default/src/app/global.css +225 -0
- package/examples/default/src/app/layout.tsx +33 -0
- package/examples/default/src/app/page.tsx +14 -0
- package/examples/default/src/entry-client.tsx +87 -0
- package/examples/default/src/entry-server.tsx +52 -0
- package/examples/default/src/router.ts +60 -0
- package/examples/default/tsconfig.json +28 -0
- package/examples/default/zylaris.config.ts +24 -0
- package/package.json +34 -0
- package/packages/adapter/package.json +59 -0
- package/packages/adapter/src/adapters/bun.ts +215 -0
- package/packages/adapter/src/adapters/cloudflare.ts +278 -0
- package/packages/adapter/src/adapters/deno.ts +219 -0
- package/packages/adapter/src/adapters/netlify.ts +274 -0
- package/packages/adapter/src/adapters/node.ts +155 -0
- package/packages/adapter/src/adapters/static.ts +134 -0
- package/packages/adapter/src/adapters/vercel.ts +239 -0
- package/packages/adapter/src/index.ts +115 -0
- package/packages/adapter/src/lib/builder.ts +361 -0
- package/packages/adapter/src/types.ts +191 -0
- package/packages/adapter/tsconfig.json +8 -0
- package/packages/cli/package.json +43 -0
- package/packages/cli/src/bin.ts +107 -0
- package/packages/cli/src/commands/build.ts +197 -0
- package/packages/cli/src/commands/create.ts +222 -0
- package/packages/cli/src/commands/deploy.ts +90 -0
- package/packages/cli/src/commands/dev.ts +108 -0
- package/packages/cli/src/index.ts +6 -0
- package/packages/cli/tsconfig.json +9 -0
- package/packages/compiler/package.json +39 -0
- package/packages/compiler/src/index.ts +210 -0
- package/packages/compiler/src/jit.ts +187 -0
- package/packages/compiler/tsconfig.json +9 -0
- package/packages/core/package.json +55 -0
- package/packages/core/src/components.test.ts +125 -0
- package/packages/core/src/components.ts +181 -0
- package/packages/core/src/config.ts +204 -0
- package/packages/core/src/hooks.ts +142 -0
- package/packages/core/src/index.ts +59 -0
- package/packages/core/src/jsx-runtime.ts +46 -0
- package/packages/core/tsconfig.json +16 -0
- package/packages/dev-server/package.json +51 -0
- package/packages/dev-server/src/index.ts +306 -0
- package/packages/dev-server/src/jit-middleware.ts +78 -0
- package/packages/dev-server/tsconfig.json +9 -0
- package/packages/plugins/package.json +44 -0
- package/packages/plugins/src/cdn/loader.ts +275 -0
- package/packages/plugins/src/index.ts +238 -0
- package/packages/plugins/src/loaders/auto-import.ts +219 -0
- package/packages/plugins/src/loaders/external.ts +332 -0
- package/packages/plugins/src/transforms/index.ts +407 -0
- package/packages/plugins/src/types.ts +296 -0
- package/packages/plugins/tsconfig.json +8 -0
- package/packages/reactivity/package.json +36 -0
- package/packages/reactivity/src/computed.d.ts +3 -0
- package/packages/reactivity/src/computed.d.ts.map +1 -0
- package/packages/reactivity/src/computed.js +64 -0
- package/packages/reactivity/src/computed.js.map +1 -0
- package/packages/reactivity/src/computed.test.ts +83 -0
- package/packages/reactivity/src/computed.ts +69 -0
- package/packages/reactivity/src/index.d.ts +6 -0
- package/packages/reactivity/src/index.d.ts.map +1 -0
- package/packages/reactivity/src/index.js +7 -0
- package/packages/reactivity/src/index.js.map +1 -0
- package/packages/reactivity/src/index.ts +18 -0
- package/packages/reactivity/src/resource.d.ts +6 -0
- package/packages/reactivity/src/resource.d.ts.map +1 -0
- package/packages/reactivity/src/resource.js +43 -0
- package/packages/reactivity/src/resource.js.map +1 -0
- package/packages/reactivity/src/resource.test.ts +70 -0
- package/packages/reactivity/src/resource.ts +59 -0
- package/packages/reactivity/src/signal.d.ts +7 -0
- package/packages/reactivity/src/signal.d.ts.map +1 -0
- package/packages/reactivity/src/signal.js +145 -0
- package/packages/reactivity/src/signal.js.map +1 -0
- package/packages/reactivity/src/signal.test.ts +130 -0
- package/packages/reactivity/src/signal.ts +207 -0
- package/packages/reactivity/src/store.d.ts +4 -0
- package/packages/reactivity/src/store.d.ts.map +1 -0
- package/packages/reactivity/src/store.js +62 -0
- package/packages/reactivity/src/store.js.map +1 -0
- package/packages/reactivity/src/store.test.ts +38 -0
- package/packages/reactivity/src/store.ts +111 -0
- package/packages/reactivity/src/types.d.ts +43 -0
- package/packages/reactivity/src/types.d.ts.map +1 -0
- package/packages/reactivity/src/types.js +3 -0
- package/packages/reactivity/src/types.js.map +1 -0
- package/packages/reactivity/src/types.ts +43 -0
- package/packages/reactivity/tsconfig.json +9 -0
- package/packages/router/package.json +44 -0
- package/packages/router/src/components.tsx +150 -0
- package/packages/router/src/fs-router.ts +163 -0
- package/packages/router/src/index.ts +22 -0
- package/packages/router/src/router.test.ts +111 -0
- package/packages/router/src/router.ts +112 -0
- package/packages/router/src/types.ts +69 -0
- package/packages/router/tsconfig.json +10 -0
- package/packages/server/package.json +41 -0
- package/packages/server/src/action.test.ts +102 -0
- package/packages/server/src/action.ts +201 -0
- package/packages/server/src/api.ts +143 -0
- package/packages/server/src/index.ts +18 -0
- package/packages/server/src/types.ts +72 -0
- package/packages/server/tsconfig.json +9 -0
- package/pnpm-workspace.yaml +4 -0
- package/scripts/publish.ps1 +138 -0
- package/scripts/publish.sh +142 -0
- package/tsconfig.json +28 -0
- package/turbo.json +24 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { resolve, join } from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
import inquirer from 'inquirer';
|
|
6
|
+
|
|
7
|
+
const TEMPLATES = ['default', 'api', 'docs', 'blog', 'ecommerce'];
|
|
8
|
+
|
|
9
|
+
interface CreateOptions {
|
|
10
|
+
template?: string;
|
|
11
|
+
skipInstall?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function createProject(name: string, options: CreateOptions): Promise<void> {
|
|
15
|
+
const targetDir = resolve(process.cwd(), name);
|
|
16
|
+
|
|
17
|
+
// Check if directory exists
|
|
18
|
+
if (await fs.pathExists(targetDir)) {
|
|
19
|
+
const { overwrite } = await inquirer.prompt([{
|
|
20
|
+
type: 'confirm',
|
|
21
|
+
name: 'overwrite',
|
|
22
|
+
message: `Directory ${name} already exists. Overwrite?`,
|
|
23
|
+
default: false,
|
|
24
|
+
}]);
|
|
25
|
+
|
|
26
|
+
if (!overwrite) {
|
|
27
|
+
console.log(chalk.yellow('Cancelled.'));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
await fs.remove(targetDir);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Validate template
|
|
35
|
+
let template = options.template || 'default';
|
|
36
|
+
if (!TEMPLATES.includes(template)) {
|
|
37
|
+
const { selectedTemplate } = await inquirer.prompt([{
|
|
38
|
+
type: 'list',
|
|
39
|
+
name: 'selectedTemplate',
|
|
40
|
+
message: 'Select a template:',
|
|
41
|
+
choices: TEMPLATES,
|
|
42
|
+
}]);
|
|
43
|
+
template = selectedTemplate;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const spinner = ora('Creating project...').start();
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
// Create directory structure
|
|
50
|
+
await fs.ensureDir(targetDir);
|
|
51
|
+
|
|
52
|
+
// Create package.json
|
|
53
|
+
await createPackageJson(targetDir, name, template);
|
|
54
|
+
|
|
55
|
+
// Create tsconfig.json
|
|
56
|
+
await createTsConfig(targetDir);
|
|
57
|
+
|
|
58
|
+
// Create zylaris.config.ts
|
|
59
|
+
await createConfig(targetDir, template);
|
|
60
|
+
|
|
61
|
+
// Create source files
|
|
62
|
+
await createSourceFiles(targetDir, template);
|
|
63
|
+
|
|
64
|
+
// Create public folder
|
|
65
|
+
await fs.ensureDir(join(targetDir, 'public'));
|
|
66
|
+
|
|
67
|
+
// Install dependencies
|
|
68
|
+
if (!options.skipInstall) {
|
|
69
|
+
spinner.text = 'Installing dependencies...';
|
|
70
|
+
// In real implementation, run npm/pnpm install
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
spinner.succeed(chalk.green(`Project ${name} created successfully!`));
|
|
74
|
+
|
|
75
|
+
console.log('\nNext steps:');
|
|
76
|
+
console.log(chalk.cyan(` cd ${name}`));
|
|
77
|
+
console.log(chalk.cyan(' npm run dev'));
|
|
78
|
+
} catch (error) {
|
|
79
|
+
spinner.fail(chalk.red('Failed to create project'));
|
|
80
|
+
console.error(error);
|
|
81
|
+
process.exit(1);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async function createPackageJson(targetDir: string, name: string, _template: string): Promise<void> {
|
|
86
|
+
const packageJson = {
|
|
87
|
+
name,
|
|
88
|
+
version: '0.1.0',
|
|
89
|
+
private: true,
|
|
90
|
+
type: 'module',
|
|
91
|
+
scripts: {
|
|
92
|
+
dev: 'zylaris dev',
|
|
93
|
+
build: 'zylaris build',
|
|
94
|
+
start: 'node .zylaris/server.js',
|
|
95
|
+
test: 'zylaris test',
|
|
96
|
+
lint: 'zylaris lint',
|
|
97
|
+
typecheck: 'zylaris typecheck',
|
|
98
|
+
},
|
|
99
|
+
dependencies: {
|
|
100
|
+
zylaris: '^1.0.0',
|
|
101
|
+
react: '^18.2.0',
|
|
102
|
+
'react-dom': '^18.2.0',
|
|
103
|
+
},
|
|
104
|
+
devDependencies: {
|
|
105
|
+
'@types/react': '^18.2.0',
|
|
106
|
+
'@types/react-dom': '^18.2.0',
|
|
107
|
+
typescript: '^5.3.3',
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
|
|
111
|
+
await fs.writeJson(join(targetDir, 'package.json'), packageJson, { spaces: 2 });
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async function createTsConfig(targetDir: string): Promise<void> {
|
|
115
|
+
const tsConfig = {
|
|
116
|
+
compilerOptions: {
|
|
117
|
+
target: 'ES2022',
|
|
118
|
+
lib: ['ES2022', 'DOM', 'DOM.Iterable'],
|
|
119
|
+
module: 'ESNext',
|
|
120
|
+
moduleResolution: 'bundler',
|
|
121
|
+
resolveJsonModule: true,
|
|
122
|
+
allowJs: true,
|
|
123
|
+
checkJs: false,
|
|
124
|
+
declaration: true,
|
|
125
|
+
sourceMap: true,
|
|
126
|
+
strict: true,
|
|
127
|
+
noUnusedLocals: true,
|
|
128
|
+
noUnusedParameters: true,
|
|
129
|
+
noFallthroughCasesInSwitch: true,
|
|
130
|
+
esModuleInterop: true,
|
|
131
|
+
skipLibCheck: true,
|
|
132
|
+
forceConsistentCasingInFileNames: true,
|
|
133
|
+
jsx: 'react-jsx',
|
|
134
|
+
jsxImportSource: 'zylaris',
|
|
135
|
+
baseUrl: '.',
|
|
136
|
+
paths: {
|
|
137
|
+
'@/*': ['./src/*'],
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
include: ['src/**/*'],
|
|
141
|
+
exclude: ['node_modules', 'dist', '.zylaris'],
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
await fs.writeJson(join(targetDir, 'tsconfig.json'), tsConfig, { spaces: 2 });
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async function createConfig(targetDir: string, _template: string): Promise<void> {
|
|
148
|
+
const config = `import { defineConfig } from 'zylaris';
|
|
149
|
+
|
|
150
|
+
export default defineConfig({
|
|
151
|
+
runtime: 'node',
|
|
152
|
+
rendering: {
|
|
153
|
+
default: 'ssr',
|
|
154
|
+
},
|
|
155
|
+
islands: {
|
|
156
|
+
mode: 'auto',
|
|
157
|
+
},
|
|
158
|
+
compiler: {
|
|
159
|
+
target: 'es2022',
|
|
160
|
+
minify: true,
|
|
161
|
+
},
|
|
162
|
+
server: {
|
|
163
|
+
port: 3000,
|
|
164
|
+
},
|
|
165
|
+
styling: {
|
|
166
|
+
tailwind: true,
|
|
167
|
+
},
|
|
168
|
+
typescript: {
|
|
169
|
+
strict: true,
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
`;
|
|
173
|
+
|
|
174
|
+
await fs.writeFile(join(targetDir, 'zylaris.config.ts'), config);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function createSourceFiles(targetDir: string, _template: string): Promise<void> {
|
|
178
|
+
const srcDir = join(targetDir, 'src');
|
|
179
|
+
const appDir = join(srcDir, 'app');
|
|
180
|
+
|
|
181
|
+
await fs.ensureDir(appDir);
|
|
182
|
+
|
|
183
|
+
// Create layout.tsx
|
|
184
|
+
const layout = `export default function RootLayout({
|
|
185
|
+
children,
|
|
186
|
+
}: {
|
|
187
|
+
children: React.ReactNode;
|
|
188
|
+
}) {
|
|
189
|
+
return (
|
|
190
|
+
<html lang="en">
|
|
191
|
+
<body>
|
|
192
|
+
{children}
|
|
193
|
+
</body>
|
|
194
|
+
</html>
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
`;
|
|
198
|
+
await fs.writeFile(join(appDir, 'layout.tsx'), layout);
|
|
199
|
+
|
|
200
|
+
// Create page.tsx
|
|
201
|
+
const page = `export default function HomePage() {
|
|
202
|
+
return (
|
|
203
|
+
<main>
|
|
204
|
+
<h1>Welcome to Zylaris!</h1>
|
|
205
|
+
<p>Get started by editing src/app/page.tsx</p>
|
|
206
|
+
</main>
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
`;
|
|
210
|
+
await fs.writeFile(join(appDir, 'page.tsx'), page);
|
|
211
|
+
|
|
212
|
+
// Create global.css
|
|
213
|
+
const globalCss = `@tailwind base;
|
|
214
|
+
@tailwind components;
|
|
215
|
+
@tailwind utilities;
|
|
216
|
+
|
|
217
|
+
body {
|
|
218
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
219
|
+
}
|
|
220
|
+
`;
|
|
221
|
+
await fs.writeFile(join(appDir, 'global.css'), globalCss);
|
|
222
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { resolve } from 'path';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import ora from 'ora';
|
|
5
|
+
// import { execa } from 'execa';
|
|
6
|
+
async function execa(_cmd: string, _args: string[], _options: { cwd?: string; stdio?: string }): Promise<unknown> {
|
|
7
|
+
throw new Error('execa not implemented');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface DeployOptions {
|
|
11
|
+
vercel?: boolean;
|
|
12
|
+
netlify?: boolean;
|
|
13
|
+
cloudflare?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export async function deployProject(options: DeployOptions): Promise<void> {
|
|
17
|
+
const spinner = ora('Deploying...').start();
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const cwd = process.cwd();
|
|
21
|
+
|
|
22
|
+
// Check if build exists
|
|
23
|
+
const distPath = resolve(cwd, 'dist');
|
|
24
|
+
if (!(await fs.pathExists(distPath))) {
|
|
25
|
+
spinner.text = 'Building first...';
|
|
26
|
+
// await buildProject({});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (options.vercel) {
|
|
30
|
+
spinner.text = 'Deploying to Vercel...';
|
|
31
|
+
await deployToVercel(cwd);
|
|
32
|
+
} else if (options.netlify) {
|
|
33
|
+
spinner.text = 'Deploying to Netlify...';
|
|
34
|
+
await deployToNetlify(cwd);
|
|
35
|
+
} else if (options.cloudflare) {
|
|
36
|
+
spinner.text = 'Deploying to Cloudflare Pages...';
|
|
37
|
+
await deployToCloudflare(cwd);
|
|
38
|
+
} else {
|
|
39
|
+
// Default: Zylaris Cloud
|
|
40
|
+
spinner.text = 'Deploying to Zylaris Cloud...';
|
|
41
|
+
await deployToZylarisCloud(cwd);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
spinner.succeed(chalk.green('Deployment complete!'));
|
|
45
|
+
} catch (error) {
|
|
46
|
+
spinner.fail(chalk.red('Deployment failed'));
|
|
47
|
+
console.error(error);
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async function deployToVercel(cwd: string): Promise<void> {
|
|
53
|
+
// Check if vercel CLI is installed
|
|
54
|
+
try {
|
|
55
|
+
await execa('vercel', ['--version'], { cwd });
|
|
56
|
+
} catch {
|
|
57
|
+
console.log(chalk.yellow('Vercel CLI not found. Installing...'));
|
|
58
|
+
await execa('npm', ['install', '-g', 'vercel'], { cwd });
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
await execa('vercel', ['--prod'], { cwd, stdio: 'inherit' });
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async function deployToNetlify(cwd: string): Promise<void> {
|
|
65
|
+
try {
|
|
66
|
+
await execa('netlify', ['--version'], { cwd });
|
|
67
|
+
} catch {
|
|
68
|
+
console.log(chalk.yellow('Netlify CLI not found. Installing...'));
|
|
69
|
+
await execa('npm', ['install', '-g', 'netlify-cli'], { cwd });
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
await execa('netlify', ['deploy', '--prod', '--dir=dist'], { cwd, stdio: 'inherit' });
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
async function deployToCloudflare(cwd: string): Promise<void> {
|
|
76
|
+
try {
|
|
77
|
+
await execa('wrangler', ['--version'], { cwd });
|
|
78
|
+
} catch {
|
|
79
|
+
console.log(chalk.yellow('Wrangler not found. Installing...'));
|
|
80
|
+
await execa('npm', ['install', '-g', 'wrangler'], { cwd });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
await execa('wrangler', ['pages', 'deploy', 'dist'], { cwd, stdio: 'inherit' });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async function deployToZylarisCloud(_cwd: string): Promise<void> {
|
|
87
|
+
// In real implementation, deploy to Zylaris Cloud
|
|
88
|
+
console.log(chalk.blue('Deploying to Zylaris Cloud...'));
|
|
89
|
+
console.log(chalk.yellow('Coming soon!'));
|
|
90
|
+
}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { createServer } from '@zylaris/dev-server';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import net from 'net';
|
|
4
|
+
|
|
5
|
+
interface DevOptions {
|
|
6
|
+
port?: string;
|
|
7
|
+
host?: string;
|
|
8
|
+
turbo?: boolean;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// Check if port is available
|
|
12
|
+
function isPortAvailable(port: number, host: string): Promise<boolean> {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
const server = net.createServer();
|
|
15
|
+
server.once('error', () => {
|
|
16
|
+
resolve(false);
|
|
17
|
+
});
|
|
18
|
+
server.once('listening', () => {
|
|
19
|
+
server.close();
|
|
20
|
+
resolve(true);
|
|
21
|
+
});
|
|
22
|
+
server.listen(port, host);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Find available port starting from preferred port
|
|
27
|
+
async function findAvailablePort(preferredPort: number, host: string): Promise<number> {
|
|
28
|
+
let port = preferredPort;
|
|
29
|
+
while (port < preferredPort + 10) {
|
|
30
|
+
if (await isPortAvailable(port, host)) {
|
|
31
|
+
return port;
|
|
32
|
+
}
|
|
33
|
+
port++;
|
|
34
|
+
}
|
|
35
|
+
throw new Error(`No available port found between ${preferredPort} and ${preferredPort + 10}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Print banner
|
|
39
|
+
function printBanner(port: number, host: string, wsPort: number) {
|
|
40
|
+
const box = `
|
|
41
|
+
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
|
|
42
|
+
┃ ┃
|
|
43
|
+
┃ 🚀 ${chalk.bold('Zylaris Dev Server')} ┃
|
|
44
|
+
┃ ┃
|
|
45
|
+
┃ ${chalk.cyan('➜')} Local: ${chalk.cyan(`http://${host}:${port}`)} ┃
|
|
46
|
+
┃ ${chalk.magenta('➜')} WebSocket: ${chalk.magenta(`ws://${host}:${wsPort}`)} ┃
|
|
47
|
+
┃ ┃
|
|
48
|
+
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
|
|
49
|
+
`;
|
|
50
|
+
console.log(box);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export async function devServer(options: DevOptions): Promise<void> {
|
|
54
|
+
const preferredPort = parseInt(options.port || '2727');
|
|
55
|
+
const host = options.host || 'localhost';
|
|
56
|
+
|
|
57
|
+
// Clear console for clean output
|
|
58
|
+
console.clear();
|
|
59
|
+
|
|
60
|
+
console.log(chalk.gray('Starting development server...\n'));
|
|
61
|
+
|
|
62
|
+
try {
|
|
63
|
+
// Find available port
|
|
64
|
+
const port = await findAvailablePort(preferredPort, host);
|
|
65
|
+
|
|
66
|
+
if (port !== preferredPort) {
|
|
67
|
+
console.log(chalk.yellow(`⚠ Port ${preferredPort} is in use, using port ${port} instead\n`));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const server = await createServer({
|
|
71
|
+
port,
|
|
72
|
+
host,
|
|
73
|
+
turbo: options.turbo,
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Print prominent banner
|
|
77
|
+
const wsPort = port + 1;
|
|
78
|
+
printBanner(port, host, wsPort);
|
|
79
|
+
|
|
80
|
+
// Handle graceful shutdown
|
|
81
|
+
const shutdown = () => {
|
|
82
|
+
console.log(chalk.yellow('\n🛑 Shutting down server...'));
|
|
83
|
+
server.close(() => {
|
|
84
|
+
console.log(chalk.green('✓ Server closed'));
|
|
85
|
+
process.exit(0);
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Force exit after 3 seconds
|
|
89
|
+
setTimeout(() => {
|
|
90
|
+
console.log(chalk.red('Force exit after timeout'));
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}, 3000);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
process.on('SIGINT', shutdown);
|
|
96
|
+
process.on('SIGTERM', shutdown);
|
|
97
|
+
|
|
98
|
+
// Handle uncaught errors
|
|
99
|
+
process.on('uncaughtException', (err) => {
|
|
100
|
+
console.error(chalk.red('\n✗ Uncaught exception:'), err);
|
|
101
|
+
shutdown();
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error(chalk.red('\n✗ Failed to start dev server:'), error);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@zylaris/compiler",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Compiler for Zylaris Framework",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsc",
|
|
20
|
+
"dev": "tsc --watch",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"clean": "rm -rf dist"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@swc/core": "^1.3.100",
|
|
26
|
+
"@swc/helpers": "^0.5.3",
|
|
27
|
+
"esbuild": "^0.19.8"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "^20.0.0",
|
|
31
|
+
"typescript": "^5.3.3"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"compiler",
|
|
35
|
+
"transform",
|
|
36
|
+
"zylaris"
|
|
37
|
+
],
|
|
38
|
+
"license": "MIT"
|
|
39
|
+
}
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
// Zylaris Compiler
|
|
2
|
+
// Transforms JSX and TypeScript for production
|
|
3
|
+
|
|
4
|
+
import { transform as swcTransform } from '@swc/core';
|
|
5
|
+
import * as esbuild from 'esbuild';
|
|
6
|
+
import path from 'path';
|
|
7
|
+
|
|
8
|
+
export interface CompileOptions {
|
|
9
|
+
target?: 'es2020' | 'es2022' | 'esnext';
|
|
10
|
+
minify?: boolean;
|
|
11
|
+
sourceMap?: boolean;
|
|
12
|
+
jsx?: {
|
|
13
|
+
runtime?: 'automatic' | 'classic';
|
|
14
|
+
importSource?: string;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface CompileResult {
|
|
19
|
+
code: string;
|
|
20
|
+
map?: string;
|
|
21
|
+
errors: CompileError[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface CompileError {
|
|
25
|
+
message: string;
|
|
26
|
+
location?: {
|
|
27
|
+
line: number;
|
|
28
|
+
column: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export async function compile(
|
|
33
|
+
source: string,
|
|
34
|
+
filename: string,
|
|
35
|
+
options: CompileOptions = {}
|
|
36
|
+
): Promise<CompileResult> {
|
|
37
|
+
const ext = path.extname(filename);
|
|
38
|
+
|
|
39
|
+
if (ext === '.tsx' || ext === '.jsx') {
|
|
40
|
+
return compileJSX(source, filename, options);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (ext === '.ts') {
|
|
44
|
+
return compileTypeScript(source, filename, options);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
code: source,
|
|
49
|
+
errors: [],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function compileJSX(
|
|
54
|
+
source: string,
|
|
55
|
+
filename: string,
|
|
56
|
+
options: CompileOptions
|
|
57
|
+
): Promise<CompileResult> {
|
|
58
|
+
try {
|
|
59
|
+
const result = await swcTransform(source, {
|
|
60
|
+
filename,
|
|
61
|
+
jsc: {
|
|
62
|
+
parser: {
|
|
63
|
+
syntax: 'typescript',
|
|
64
|
+
tsx: true,
|
|
65
|
+
},
|
|
66
|
+
transform: {
|
|
67
|
+
react: {
|
|
68
|
+
runtime: options.jsx?.runtime || 'automatic',
|
|
69
|
+
importSource: options.jsx?.importSource || 'zylaris',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
target: options.target || 'es2022',
|
|
73
|
+
minify: {
|
|
74
|
+
compress: options.minify,
|
|
75
|
+
mangle: options.minify,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
sourceMaps: options.sourceMap,
|
|
79
|
+
minify: options.minify,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
code: result.code,
|
|
84
|
+
map: result.map,
|
|
85
|
+
errors: [],
|
|
86
|
+
};
|
|
87
|
+
} catch (error) {
|
|
88
|
+
return {
|
|
89
|
+
code: '',
|
|
90
|
+
errors: [
|
|
91
|
+
{
|
|
92
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
async function compileTypeScript(
|
|
100
|
+
source: string,
|
|
101
|
+
filename: string,
|
|
102
|
+
options: CompileOptions
|
|
103
|
+
): Promise<CompileResult> {
|
|
104
|
+
try {
|
|
105
|
+
const result = await swcTransform(source, {
|
|
106
|
+
filename,
|
|
107
|
+
jsc: {
|
|
108
|
+
parser: {
|
|
109
|
+
syntax: 'typescript',
|
|
110
|
+
},
|
|
111
|
+
target: options.target || 'es2022',
|
|
112
|
+
minify: {
|
|
113
|
+
compress: options.minify,
|
|
114
|
+
mangle: options.minify,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
sourceMaps: options.sourceMap,
|
|
118
|
+
minify: options.minify,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
code: result.code,
|
|
123
|
+
map: result.map,
|
|
124
|
+
errors: [],
|
|
125
|
+
};
|
|
126
|
+
} catch (error) {
|
|
127
|
+
return {
|
|
128
|
+
code: '',
|
|
129
|
+
errors: [
|
|
130
|
+
{
|
|
131
|
+
message: error instanceof Error ? error.message : 'Unknown error',
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Bundle with esbuild
|
|
139
|
+
export async function bundle(
|
|
140
|
+
entryPoints: string[],
|
|
141
|
+
outdir: string,
|
|
142
|
+
options: CompileOptions = {}
|
|
143
|
+
): Promise<void> {
|
|
144
|
+
await esbuild.build({
|
|
145
|
+
entryPoints,
|
|
146
|
+
outdir,
|
|
147
|
+
bundle: true,
|
|
148
|
+
splitting: true,
|
|
149
|
+
format: 'esm',
|
|
150
|
+
target: options.target || 'es2022',
|
|
151
|
+
minify: options.minify,
|
|
152
|
+
sourcemap: options.sourceMap,
|
|
153
|
+
jsx: 'automatic',
|
|
154
|
+
jsxImportSource: options.jsx?.importSource || 'zylaris',
|
|
155
|
+
metafile: true,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Transform JSX for client-side hydration
|
|
160
|
+
export async function transformJSXForClient(
|
|
161
|
+
source: string,
|
|
162
|
+
filename: string
|
|
163
|
+
): Promise<string> {
|
|
164
|
+
const result = await swcTransform(source, {
|
|
165
|
+
filename,
|
|
166
|
+
jsc: {
|
|
167
|
+
parser: {
|
|
168
|
+
syntax: 'typescript',
|
|
169
|
+
tsx: true,
|
|
170
|
+
},
|
|
171
|
+
transform: {
|
|
172
|
+
react: {
|
|
173
|
+
runtime: 'automatic',
|
|
174
|
+
importSource: 'zylaris',
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
target: 'es2022',
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
return result.code;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Export JIT compiler for development
|
|
185
|
+
export * from './jit.js';
|
|
186
|
+
|
|
187
|
+
// Transform JSX for server-side rendering
|
|
188
|
+
export async function transformJSXForServer(
|
|
189
|
+
source: string,
|
|
190
|
+
filename: string
|
|
191
|
+
): Promise<string> {
|
|
192
|
+
const result = await swcTransform(source, {
|
|
193
|
+
filename,
|
|
194
|
+
jsc: {
|
|
195
|
+
parser: {
|
|
196
|
+
syntax: 'typescript',
|
|
197
|
+
tsx: true,
|
|
198
|
+
},
|
|
199
|
+
transform: {
|
|
200
|
+
react: {
|
|
201
|
+
runtime: 'automatic',
|
|
202
|
+
importSource: 'zylaris',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
target: 'es2022',
|
|
206
|
+
},
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
return result.code;
|
|
210
|
+
}
|