round-core 0.0.7 → 0.0.9

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 (76) hide show
  1. package/README.md +62 -41
  2. package/dist/index.d.ts +341 -341
  3. package/dist/index.js +211 -192
  4. package/dist/vite-plugin.js +52 -3
  5. package/package.json +7 -4
  6. package/.github/workflows/benchmarks.yml +0 -44
  7. package/Round.png +0 -0
  8. package/benchmarks/apps/react/index.html +0 -9
  9. package/benchmarks/apps/react/main.jsx +0 -25
  10. package/benchmarks/apps/react/vite.config.js +0 -12
  11. package/benchmarks/apps/round/index.html +0 -11
  12. package/benchmarks/apps/round/main.jsx +0 -22
  13. package/benchmarks/apps/round/vite.config.js +0 -15
  14. package/benchmarks/bun.lock +0 -497
  15. package/benchmarks/dist-bench/react/assets/index-9KGqIPOU.js +0 -8
  16. package/benchmarks/dist-bench/react/index.html +0 -10
  17. package/benchmarks/dist-bench/round/assets/index-CBBIRhox.js +0 -52
  18. package/benchmarks/dist-bench/round/index.html +0 -8
  19. package/benchmarks/package.json +0 -22
  20. package/benchmarks/scripts/measure-build.js +0 -64
  21. package/benchmarks/tests/runtime.bench.js +0 -51
  22. package/benchmarks/vitest.config.js +0 -8
  23. package/bun.lock +0 -425
  24. package/cli.js +0 -2
  25. package/extension/.vscodeignore +0 -5
  26. package/extension/LICENSE +0 -21
  27. package/extension/cgmanifest.json +0 -45
  28. package/extension/extension.js +0 -163
  29. package/extension/images/round-config-dark.svg +0 -10
  30. package/extension/images/round-config-light.svg +0 -10
  31. package/extension/images/round-dark.svg +0 -10
  32. package/extension/images/round-light.svg +0 -10
  33. package/extension/javascript-language-configuration.json +0 -241
  34. package/extension/package-lock.json +0 -97
  35. package/extension/package.json +0 -119
  36. package/extension/package.nls.json +0 -4
  37. package/extension/round-0.1.0.vsix +0 -0
  38. package/extension/round-lsp/package-lock.json +0 -185
  39. package/extension/round-lsp/package.json +0 -21
  40. package/extension/round-lsp/src/round-transformer-lsp.js +0 -248
  41. package/extension/round-lsp/src/server.js +0 -396
  42. package/extension/snippets/javascript.code-snippets +0 -266
  43. package/extension/snippets/round.code-snippets +0 -109
  44. package/extension/syntaxes/JavaScript.tmLanguage.json +0 -6001
  45. package/extension/syntaxes/JavaScriptReact.tmLanguage.json +0 -6066
  46. package/extension/syntaxes/Readme.md +0 -12
  47. package/extension/syntaxes/Regular Expressions (JavaScript).tmLanguage +0 -237
  48. package/extension/syntaxes/Round.tmLanguage.json +0 -290
  49. package/extension/syntaxes/RoundInject.tmLanguage.json +0 -20
  50. package/extension/tags-language-configuration.json +0 -152
  51. package/extension/temp_astro/package-lock.json +0 -912
  52. package/extension/temp_astro/package.json +0 -16
  53. package/extension/types/round-core.d.ts +0 -326
  54. package/index.js +0 -2
  55. package/logo.svg +0 -10
  56. package/src/cli.js +0 -608
  57. package/src/compiler/index.js +0 -2
  58. package/src/compiler/transformer.js +0 -443
  59. package/src/compiler/vite-plugin.js +0 -472
  60. package/src/index.d.ts +0 -341
  61. package/src/index.js +0 -45
  62. package/src/runtime/context.js +0 -101
  63. package/src/runtime/dom.js +0 -403
  64. package/src/runtime/error-boundary.js +0 -48
  65. package/src/runtime/error-reporter.js +0 -13
  66. package/src/runtime/error-store.js +0 -85
  67. package/src/runtime/errors.js +0 -152
  68. package/src/runtime/lifecycle.js +0 -142
  69. package/src/runtime/markdown.js +0 -72
  70. package/src/runtime/router.js +0 -468
  71. package/src/runtime/signals.js +0 -548
  72. package/src/runtime/store.js +0 -215
  73. package/src/runtime/suspense.js +0 -128
  74. package/vite.config.build.js +0 -48
  75. package/vite.config.js +0 -10
  76. package/vitest.config.js +0 -8
