nuclie 1.0.7 → 1.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.
- package/README.md +14 -7
- package/dist/cli.js +0 -0
- package/dist/config/index.d.ts +1 -1
- package/dist/config/index.js +25 -20
- package/dist/core/framework-detector.d.ts +1 -1
- package/dist/core/framework-detector.js +16 -0
- package/dist/core/pipeline/framework-pipeline.js +15 -5
- package/dist/core/universal-transformer.js +44 -12
- package/dist/create-nuclie/cli.js +19 -17
- package/dist/create-nuclie.js +0 -0
- package/dist/dev/devServer.js +219 -113
- package/dist/dev/devServer.minimal.js +5 -16
- package/dist/dev/preBundler.js +26 -3
- package/dist/init/bootstrap.d.ts +1 -1
- package/dist/init/bootstrap.js +69 -29
- package/dist/native/index.js +26 -10
- package/dist/presets/frameworks.js +34 -0
- package/dist/utils/templates.d.ts +36 -0
- package/dist/utils/templates.js +1063 -0
- package/package.json +3 -8
- package/dist/create-nuclie/templates.d.ts +0 -18
- package/dist/create-nuclie/templates.js +0 -263
- package/dist/init/templates.d.ts +0 -2
- package/dist/init/templates.js +0 -227
- package/native/README.md +0 -10
- package/native/index.cjs +0 -117
- package/native/index.d.ts +0 -232
- package/native/index.js +0 -594
- package/native/nuclie_native.linux-x64-gnu.node +0 -0
- package/native/package.json +0 -7
package/README.md
CHANGED
|
@@ -432,14 +432,21 @@ nuclie bootstrap --name my-app --template svelte-ts
|
|
|
432
432
|
nuclie bootstrap --name my-app --template solid-ts
|
|
433
433
|
nuclie bootstrap --name my-app --template preact-ts
|
|
434
434
|
nuclie bootstrap --name my-app --template lit-ts
|
|
435
|
+
nuclie bootstrap --name my-app --template mithril-ts
|
|
436
|
+
nuclie bootstrap --name my-app --template alpine-ts
|
|
435
437
|
nuclie bootstrap --name my-app --template vanilla-ts
|
|
436
438
|
|
|
437
439
|
# JavaScript
|
|
438
|
-
nuclie bootstrap --name my-app --template react
|
|
439
|
-
nuclie bootstrap --name my-app --template vue
|
|
440
|
-
nuclie bootstrap --name my-app --template svelte
|
|
441
|
-
nuclie bootstrap --name my-app --template
|
|
442
|
-
nuclie bootstrap --name my-app --template
|
|
440
|
+
nuclie bootstrap --name my-app --template react
|
|
441
|
+
nuclie bootstrap --name my-app --template vue
|
|
442
|
+
nuclie bootstrap --name my-app --template svelte
|
|
443
|
+
nuclie bootstrap --name my-app --template solid
|
|
444
|
+
nuclie bootstrap --name my-app --template preact
|
|
445
|
+
nuclie bootstrap --name my-app --template lit
|
|
446
|
+
nuclie bootstrap --name my-app --template qwik
|
|
447
|
+
nuclie bootstrap --name my-app --template mithril
|
|
448
|
+
nuclie bootstrap --name my-app --template alpine
|
|
449
|
+
nuclie bootstrap --name my-app --template vanilla
|
|
443
450
|
```
|
|
444
451
|
|
|
445
452
|
---
|
|
@@ -454,9 +461,9 @@ nuclie bootstrap --name my-app --template vanilla-js
|
|
|
454
461
|
| SolidJS | ✅ Stable | ✅ Signal-aware | ✅ | |
|
|
455
462
|
| Preact | ✅ Stable | ✅ Fast Refresh | ✅ | React compat |
|
|
456
463
|
| Lit | ✅ Verified | ✅ Web Component | ✅ | |
|
|
457
|
-
| Alpine.js | ✅ Verified | ✅ Core Reload |
|
|
464
|
+
| Alpine.js | ✅ Verified | ✅ Core Reload | ✅ | HTML-first |
|
|
458
465
|
| Qwik | 🔶 Experimental | ✅ | ✅ | |
|
|
459
|
-
| Mithril.js |
|
|
466
|
+
| Mithril.js | ✅ Stable | ✅ | ✅ | |
|
|
460
467
|
| Vanilla JS | ✅ Stable | ✅ | ✅ | |
|
|
461
468
|
|
|
462
469
|
---
|
package/dist/cli.js
CHANGED
|
File without changes
|
package/dist/config/index.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ export declare const BuildConfigSchema: z.ZodObject<{
|
|
|
4
4
|
root: z.ZodOptional<z.ZodString>;
|
|
5
5
|
adapter: z.ZodOptional<z.ZodString>;
|
|
6
6
|
framework: z.ZodOptional<z.ZodString>;
|
|
7
|
-
entry: z.
|
|
7
|
+
entry: z.ZodOptional<z.ZodPipe<z.ZodUnion<readonly [z.ZodString, z.ZodArray<z.ZodString>]>, z.ZodTransform<string[], string | string[]>>>;
|
|
8
8
|
mode: z.ZodDefault<z.ZodEnum<{
|
|
9
9
|
development: "development";
|
|
10
10
|
production: "production";
|
package/dist/config/index.js
CHANGED
|
@@ -13,7 +13,7 @@ export const BuildConfigSchema = z.object({
|
|
|
13
13
|
framework: z.string().optional(),
|
|
14
14
|
entry: z.union([z.string(), z.array(z.string())])
|
|
15
15
|
.transform((val) => (typeof val === 'string' ? [val] : val))
|
|
16
|
-
.
|
|
16
|
+
.optional(),
|
|
17
17
|
mode: z.enum(['development', 'production', 'test']).default('development'),
|
|
18
18
|
outDir: z.string().default('build_output'),
|
|
19
19
|
port: z.number().default(5173),
|
|
@@ -135,27 +135,9 @@ export async function loadConfig(cwd) {
|
|
|
135
135
|
else {
|
|
136
136
|
// Return default config if file not found, with auto-detection
|
|
137
137
|
log.info('No config file found, using defaults...');
|
|
138
|
-
// Auto-detect entry point
|
|
139
|
-
const entryCandidates = [
|
|
140
|
-
'src/main.tsx',
|
|
141
|
-
'src/main.ts',
|
|
142
|
-
'src/main.jsx',
|
|
143
|
-
'src/main.js',
|
|
144
|
-
'src/index.tsx',
|
|
145
|
-
'src/index.ts',
|
|
146
|
-
'src/index.jsx',
|
|
147
|
-
'src/index.js'
|
|
148
|
-
];
|
|
149
|
-
let detectedEntry = ['src/main.tsx']; // Default fallback
|
|
150
|
-
for (const candidate of entryCandidates) {
|
|
151
|
-
if (await fs.access(path.join(cwd, candidate)).then(() => true).catch(() => false)) {
|
|
152
|
-
detectedEntry = [candidate];
|
|
153
|
-
break;
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
138
|
return {
|
|
157
139
|
root: cwd,
|
|
158
|
-
entry:
|
|
140
|
+
entry: [], // will be auto-detected below
|
|
159
141
|
mode: 'development',
|
|
160
142
|
outDir: 'build_output',
|
|
161
143
|
port: 5173,
|
|
@@ -176,6 +158,29 @@ export async function loadConfig(cwd) {
|
|
|
176
158
|
const config = result.data;
|
|
177
159
|
// Ensure root is set
|
|
178
160
|
const root = config.root || cwd;
|
|
161
|
+
// Auto-detect entry point if missing
|
|
162
|
+
if (!config.entry || config.entry.length === 0) {
|
|
163
|
+
const entryCandidates = [
|
|
164
|
+
'src/main.tsx',
|
|
165
|
+
'src/main.ts',
|
|
166
|
+
'src/main.jsx',
|
|
167
|
+
'src/main.js',
|
|
168
|
+
'src/index.tsx',
|
|
169
|
+
'src/index.ts',
|
|
170
|
+
'src/index.jsx',
|
|
171
|
+
'src/index.js',
|
|
172
|
+
'src/root.tsx',
|
|
173
|
+
'src/root.ts',
|
|
174
|
+
];
|
|
175
|
+
let detectedEntry = ['src/main.tsx']; // Default fallback
|
|
176
|
+
for (const candidate of entryCandidates) {
|
|
177
|
+
if (await fs.access(path.join(root, candidate)).then(() => true).catch(() => false)) {
|
|
178
|
+
detectedEntry = [candidate];
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
config.entry = detectedEntry;
|
|
183
|
+
}
|
|
179
184
|
let finalConfig = { ...config };
|
|
180
185
|
if (config.preset === 'spa')
|
|
181
186
|
finalConfig = { ...finalConfig, ...spaPreset.apply(finalConfig) };
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Framework Detector
|
|
3
3
|
* Automatically detects which framework(s) are being used in the project
|
|
4
4
|
*/
|
|
5
|
-
export type Framework = 'react' | 'vue' | 'svelte' | 'angular' | 'solid' | 'preact' | 'qwik' | 'lit' | 'astro' | 'next' | 'nuxt' | 'remix' | 'vanilla';
|
|
5
|
+
export type Framework = 'react' | 'vue' | 'svelte' | 'angular' | 'solid' | 'preact' | 'qwik' | 'lit' | 'astro' | 'next' | 'nuxt' | 'remix' | 'alpine' | 'mithril' | 'vanilla';
|
|
6
6
|
export interface FrameworkInfo {
|
|
7
7
|
name: Framework;
|
|
8
8
|
version?: string;
|
|
@@ -122,6 +122,22 @@ export class FrameworkDetector {
|
|
|
122
122
|
confidence: 1.0
|
|
123
123
|
});
|
|
124
124
|
}
|
|
125
|
+
if (deps['alpinejs']) {
|
|
126
|
+
frameworks.push({
|
|
127
|
+
name: 'alpine',
|
|
128
|
+
version: deps['alpinejs'],
|
|
129
|
+
detected: true,
|
|
130
|
+
confidence: 1.0
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
if (deps['mithril']) {
|
|
134
|
+
frameworks.push({
|
|
135
|
+
name: 'mithril',
|
|
136
|
+
version: deps['mithril'],
|
|
137
|
+
detected: true,
|
|
138
|
+
confidence: 1.0
|
|
139
|
+
});
|
|
140
|
+
}
|
|
125
141
|
// If no framework detected, it's vanilla JS/TS
|
|
126
142
|
if (frameworks.length === 0) {
|
|
127
143
|
frameworks.push({
|
|
@@ -20,16 +20,26 @@ export class FrameworkPipeline {
|
|
|
20
20
|
// Honor explicit configuration (Phase 2/3 Alignment)
|
|
21
21
|
let framework = config.framework;
|
|
22
22
|
if (!framework && config.adapter) {
|
|
23
|
-
if (config.adapter.
|
|
23
|
+
if (config.adapter === 'react' || config.adapter === 'react-typescript' || config.adapter === 'react-adapter')
|
|
24
24
|
framework = 'react';
|
|
25
|
-
else if (config.adapter
|
|
25
|
+
else if (config.adapter === 'vue')
|
|
26
26
|
framework = 'vue';
|
|
27
|
-
else if (config.adapter
|
|
27
|
+
else if (config.adapter === 'svelte')
|
|
28
28
|
framework = 'svelte';
|
|
29
|
-
else if (config.adapter
|
|
29
|
+
else if (config.adapter === 'angular')
|
|
30
30
|
framework = 'angular';
|
|
31
|
-
else if (config.adapter
|
|
31
|
+
else if (config.adapter === 'solid')
|
|
32
32
|
framework = 'solid';
|
|
33
|
+
else if (config.adapter === 'preact')
|
|
34
|
+
framework = 'preact';
|
|
35
|
+
else if (config.adapter === 'qwik')
|
|
36
|
+
framework = 'qwik';
|
|
37
|
+
else if (config.adapter === 'lit')
|
|
38
|
+
framework = 'lit';
|
|
39
|
+
else if (config.adapter === 'alpine')
|
|
40
|
+
framework = 'alpine';
|
|
41
|
+
else if (config.adapter === 'mithril' || config.adapter === 'mithril-ts')
|
|
42
|
+
framework = 'mithril';
|
|
33
43
|
}
|
|
34
44
|
if (!framework) {
|
|
35
45
|
framework = await detectFramework(rootDir);
|
|
@@ -8,6 +8,7 @@ import fs from 'fs/promises';
|
|
|
8
8
|
import { getFrameworkPreset } from '../presets/frameworks.js';
|
|
9
9
|
import { log } from '../utils/logger.js';
|
|
10
10
|
import { createRequire } from 'module';
|
|
11
|
+
import { fileURLToPath, pathToFileURL } from 'url';
|
|
11
12
|
import * as esbuild from 'esbuild';
|
|
12
13
|
import { canonicalHash } from '../core/engine/hash.js';
|
|
13
14
|
const _require = createRequire(import.meta.url);
|
|
@@ -219,8 +220,11 @@ if (import.meta.hot) {
|
|
|
219
220
|
try {
|
|
220
221
|
let compiler;
|
|
221
222
|
try {
|
|
222
|
-
|
|
223
|
-
|
|
223
|
+
// Try: user project first, then nuclie's own node_modules (nuclie ships @vue/compiler-sfc as a dep)
|
|
224
|
+
const searchPaths = [this.root, process.cwd(), fileURLToPath(new URL('../..', import.meta.url))];
|
|
225
|
+
const compilerPath = _require.resolve('@vue/compiler-sfc', { paths: searchPaths });
|
|
226
|
+
const compilerUrl = pathToFileURL(compilerPath).href;
|
|
227
|
+
compiler = await import(compilerUrl);
|
|
224
228
|
}
|
|
225
229
|
catch {
|
|
226
230
|
log.warn('No Vue 3 compiler found, using fallback with HMR');
|
|
@@ -317,7 +321,7 @@ if (import.meta.hot) {
|
|
|
317
321
|
` : ''}
|
|
318
322
|
|
|
319
323
|
${descriptor.styles.some((s) => s.scoped) ? `_sfc_main.__scopeId = "${scopeId}";` : ''}
|
|
320
|
-
_sfc_main.__file = "${filePath}";
|
|
324
|
+
_sfc_main.__file = "${filePath.replace(/\\/g, '/')}";
|
|
321
325
|
|
|
322
326
|
export default _sfc_main;
|
|
323
327
|
`;
|
|
@@ -360,7 +364,8 @@ if (import.meta.hot) {
|
|
|
360
364
|
let svelte;
|
|
361
365
|
try {
|
|
362
366
|
const compilerPath = _require.resolve('svelte/compiler', { paths: [this.root, process.cwd()] });
|
|
363
|
-
const
|
|
367
|
+
const compilerUrl = pathToFileURL(compilerPath).href;
|
|
368
|
+
const mod = await import(compilerUrl);
|
|
364
369
|
svelte = typeof mod.compile === 'function' ? mod : (mod.default || mod);
|
|
365
370
|
}
|
|
366
371
|
catch {
|
|
@@ -533,7 +538,8 @@ if (import.meta.hot) {
|
|
|
533
538
|
if (dispose) dispose();
|
|
534
539
|
const NewComponent = newModule.default || newModule[component];
|
|
535
540
|
if (NewComponent && container) {
|
|
536
|
-
|
|
541
|
+
// Use server-relative path so the dev server resolves via exports field
|
|
542
|
+
import('/node_modules/solid-js/web').then(({ render }) => {
|
|
537
543
|
render(() => NewComponent({}), container);
|
|
538
544
|
});
|
|
539
545
|
}
|
|
@@ -592,14 +598,19 @@ if (import.meta.hot) {
|
|
|
592
598
|
* Qwik Transformer - Works with all Qwik versions
|
|
593
599
|
*/
|
|
594
600
|
async transformQwik(code, filePath, isDev) {
|
|
601
|
+
const ext = path.extname(filePath);
|
|
602
|
+
if (ext !== '.tsx' && ext !== '.ts' && ext !== '.jsx' && ext !== '.js') {
|
|
603
|
+
return this.transformVanilla(code, filePath, isDev);
|
|
604
|
+
}
|
|
595
605
|
try {
|
|
596
606
|
let qwik;
|
|
597
607
|
try {
|
|
598
608
|
const compilerPath = _require.resolve('@builder.io/qwik/optimizer', { paths: [this.root, process.cwd()] });
|
|
599
|
-
const mod = await import(compilerPath);
|
|
609
|
+
const mod = await import(pathToFileURL(compilerPath).href);
|
|
600
610
|
qwik = typeof mod.createOptimizer === 'function' ? mod : (mod.default || mod);
|
|
601
611
|
}
|
|
602
|
-
catch {
|
|
612
|
+
catch (e) {
|
|
613
|
+
console.error("[Qwik Optimizer] Original import failed:", e);
|
|
603
614
|
const fallbackQwikOptimizer = '@builder.io/qwik/optimizer';
|
|
604
615
|
const mod = await import(fallbackQwikOptimizer);
|
|
605
616
|
qwik = typeof mod.createOptimizer === 'function' ? mod : (mod.default || mod);
|
|
@@ -608,9 +619,11 @@ if (import.meta.hot) {
|
|
|
608
619
|
const result = await optimizer.transformModules({
|
|
609
620
|
input: [{ code, path: filePath }],
|
|
610
621
|
srcDir: path.join(this.root, 'src'),
|
|
611
|
-
|
|
622
|
+
rootDir: this.root,
|
|
623
|
+
entryStrategy: { type: 'inline' },
|
|
612
624
|
minify: isDev ? 'none' : 'simplify',
|
|
613
625
|
sourceMaps: isDev,
|
|
626
|
+
mode: isDev ? 'dev' : 'lib',
|
|
614
627
|
transpile: true,
|
|
615
628
|
});
|
|
616
629
|
const output = result.modules[0];
|
|
@@ -618,15 +631,34 @@ if (import.meta.hot) {
|
|
|
618
631
|
const final = await transform(output.code, {
|
|
619
632
|
loader: 'tsx',
|
|
620
633
|
format: 'esm',
|
|
621
|
-
target: '
|
|
634
|
+
target: 'es2020',
|
|
622
635
|
jsx: 'automatic',
|
|
623
636
|
jsxImportSource: '@builder.io/qwik'
|
|
624
637
|
});
|
|
625
|
-
|
|
638
|
+
const finalCode = final.code;
|
|
639
|
+
return { code: finalCode, map: final.map ? JSON.stringify(final.map) : undefined };
|
|
626
640
|
}
|
|
627
641
|
catch (error) {
|
|
628
|
-
|
|
629
|
-
|
|
642
|
+
// Fallback: use esbuild directly with Qwik JSX classic mode
|
|
643
|
+
log.warn(`Qwik optimizer failed, using esbuild fallback: ${error.message}`);
|
|
644
|
+
try {
|
|
645
|
+
const final = await esbuild.transform(code, {
|
|
646
|
+
loader: (path.extname(filePath) === '.tsx' || path.extname(filePath) === '.jsx') ? 'tsx' : 'ts',
|
|
647
|
+
format: 'esm',
|
|
648
|
+
target: 'es2020',
|
|
649
|
+
jsx: 'transform',
|
|
650
|
+
jsxFactory: 'h',
|
|
651
|
+
jsxFragment: 'Fragment',
|
|
652
|
+
jsxImportSource: undefined,
|
|
653
|
+
});
|
|
654
|
+
// Inject h/Fragment imports from qwik
|
|
655
|
+
const imports = `import { h, Fragment } from '@builder.io/qwik';\n`;
|
|
656
|
+
return { code: imports + final.code };
|
|
657
|
+
}
|
|
658
|
+
catch (fallbackErr) {
|
|
659
|
+
log.error(`Qwik fallback also failed for ${filePath}: ${fallbackErr.message}`);
|
|
660
|
+
return this.transformVanilla(code, filePath, isDev);
|
|
661
|
+
}
|
|
630
662
|
}
|
|
631
663
|
}
|
|
632
664
|
/**
|
|
@@ -5,8 +5,21 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as path from 'path';
|
|
8
|
-
import {
|
|
8
|
+
import { fileURLToPath } from 'url';
|
|
9
|
+
import { TEMPLATES } from '../utils/templates.js';
|
|
9
10
|
import { red, green, blue, bold } from 'kleur/colors';
|
|
11
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
12
|
+
// Read real nuclie version from its own package.json
|
|
13
|
+
function getNuclieVersion() {
|
|
14
|
+
try {
|
|
15
|
+
const pkgPath = path.resolve(__dirname, '../../package.json');
|
|
16
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
17
|
+
return `^${pkg.version}`;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return 'latest';
|
|
21
|
+
}
|
|
22
|
+
}
|
|
10
23
|
async function main() {
|
|
11
24
|
const args = process.argv.slice(2);
|
|
12
25
|
let projectName = args[0];
|
|
@@ -43,29 +56,18 @@ async function main() {
|
|
|
43
56
|
console.log(blue(`\n🚀 Scaffolding ${bold(template.name)} project in ${bold(projectName)}...`));
|
|
44
57
|
// 1. Create Dir
|
|
45
58
|
fs.mkdirSync(targetDir, { recursive: true });
|
|
46
|
-
// 2. Create Files
|
|
59
|
+
// 2. Create Files (replace version placeholder with real version)
|
|
60
|
+
const nuclieVersion = getNuclieVersion();
|
|
61
|
+
const versionLabel = nuclieVersion.replace('^', '');
|
|
47
62
|
for (const file of template.files) {
|
|
48
63
|
const filePath = path.join(targetDir, file.path);
|
|
49
64
|
const dir = path.dirname(filePath);
|
|
50
65
|
if (!fs.existsSync(dir))
|
|
51
66
|
fs.mkdirSync(dir, { recursive: true });
|
|
52
|
-
|
|
67
|
+
const content = file.content.replace(/\{\{NUCLIE_VERSION\}\}/g, versionLabel);
|
|
68
|
+
fs.writeFileSync(filePath, content);
|
|
53
69
|
}
|
|
54
70
|
// 3. Create package.json
|
|
55
|
-
let nuclieVersion = 'latest';
|
|
56
|
-
try {
|
|
57
|
-
const pkgjsonPath = path.resolve(process.cwd(), 'node_modules/nuclie/package.json');
|
|
58
|
-
if (fs.existsSync(pkgjsonPath)) {
|
|
59
|
-
nuclieVersion = '^' + JSON.parse(fs.readFileSync(pkgjsonPath, 'utf8')).version;
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
const localPkgPath = new URL('../../package.json', import.meta.url);
|
|
63
|
-
if (fs.existsSync(localPkgPath)) {
|
|
64
|
-
nuclieVersion = '^' + JSON.parse(fs.readFileSync(localPkgPath, 'utf8')).version;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
catch (e) { }
|
|
69
71
|
const pkg = {
|
|
70
72
|
name: projectName,
|
|
71
73
|
version: '0.0.0',
|
package/dist/create-nuclie.js
CHANGED
|
File without changes
|