package/src/cli.js DELETED
@@ -1,608 +0,0 @@
1
-
2
- import path from 'node:path';
3
- import fs from 'node:fs';
4
- import process from 'node:process';
5
- import { fileURLToPath } from 'node:url';
6
- import { createServer, build as viteBuild, preview as vitePreview } from 'vite';
7
- import RoundPlugin from './compiler/vite-plugin.js';
8
-
9
- // Handle graceful shutdown
10
- function onSignal() {
11
- process.exit(0);
12
- }
13
- process.on('SIGINT', onSignal);
14
- process.on('SIGTERM', onSignal);
15
- process.on('exit', () => {
16
- cleanupTemporaryFiles();
17
- });
18
-
19
- const temporaryFiles = new Set();
20
- function cleanupTemporaryFiles() {
21
- for (const f of temporaryFiles) {
22
- try { if (fs.existsSync(f)) fs.unlinkSync(f); } catch { }
23
- }
24
- temporaryFiles.clear();
25
- }
26
-
27
- function normalizePath(p) {
28
- return p.replaceAll('\\', '/');
29
- }
30
-
31
- const colors = {
32
- reset: '\x1b[0m',
33
- dim: '\x1b[2m',
34
- bold: '\x1b[1m',
35
- red: '\x1b[31m',
36
- green: '\x1b[32m',
37
- yellow: '\x1b[33m',
38
- blue: '\x1b[34m',
39
- magenta: '\x1b[35m',
40
- cyan: '\x1b[36m',
41
- gray: '\x1b[90m'
42
- };
43
-
44
- function c(text, color) {
45
- return `${colors[color] ?? ''}${text}${colors.reset}`;
46
- }
47
-
48
- class CliError extends Error {
49
- constructor(message, options = {}) {
50
- super(message);
51
- this.name = 'CliError';
52
- this.code = Number.isFinite(Number(options.code)) ? Number(options.code) : 1;
53
- this.showHelp = Boolean(options.showHelp);
54
- }
55
- }
56
-
57
- function printError(message) {
58
- const msg = String(message ?? '').trimEnd();
59
- if (!msg) return;
60
- process.stderr.write(`${c('Error:', 'red')} ${msg}\n`);
61
- }
62
-
63
- function getRoundVersion() {
64
- try {
65
- const here = path.dirname(fileURLToPath(import.meta.url));
66
- const pkgPath = path.resolve(here, '..', 'package.json');
67
- const raw = fs.readFileSync(pkgPath, 'utf8');
68
- const json = JSON.parse(raw);
69
- return typeof json?.version === 'string' ? json.version : null;
70
- } catch {
71
- return null;
72
- }
73
- }
74
-
75
- function banner(title) {
76
- const v = getRoundVersion();
77
- const name = c('ROUND', 'cyan');
78
- const version = v ? c(`v${v}`, 'gray') : '';
79
- process.stdout.write(`\n ${name} ${version}`.trimEnd() + `\n`);
80
- process.stdout.write(`\n`);
81
- }
82
-
83
- function createViteLogger() {
84
- let hasError = false;
85
- const noop = () => { };
86
- return {
87
- hasErrorLogged: () => hasError,
88
- info(msg) {
89
- const s = String(msg ?? '');
90
- if (!s) return;
91
- if (s.includes('hmr update') || s.includes('page reload') || s.includes('hot updated') || s.includes('modules transformed')) {
92
- process.stdout.write(`${c('[round]', 'cyan')} ${s.replace(/^\[vite\]\s*/i, '')}\n`);
93
- }
94
- },
95
- warn(msg) {
96
- process.stderr.write(String(msg) + '\n');
97
- },
98
- warnOnce(msg) {
99
- process.stderr.write(String(msg) + '\n');
100
- },
101
- clearScreen: noop,
102
- error(msg) {
103
- hasError = true;
104
- const s = String(msg ?? '');
105
- if (s.startsWith('[round] Runtime error')) {
106
- process.stderr.write(`${c(s, 'red')}\n`);
107
- return;
108
- }
109
- if (/^\s*at\s+/.test(s) || s.includes('http://localhost:')) {
110
- process.stderr.write(`${c(s, 'gray')}\n`);
111
- return;
112
- }
113
- process.stderr.write(s + '\n');
114
- }
115
- };
116
- }
117
-
118
- function printUrls(resolvedUrls, base = '/', ms = null) {
119
- const local = resolvedUrls?.local?.[0];
120
- const network = resolvedUrls?.network?.[0];
121
- const label = c('ROUND', 'cyan');
122
- const ready = c('ready', 'green');
123
- const inMs = (typeof ms === 'number') ? `${c('in', 'gray')} ${c(`${ms} ms`, 'gray')}` : '';
124
- process.stdout.write(` ${label} ${ready}${inMs ? ' ' + inMs : ''}\n\n`);
125
- if (local) process.stdout.write(` ${c('➜', 'green')} ${c('Local:', 'green')} ${local}\n`);
126
- if (network) process.stdout.write(` ${c('➜', 'green')} ${c('Network:', 'green')} ${network}\n`);
127
- process.stdout.write(`\n`);
128
- }
129
-
130
- function resolveFrom(baseDir, p) {
131
- if (!p) return null;
132
- if (path.isAbsolute(p)) return p;
133
- return path.resolve(baseDir, p);
134
- }
135
-
136
-
137
- function parseArgs(argv) {
138
- const args = { _: [] };
139
- for (let i = 0; i < argv.length; i++) {
140
- const a = argv[i];
141
- if (!a) continue;
142
- if (a === '--help' || a === '-h') {
143
- args.help = true;
144
- continue;
145
- }
146
- if (a.startsWith('--')) {
147
- const eq = a.indexOf('=');
148
- if (eq !== -1) {
149
- const k = a.slice(2, eq);
150
- const v = a.slice(eq + 1);
151
- args[k] = v;
152
- } else {
153
- const k = a.slice(2);
154
- const next = argv[i + 1];
155
- if (next && !next.startsWith('-')) {
156
- args[k] = next;
157
- i++;
158
- } else {
159
- args[k] = true;
160
- }
161
- }
162
- continue;
163
- }
164
- args._.push(a);
165
- }
166
- return args;
167
- }
168
-
169
- function printHelp() {
170
- const header = `${c('round', 'cyan')} ${c('(CLI)', 'gray')}`;
171
- process.stdout.write(
172
- [
173
- header,
174
- '',
175
- c('Usage', 'bold') + ':',
176
- ` ${c('round', 'cyan')} dev ${c('[--config <path>] [--root <path>]', 'gray')}`,
177
- ` ${c('round', 'cyan')} build ${c('[--config <path>] [--root <path>]', 'gray')}`,
178
- ` ${c('round', 'cyan')} preview ${c('[--config <path>] [--root <path>]', 'gray')}`,
179
- ` ${c('round', 'cyan')} init ${c('<name>', 'yellow')}`,
180
- '',
181
- c('Options', 'bold') + ':',
182
- ` ${c('--config', 'yellow')} ${c('Path to round.config.json', 'gray')} ${c('(default: ./round.config.json)', 'gray')}`,
183
- ` ${c('--root', 'yellow')} ${c('Project root', 'gray')} ${c('(default: process.cwd())', 'gray')}`,
184
- ` ${c('-h, --help', 'yellow')} ${c('Show this help', 'gray')}`,
185
- ''
186
- ].join('\n')
187
- );
188
- }
189
-
190
- function ensureDir(dir) {
191
- if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
192
- }
193
-
194
- function writeFileIfMissing(filePath, content) {
195
- if (fs.existsSync(filePath)) {
196
- throw new Error(`File already exists: ${filePath}`);
197
- }
198
- fs.writeFileSync(filePath, content, 'utf8');
199
- }
200
-
201
- async function runInit({ name }) {
202
- if (!name || typeof name !== 'string') {
203
- throw new CliError(
204
- `Missing project name.\n\nUsage:\n round init <name>`,
205
- { code: 1 }
206
- );
207
- }
208
-
209
- const mode = 'spa';
210
-
211
- const projectDir = path.resolve(process.cwd(), name);
212
- const srcDir = path.join(projectDir, 'src');
213
-
214
- ensureDir(srcDir);
215
-
216
- const pkgPath = path.join(projectDir, 'package.json');
217
- const configPath = path.join(projectDir, 'round.config.json');
218
- const viteConfigPath = path.join(projectDir, 'vite.config.js');
219
- const appRoundPath = path.join(srcDir, 'app.round');
220
- const counterRoundPath = path.join(srcDir, 'counter.round');
221
-
222
- writeFileIfMissing(pkgPath, JSON.stringify({
223
- name,
224
- private: true,
225
- version: '0.0.1',
226
- type: 'module',
227
- scripts: {
228
- dev: 'round dev',
229
- build: 'round build',
230
- preview: 'round preview'
231
- },
232
- dependencies: {
233
- 'round-core': '^0.0.4'
234
- },
235
- devDependencies: {
236
- vite: '^5.0.0'
237
- }
238
- }, null, 4) + '\n');
239
-
240
- writeFileIfMissing(configPath, JSON.stringify({
241
- mode,
242
- entry: './src/app.round',
243
- public: './public',
244
- output: './dist',
245
- include: ['./src'],
246
- exclude: ['./node_modules', './dist'],
247
- dev: {
248
- port: 5173,
249
- open: false,
250
- hmr: true
251
- },
252
- build: {
253
- minify: true,
254
- sourcemap: false,
255
- target: 'es2020',
256
- splitting: true
257
- },
258
- routing: {
259
- base: '/',
260
- trailingSlash: true
261
- }
262
- }, null, 4) + '\n');
263
-
264
- writeFileIfMissing(viteConfigPath, [
265
- "import { defineConfig } from 'vite';",
266
- "import RoundPlugin from 'round-core/vite-plugin';",
267
- '',
268
- 'export default defineConfig({',
269
- " plugins: [RoundPlugin({ configPath: './round.config.json' })],",
270
- ' server: {',
271
- ' port: 5173',
272
- ' }',
273
- '});',
274
- ''
275
- ].join('\n'));
276
-
277
-
278
- writeFileIfMissing(appRoundPath, [
279
- "import { Route } from 'round-core';",
280
- 'import { Counter } from "./counter"',
281
- '',
282
- 'export default function App() {',
283
- ' return (',
284
- ' <div style={{display: "flex", flexDirection: "column", alignItems: "center"}}>',
285
- ' <Route route="/" title="Home">',
286
- ' <Counter />',
287
- ' </Route>',
288
- ' </div>',
289
- ' )',
290
- '}',
291
- ''
292
- ].join('\n'));
293
-
294
- writeFileIfMissing(counterRoundPath, [
295
- "import { signal } from 'round-core';",
296
- '',
297
- 'export function Counter() {',
298
- ' const count = signal(0)',
299
- '',
300
- ' return (',
301
- " <div style={{ padding: '16px', fontFamily: 'system-ui' }}>",
302
- " <h1 style={{ fontSize: '32px', fontWeight: '700', marginBottom: '12px' }}>",
303
- ' Counter: {count()}',
304
- ' </h1>',
305
- '',
306
- " <div style={{ display: 'flex', gap: '8px' }}>",
307
- " <button onClick={() => count(count() + 1)} style={{ padding: '8px 12px', borderRadius: '8px' }}>",
308
- ' Increment',
309
- ' </button>',
310
- '',
311
- " <button onClick={() => count(count() - 1)} style={{ padding: '8px 12px', borderRadius: '8px' }}>",
312
- ' Decrement',
313
- ' </button>',
314
- '',
315
- " <button onClick={() => count(0)} style={{ padding: '8px 12px', borderRadius: '8px' }}>",
316
- ' Reset',
317
- ' </button>',
318
- ' </div>',
319
- ' </div>',
320
- ' )',
321
- '}',
322
- ''
323
- ].join('\n'));
324
-
325
- process.stdout.write(`\n${c('Project created:', 'green')} ${projectDir}\n`);
326
- process.stdout.write(`${c('Mode:', 'cyan')} ${mode}\n\n`);
327
- process.stdout.write(`${c('Next steps:', 'bold')}\n`);
328
- process.stdout.write(`${c(' 1)', 'cyan')} cd ${name}\n`);
329
- process.stdout.write(`${c(' 2)', 'cyan')} npm install ${c('(or bun install)', 'gray')}\n`);
330
- process.stdout.write(`${c(' 3)', 'cyan')} npm run dev\n\n`);
331
- }
332
-
333
- function loadRoundConfig(configPathAbs) {
334
- const raw = fs.readFileSync(configPathAbs, 'utf8');
335
- const json = JSON.parse(raw);
336
- return json && typeof json === 'object' ? json : {};
337
- }
338
-
339
- function coerceNumber(v, fallback) {
340
- const n = Number(v);
341
- return Number.isFinite(n) ? n : fallback;
342
- }
343
-
344
- function generateIndexHtml(config) {
345
- const name = config?.name ?? 'Round';
346
- const rawEntry = config?.entry ?? './src/app.round';
347
- let entry = rawEntry;
348
- if (entry.startsWith('./')) entry = entry.slice(1);
349
- if (!entry.startsWith('/')) entry = '/' + entry;
350
-
351
- return [
352
- '<!DOCTYPE html>',
353
- '<html lang="en">',
354
- '<head>',
355
- ' <meta charset="UTF-8" />',
356
- ' <meta name="viewport" content="width=device-width, initial-scale=1.0" />',
357
- ` <title>${name}</title>`,
358
- '</head>',
359
- '<body>',
360
- ' <div id="app"></div>',
361
- ' <script type="module">',
362
- " import { render } from 'round-core';",
363
- ` import App from '${entry}';`,
364
- '',
365
- " render(App, document.getElementById('app'));",
366
- ' </script>',
367
- '</body>',
368
- '</html>'
369
- ].join('\n');
370
- }
371
-
372
- function writeTemporaryIndex(rootDir, config) {
373
- const indexPath = path.resolve(rootDir, 'index.html');
374
- if (fs.existsSync(indexPath)) return false;
375
-
376
- const content = generateIndexHtml(config);
377
- fs.writeFileSync(indexPath, content, 'utf8');
378
- temporaryFiles.add(indexPath);
379
- return true;
380
- }
381
-
382
- async function runDev({ rootDir, configPathAbs, config }) {
383
- const startedAt = Date.now();
384
- const configDir = path.dirname(configPathAbs);
385
-
386
- const entryAbs = config?.entry ? resolveFrom(configDir, config.entry) : null;
387
- if (!entryAbs || !fs.existsSync(entryAbs)) {
388
- throw new Error(`Entry not found: ${entryAbs ?? '(missing entry)'} (config: ${configPathAbs})`);
389
- }
390
- const entryRel = normalizePath(path.relative(rootDir, entryAbs));
391
-
392
- let viteServer = null;
393
- let restarting = false;
394
- let restartTimer = null;
395
-
396
- const startServer = async (nextConfig, { showBanner, showReady } = { showBanner: true, showReady: true }) => {
397
- const cfgDir = path.dirname(configPathAbs);
398
-
399
- const entryAbs2 = nextConfig?.entry ? resolveFrom(cfgDir, nextConfig.entry) : null;
400
- if (!entryAbs2 || !fs.existsSync(entryAbs2)) {
401
- throw new Error(`Entry not found: ${entryAbs2 ?? '(missing entry)'} (config: ${configPathAbs})`);
402
- }
403
- const entryRel2 = normalizePath(path.relative(rootDir, entryAbs2));
404
-
405
- const serverPort2 = coerceNumber(nextConfig?.dev?.port, 5173);
406
- const open2 = Boolean(nextConfig?.dev?.open);
407
- const base2 = nextConfig?.routing?.base ?? '/';
408
-
409
- const isTemp = writeTemporaryIndex(rootDir, nextConfig);
410
-
411
- if (showBanner) {
412
- banner('Dev Server');
413
- process.stdout.write(`${c(' Config', 'gray')} ${configPathAbs}\n`);
414
- process.stdout.write(`${c(' Base', 'gray')} ${base2}\n`);
415
- process.stdout.write(`${c(' Port', 'gray')} ${serverPort2}\n\n`);
416
- }
417
-
418
- const server = await createServer({
419
- configFile: false,
420
- root: rootDir,
421
- base: base2,
422
- logLevel: 'info',
423
- customLogger: createViteLogger(),
424
- plugins: [RoundPlugin({
425
- configPath: normalizePath(path.relative(rootDir, configPathAbs)),
426
- restartOnConfigChange: false
427
- })],
428
- server: {
429
- port: serverPort2,
430
- open: open2
431
- },
432
- publicDir: nextConfig?.public ? resolveFrom(cfgDir, nextConfig.public) : undefined
433
- });
434
-
435
- await server.listen();
436
-
437
- if (showReady) {
438
- const ms = Date.now() - startedAt;
439
- printUrls(server.resolvedUrls, base2, ms);
440
- }
441
-
442
- return server;
443
- };
444
-
445
- viteServer = await startServer(config, { showBanner: true, showReady: true });
446
-
447
- if (typeof fs.watch === 'function') {
448
- try {
449
- fs.watch(configPathAbs, { persistent: true }, () => {
450
- if (restartTimer) clearTimeout(restartTimer);
451
- restartTimer = setTimeout(async () => {
452
- if (restarting) return;
453
- restarting = true;
454
- try {
455
- const next = loadRoundConfig(configPathAbs);
456
- process.stdout.write(`\n${c('[round]', 'cyan')} ${c('config changed', 'gray')} ${c('restarting dev server...', 'gray')}\n`);
457
- if (viteServer) await viteServer.close();
458
- viteServer = await startServer(next, { showBanner: true, showReady: true });
459
- } catch (e) {
460
- process.stderr.write(String(e?.stack ?? e?.message ?? e) + '\n');
461
- } finally {
462
- restarting = false;
463
- }
464
- }, 150);
465
- });
466
- } catch {
467
- }
468
- }
469
- }
470
-
471
- async function runBuild({ rootDir, configPathAbs, config }) {
472
- const startedAt = Date.now();
473
- const configDir = path.dirname(configPathAbs);
474
-
475
- const entryAbs = config?.entry ? resolveFrom(configDir, config.entry) : null;
476
- if (!entryAbs || !fs.existsSync(entryAbs)) {
477
- throw new Error(`Entry not found: ${entryAbs ?? '(missing entry)'} (config: ${configPathAbs})`);
478
- }
479
- const entryRel = normalizePath(path.relative(rootDir, entryAbs));
480
-
481
- const outDir = config?.output ? resolveFrom(configDir, config.output) : resolveFrom(rootDir, './dist');
482
- const base = config?.routing?.base ?? '/';
483
-
484
- const isTemp = writeTemporaryIndex(rootDir, config);
485
-
486
- banner('Build');
487
- process.stdout.write(`${c(' Config', 'gray')} ${configPathAbs}\n`);
488
- process.stdout.write(`${c(' OutDir', 'gray')} ${outDir}\n`);
489
- process.stdout.write(`${c(' Base', 'gray')} ${base}\n\n`);
490
-
491
- await viteBuild({
492
- configFile: false,
493
- root: rootDir,
494
- base,
495
- logLevel: 'warn',
496
- customLogger: createViteLogger(),
497
- plugins: [RoundPlugin({ configPath: normalizePath(path.relative(rootDir, configPathAbs)) })],
498
- publicDir: config?.public ? resolveFrom(configDir, config.public) : undefined,
499
- build: {
500
- outDir,
501
- sourcemap: Boolean(config?.build?.sourcemap),
502
- minify: config?.build?.minify !== undefined ? config.build.minify : true,
503
- target: config?.build?.target ?? 'es2020'
504
- }
505
- });
506
-
507
- const ms = Date.now() - startedAt;
508
- process.stdout.write(`\n ${c('ROUND', 'cyan')} ${c('built', 'green')} ${c('in', 'gray')} ${c(`${ms} ms`, 'gray')}\n\n`);
509
- }
510
-
511
- async function runPreview({ rootDir, configPathAbs, config }) {
512
- const configDir = path.dirname(configPathAbs);
513
- const outDir = config?.output ? resolveFrom(configDir, config.output) : resolveFrom(rootDir, './dist');
514
- const base = config?.routing?.base ?? '/';
515
- const previewPort = coerceNumber(config?.dev?.port, 5173);
516
-
517
- const entryAbs = config?.entry ? resolveFrom(configDir, config.entry) : null;
518
- if (entryAbs && fs.existsSync(entryAbs)) {
519
- // No physical index.html needed
520
- }
521
-
522
- banner('Preview');
523
- process.stdout.write(`${c('Config:', 'cyan')} ${configPathAbs}\n`);
524
- process.stdout.write(`${c('OutDir:', 'cyan')} ${outDir}\n`);
525
- process.stdout.write(`${c('Base:', 'cyan')} ${base}\n`);
526
- process.stdout.write(`${c('Port:', 'cyan')} ${previewPort}\n\n`);
527
-
528
- if (!fs.existsSync(outDir)) {
529
- process.stdout.write(`${c('Error:', 'red')} Build output not found: ${outDir}\n`);
530
- process.stdout.write(`${c('Hint:', 'gray')} Run \"round build\" first.\n`);
531
- process.exit(1);
532
- }
533
-
534
- const server = await vitePreview({
535
- configFile: false,
536
- root: rootDir,
537
- base,
538
- logLevel: 'warn',
539
- customLogger: createViteLogger(),
540
- preview: {
541
- port: previewPort
542
- },
543
- build: {
544
- outDir
545
- }
546
- });
547
-
548
- printUrls(server.resolvedUrls, base);
549
- }
550
-
551
- async function main() {
552
- const args = parseArgs(process.argv.slice(2));
553
- const cmd = args._[0];
554
-
555
- if (args.help || !cmd || (cmd !== 'dev' && cmd !== 'build' && cmd !== 'preview' && cmd !== 'init')) {
556
- printHelp();
557
- process.exit(cmd ? 1 : 0);
558
- }
559
-
560
- if (cmd === 'init') {
561
- const name = args._[1];
562
- await runInit({ name, template: args.template });
563
- return;
564
- }
565
-
566
- const initialRootDir = path.resolve(process.cwd(), args.root ?? '.');
567
- const configPathAbs = resolveFrom(initialRootDir, args.config ?? './round.config.json');
568
-
569
- const rootDir = args.root
570
- ? initialRootDir
571
- : path.dirname(configPathAbs);
572
-
573
- if (!fs.existsSync(configPathAbs)) {
574
- throw new CliError(`Config not found: ${configPathAbs}`, { code: 1 });
575
- }
576
-
577
- let config;
578
- try {
579
- config = loadRoundConfig(configPathAbs);
580
- } catch (e) {
581
- throw new CliError(`Failed to read config: ${configPathAbs}\n${String(e?.message ?? e)}`, { code: 1 });
582
- }
583
-
584
- if (cmd === 'dev') {
585
- await runDev({ rootDir, configPathAbs, config });
586
- return;
587
- }
588
-
589
- if (cmd === 'build') {
590
- await runBuild({ rootDir, configPathAbs, config });
591
- return;
592
- }
593
-
594
- if (cmd === 'preview') {
595
- await runPreview({ rootDir, configPathAbs, config });
596
- }
597
- }
598
-
599
- main().catch((e) => {
600
- if (e && e.name === 'CliError') {
601
- printError(e.message);
602
- if (e.showHelp) printHelp();
603
- process.exit(e.code ?? 1);
604
- }
605
- const msg = String(e?.stack ?? e?.message ?? e);
606
- process.stderr.write(c(msg, 'red') + '\n');
607
- process.exit(1);
608
- });
@@ -1,2 +0,0 @@
1
- export { transform } from './transformer.js';
2
- export { default as RoundPlugin } from './vite-plugin.js';