vaderjs-native 1.0.37 → 1.0.38

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/cli.ts CHANGED
@@ -1,279 +1,353 @@
1
- #!/usr/bin/env bun
2
- import fs from "fs/promises";
3
- import fsSync from "fs";
4
- import path from "path";
5
- import readline from "readline";
6
-
7
- const cwd = process.cwd();
8
-
9
- /* -------------------------------- utils -------------------------------- */
10
- /* -------------------------------- utils -------------------------------- */
11
- function ask(question: string): Promise<string> {
12
- const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
13
- return new Promise((resolve) =>
14
- rl.question(question + " ", (answer) => {
15
- rl.close();
16
- resolve(answer.trim());
17
- })
18
- );
19
- }
20
-
21
- async function run(cmd: string, args: string[] = []) {
22
- const proc = Bun.spawn([cmd, ...args], { stdout: "inherit", stderr: "inherit" });
23
- const code = await proc.exited;
24
- if (code !== 0) process.exit(code);
25
- }
26
-
27
- function logSection(title: string) {
28
- console.log(`\n${title}`);
29
- console.log("─".repeat(title.length));
30
- }
31
-
32
- function getFlags() {
33
- return new Set(process.argv.slice(2));
34
- }
35
-
36
- /* ---------------------------- UI frameworks ---------------------------- */
37
- const UI_FRAMEWORKS = {
38
- none: {
39
- name: "None (Basic)",
40
- runtimeDeps: [],
41
- devDeps: [],
42
- },
43
-
44
- daisyui: {
45
- name: "VaderUI (DaisyUI)",
46
- runtimeDeps: ["vaderjs-daisyui", "daisyui"],
47
- devDeps: ["tailwindcss", "postcss", "autoprefixer"],
48
- pluginImport: `import daisyui from "vaderjs-daisyui";`,
49
- pluginRef: "daisyui",
50
- requiresRootCss: true,
51
- requiresTailwindConfig: true,
52
- },
53
- };
54
-
55
- /* ------------------------------ initProject ------------------------------ */
56
- export async function initProject(dir?: string) {
57
- console.log("🚀 Initializing Vader.js project");
58
-
59
- const projectDir = path.resolve(cwd, dir || ".");
60
- if (!fsSync.existsSync(projectDir)) await fs.mkdir(projectDir, { recursive: true });
61
-
62
- if (fsSync.readdirSync(projectDir).length) {
63
- const confirm = await ask("Directory is not empty. Continue? (y/n):");
64
- if (confirm !== "y") process.exit(0);
65
- }
66
-
67
- /* language */
68
- console.log("\nSelect language:");
69
- console.log(" 1. JavaScript");
70
- console.log(" 2. TypeScript");
71
- const useTypeScript = (await ask("Choose (1-2):")) === "2";
72
- const fileExt = useTypeScript ? "tsx" : "jsx";
73
- const configExt = useTypeScript ? "ts" : "js";
74
-
75
- /* framework */
76
- console.log("\nSelect UI framework:");
77
- const keys = Object.keys(UI_FRAMEWORKS);
78
- keys.forEach((k, i) => console.log(` ${i + 1}. ${UI_FRAMEWORKS[k].name}`));
79
- const fwKey = keys[Number(await ask(`Choose (1-${keys.length}):`)) - 1];
80
- const framework = UI_FRAMEWORKS[fwKey];
81
-
82
- /* folders */
83
- logSection("📁 Creating folders");
84
- for (const d of ["app", "src", "public"]) {
85
- await fs.mkdir(path.join(projectDir, d), { recursive: true });
86
- }
87
-
88
- /* root.css */
89
- if (framework.requiresRootCss) {
90
- await fs.writeFile(
91
- path.join(projectDir, "root.css"),
92
- `@import "tailwindcss";\n@plugin "daisyui";\n`
93
- );
94
- }
95
-
96
- /* tailwind.config.js */
97
- if (framework.requiresTailwindConfig) {
98
- await fs.writeFile(
99
- path.join(projectDir, "tailwind.config.js"),
100
- `export default {
101
- content: [
102
- "./app/**/*.{js,jsx,ts,tsx}",
103
- "./src/**/*.{js,jsx,ts,tsx}"
104
- ],
105
-
106
- safelist: [
107
- "btn",
108
- "btn-primary",
109
- "btn-secondary",
110
- "btn-accent",
111
- "alert",
112
- "alert-error",
113
- "card",
114
- "card-body",
115
- "badge",
116
- "badge-info",
117
- ],
118
-
119
- theme: { extend: {} },
120
- plugins: [require("daisyui")]
121
- };
122
- `
123
- );
124
- }
125
-
126
- /* --------------------- VITE-STYLE DAISYUI DEMO --------------------- */
127
- const appCode = `import * as Vader from "vaderjs-native";
128
- import { useState } from "vaderjs-native";
129
- import Button from "vaderjs-daisyui/Components/Actions/Button";
130
-
131
- function Main() {
132
- const [count, setCount] = useState(0);
133
-
134
- return (
135
- <div className="min-h-screen bg-base-200 flex flex-col items-center justify-center">
136
- <div className="text-center mb-10">
137
- <h1 className="text-5xl font-bold">
138
- Vader<span className="text-primary">.js</span>
139
- </h1>
140
- <p className="opacity-70 mt-2">Next-gen UI, zero React</p>
141
- </div>
142
-
143
- <div className="grid md:grid-cols-3 gap-6 max-w-5xl w-full px-6">
144
- <div className="card bg-base-100 shadow-xl">
145
- <div className="card-body">
146
- <h2 className="card-title">Instant Reactivity</h2>
147
- <p>Signals + fibers, no virtual DOM tax.</p>
148
- </div>
149
- </div>
150
-
151
- <div className="card bg-base-100 shadow-xl">
152
- <div className="card-body">
153
- <h2 className="card-title">DaisyUI Built-In</h2>
154
- <p>Accessible components styled with Tailwind.</p>
155
- </div>
156
- </div>
157
-
158
- <div className="card bg-base-100 shadow-xl">
159
- <div className="card-body">
160
- <h2 className="card-title">Multi-Platform</h2>
161
- <p>Web, Android, Windows from one codebase.</p>
162
- </div>
163
- </div>
164
- </div>
165
-
166
- <div className="mt-10 flex gap-4">
167
- <Button color="primary" onClick={() => setCount(count + 1)}>
168
- Count: {count}
169
- </Button>
170
- <Button color="secondary" onClick={() => setCount(0)}>
171
- Reset
172
- </Button>
173
- </div>
174
-
175
- <p className="mt-6 opacity-60 text-sm">
176
- Edit <code>app/index.${fileExt}</code> and save to reload
177
- </p>
178
- </div>
179
- );
180
- }
181
-
182
- Vader.render(Vader.createElement(Main), document.getElementById("app"));`;
183
-
184
- await fs.writeFile(path.join(projectDir, `app/index.${fileExt}`), appCode);
185
-
186
- /* ---------------- jsconfig (EXACT – DO NOT TOUCH) ---------------- */
187
- await fs.writeFile(
188
- path.join(projectDir, "jsconfig.json"),
189
- JSON.stringify(
190
- {
191
- compilerOptions: {
192
- jsx: "react",
193
- jsxFactory: "Vader.createElement",
194
- jsxFragmentFactory: "Fragment",
195
- },
196
- include: ["app", "src"],
197
- },
198
- null,
199
- 2
200
- )
201
- );
202
-
203
- /* config */
204
- const name = path.basename(projectDir);
205
- const config = `${framework.pluginImport}
206
- import defineConfig from "vaderjs-native/config";
207
-
208
- export default defineConfig({
209
- app: {
210
- name: "${name}",
211
- id: "com.example.${name}",
212
- version: { code: 1, name: "1.0.0" },
213
- },
214
- platforms: {
215
- web: { title: "${name}", themeColor: "#111827" },
216
- windows: {
217
- publisher: "CN=VaderJS",
218
- icon: "./assets/windows/icon.png",
219
- executionAlias: "${name}",
220
- sdkVersion: "10.0.19041.0",
221
- minSdkVersion: "10.0.17763.0"
222
- }
223
- },
224
- plugins: [${framework.pluginRef}]
225
- });`;
226
-
227
- await fs.writeFile(path.join(projectDir, `vaderjs.config.${configExt}`), config);
228
-
229
- /* package.json */
230
- const pkgPath = path.join(projectDir, "package.json");
231
- const pkg = {
232
- name,
233
- version: "1.0.0",
234
- type: "module",
235
- dependencies: { "vaderjs-native": "latest" },
236
- devDependencies: {},
237
- };
238
-
239
- framework.runtimeDeps.forEach((d) => (pkg.dependencies[d] = "latest"));
240
- framework.devDeps.forEach((d) => (pkg.devDependencies[d] = "latest"));
241
-
242
- await fs.writeFile(pkgPath, JSON.stringify(pkg, null, 2));
243
-
244
- logSection("📦 Installing dependencies");
245
- await run("bun", ["install"]);
246
-
247
- console.log("\n✅ Project ready!");
248
- }
249
-
250
- /* ------------------------------- plugins ------------------------------- */
251
- export async function addPlugin(name: string) {
252
- const pkgName = name.startsWith("vaderjs-") ? name : `vaderjs-${name}`;
253
- await run("bun", ["add", pkgName]);
254
-
255
- const configPath = fsSync.existsSync("vaderjs.config.ts")
256
- ? "vaderjs.config.ts"
257
- : "vaderjs.config.js";
258
-
259
- let config = await fs.readFile(configPath, "utf8");
260
- const importName = pkgName.replace(/^vaderjs-/, "").replace(/-/g, "_");
261
-
262
- if (!config.includes(pkgName)) {
263
- config = `import ${importName} from "${pkgName}";\n` + config;
264
- config = config.replace(/plugins:\s*\[/, `plugins: [${importName}, `);
265
- await fs.writeFile(configPath, config);
266
- }
267
- }
268
-
269
- export async function removePlugin(name: string) {
270
- const pkgName = name.startsWith("vaderjs-") ? name : `vaderjs-${name}`;
271
- await run("bun", ["remove", pkgName]);
272
- }
273
-
274
- export async function listPlugins() {
275
- const pkg = JSON.parse(await fs.readFile("package.json", "utf8"));
276
- Object.keys(pkg.dependencies || {})
277
- .filter((d) => d.startsWith("vaderjs-"))
278
- .forEach((d) => console.log("•", d));
279
- }
1
+ #!/usr/bin/env bun
2
+ import fs from "fs/promises";
3
+ import fsSync from "fs";
4
+ import path from "path";
5
+ import readline from "readline";
6
+
7
+ const cwd = process.cwd();
8
+
9
+ /* ------------------------------------------------ utils ------------------------------------------------ */
10
+
11
+ function ask(question: string): Promise<string> {
12
+ const rl = readline.createInterface({
13
+ input: process.stdin,
14
+ output: process.stdout,
15
+ });
16
+
17
+ return new Promise(resolve =>
18
+ rl.question(question + " ", ans => {
19
+ rl.close();
20
+ resolve(ans.trim());
21
+ })
22
+ );
23
+ }
24
+
25
+ async function run(cmd: string, args: string[] = []) {
26
+ const proc = Bun.spawn([cmd, ...args], {
27
+ stdout: "inherit",
28
+ stderr: "inherit",
29
+ });
30
+
31
+ const code = await proc.exited;
32
+ if (code !== 0) process.exit(code);
33
+ }
34
+
35
+ function logSection(title: string) {
36
+ console.log(`\n${title}`);
37
+ console.log("─".repeat(title.length));
38
+ }
39
+
40
+ /* ------------------------------------------------ frameworks ------------------------------------------------ */
41
+
42
+ const UI_FRAMEWORKS: Record<string, any> = {
43
+ none: {
44
+ name: "None (Basic)",
45
+ runtimeDeps: [],
46
+ devDeps: [],
47
+ },
48
+
49
+ daisyui: {
50
+ name: "VaderUI (DaisyUI)",
51
+ runtimeDeps: ["vaderjs-daisyui", "daisyui"],
52
+ devDeps: ["tailwindcss", "postcss", "autoprefixer"],
53
+ pluginImport: `import daisyui from "vaderjs-daisyui";`,
54
+ pluginRef: "daisyui",
55
+ requiresRootCss: true,
56
+ requiresTailwindConfig: true,
57
+ },
58
+ };
59
+
60
+ /* ------------------------------------------------ project generator ------------------------------------------------ */
61
+
62
+ export async function initProject(dir?: string) {
63
+ console.log("🚀 Initializing Vader.js project");
64
+
65
+ const projectDir = path.resolve(cwd, dir || ".");
66
+
67
+ if (!fsSync.existsSync(projectDir)) {
68
+ await fs.mkdir(projectDir, { recursive: true });
69
+ }
70
+
71
+ if (fsSync.readdirSync(projectDir).length) {
72
+ const confirm = await ask("Directory is not empty. Continue? (y/n):");
73
+ if (confirm !== "y") process.exit(0);
74
+ }
75
+
76
+ /* ---------------- language ---------------- */
77
+
78
+ console.log("\nSelect language:");
79
+ console.log(" 1. JavaScript");
80
+ console.log(" 2. TypeScript");
81
+
82
+ const useTypeScript = (await ask("Choose (1-2):")) === "2";
83
+
84
+ const fileExt = useTypeScript ? "tsx" : "jsx";
85
+ const configExt = useTypeScript ? "ts" : "js";
86
+
87
+ /* ---------------- port ---------------- */
88
+
89
+ const port = (await ask("Enter dev server port (default 5173):")) || "5173";
90
+
91
+ /* ---------------- framework ---------------- */
92
+
93
+ console.log("\nSelect UI framework:");
94
+
95
+ const keys = Object.keys(UI_FRAMEWORKS);
96
+ keys.forEach((k, i) => {
97
+ console.log(` ${i + 1}. ${UI_FRAMEWORKS[k].name}`);
98
+ });
99
+
100
+ const fwKey = keys[Number(await ask(`Choose (1-${keys.length}):`)) - 1];
101
+ const framework = UI_FRAMEWORKS[fwKey];
102
+
103
+ /* ------------------------------------------------ folders ------------------------------------------------ */
104
+
105
+ logSection("📁 Creating project structure");
106
+
107
+ for (const d of ["app", "src", "public"]) {
108
+ await fs.mkdir(path.join(projectDir, d), { recursive: true });
109
+ }
110
+
111
+ /* ------------------------------------------------ framework configs ------------------------------------------------ */
112
+
113
+ if (framework.requiresRootCss) {
114
+ await fs.writeFile(
115
+ path.join(projectDir, "root.css"),
116
+ `@import "tailwindcss";
117
+ @plugin "daisyui";
118
+ `
119
+ );
120
+ }
121
+
122
+ if (framework.requiresTailwindConfig) {
123
+ await fs.writeFile(
124
+ path.join(projectDir, "tailwind.config.js"),
125
+ `export default {
126
+ content: [
127
+ "./app/**/*.{js,jsx,ts,tsx}",
128
+ "./src/**/*.{js,jsx,ts,tsx}"
129
+ ],
130
+
131
+ theme: { extend: {} },
132
+
133
+ plugins: [require("daisyui")]
134
+ };
135
+ `
136
+ );
137
+ }
138
+
139
+ /* ------------------------------------------------ app/index template ------------------------------------------------ */
140
+
141
+ const appIndexTemplate = framework.pluginRef
142
+ ? `
143
+ import * as Vader from "vaderjs-native";
144
+ import { useState } from "vaderjs-native";
145
+ import Button from "vaderjs-daisyui/Components/Actions/Button";
146
+
147
+ function Main() {
148
+ const [count, setCount] = useState(0);
149
+
150
+ return (
151
+ <div className="min-h-screen flex flex-col items-center justify-center bg-base-200">
152
+ <h1 className="text-5xl font-bold">
153
+ Vader<span className="text-primary">.js</span>
154
+ </h1>
155
+
156
+ <div className="mt-10 flex gap-4">
157
+ <Button color="primary" onClick={() => setCount(count + 1)}>
158
+ Count: {count}
159
+ </Button>
160
+
161
+ <Button color="secondary" onClick={() => setCount(0)}>
162
+ Reset
163
+ </Button>
164
+ </div>
165
+ </div>
166
+ );
167
+ }
168
+
169
+ export default Main;
170
+ `
171
+ : `
172
+ import * as Vader from "vaderjs-native";
173
+ import { useState } from "vaderjs-native";
174
+
175
+ function Main() {
176
+ const [count, setCount] = useState(0);
177
+
178
+ return (
179
+ <div style={{
180
+ minHeight: "100vh",
181
+ display: "flex",
182
+ flexDirection: "column",
183
+ alignItems: "center",
184
+ justifyContent: "center",
185
+ fontFamily: "sans-serif"
186
+ }}>
187
+ <h1>Vader.js</h1>
188
+
189
+ <p>Zero plugin runtime.</p>
190
+
191
+ <button onClick={() => count + 1}>
192
+ Count: {count}
193
+ </button>
194
+ </div>
195
+ );
196
+ }
197
+
198
+ export default Main;
199
+ `;
200
+
201
+ await fs.writeFile(
202
+ path.join(projectDir, `app/index.${fileExt}`),
203
+ appIndexTemplate
204
+ );
205
+
206
+ /* ------------------------------------------------ Router scaffold ------------------------------------------------ */
207
+
208
+ const routerCode = `
209
+ import * as Vader from "vaderjs-native";
210
+ import { createRouter } from "vaderjs-native/router";
211
+ import Main from "../app/index";
212
+
213
+ export const router = createRouter({
214
+ routes: [
215
+ {
216
+ path: "/",
217
+ component: Main,
218
+ },
219
+ ],
220
+
221
+ fallback: function NotFound() {
222
+ return <div style={{
223
+ padding: "40px",
224
+ textAlign: "center",
225
+ fontFamily: "sans-serif"
226
+ }}>
227
+ 404 - Page Not Found
228
+ </div>;
229
+ },
230
+ });
231
+ `;
232
+
233
+ await fs.writeFile(
234
+ path.join(projectDir, "src/router.tsx"),
235
+ routerCode
236
+ );
237
+
238
+ /* ------------------------------------------------ App.tsx wrapper ------------------------------------------------ */
239
+
240
+ const appWrapper = `
241
+ import * as Vader from "vaderjs-native";
242
+ import { useRoute } from "vaderjs-native/router";
243
+ import { router } from "./src/router";
244
+
245
+ function App() {
246
+ const route = useRoute();
247
+
248
+ if (!route) {
249
+ const Fallback = router.getFallback();
250
+ return <Fallback />;
251
+ }
252
+
253
+ const Component = route.route.component;
254
+ return <Component />;
255
+ }
256
+
257
+ export default App;
258
+ `;
259
+
260
+ await fs.writeFile(path.join(projectDir, "App.tsx"), appWrapper);
261
+
262
+ /* ------------------------------------------------ jsconfig ------------------------------------------------ */
263
+
264
+ await fs.writeFile(
265
+ path.join(projectDir, "jsconfig.json"),
266
+ JSON.stringify(
267
+ {
268
+ compilerOptions: {
269
+ jsx: "react",
270
+ jsxFactory: "Vader.createElement",
271
+ jsxFragmentFactory: "Fragment",
272
+ },
273
+ include: ["app", "src"],
274
+ },
275
+ null,
276
+ 2
277
+ )
278
+ );
279
+
280
+ /* ------------------------------------------------ config ------------------------------------------------ */
281
+
282
+ const name = path.basename(projectDir);
283
+
284
+ const pluginImport = framework.pluginImport
285
+ ? framework.pluginImport + "\n"
286
+ : "";
287
+
288
+ const pluginsArray = framework.pluginRef
289
+ ? `[${framework.pluginRef}]`
290
+ : `[]`;
291
+
292
+ const config = `
293
+ ${pluginImport}
294
+ import defineConfig from "vaderjs-native/config";
295
+
296
+ export default defineConfig({
297
+ server: {
298
+ port: ${port}
299
+ },
300
+
301
+ app: {
302
+ name: "${name}",
303
+ id: "com.example.${name}",
304
+ version: { code: 1, name: "1.0.0" },
305
+ },
306
+
307
+ platforms: {
308
+ web: {
309
+ title: "${name}",
310
+ themeColor: "#111827"
311
+ }
312
+ },
313
+
314
+ plugins: ${pluginsArray}
315
+ });
316
+ `;
317
+
318
+ await fs.writeFile(
319
+ path.join(projectDir, `vaderjs.config.${configExt}`),
320
+ config
321
+ );
322
+
323
+ /* ------------------------------------------------ package.json ------------------------------------------------ */
324
+
325
+ const pkg = {
326
+ name,
327
+ version: "1.0.0",
328
+ type: "module",
329
+ dependencies: {
330
+ "vaderjs-native": "latest",
331
+ },
332
+ devDependencies: {},
333
+ };
334
+
335
+ framework.runtimeDeps?.forEach((d: string) => {
336
+ pkg.dependencies[d] = "latest";
337
+ });
338
+
339
+ framework.devDeps?.forEach((d: string) => {
340
+ pkg.devDependencies[d] = "latest";
341
+ });
342
+
343
+ await fs.writeFile(
344
+ path.join(projectDir, "package.json"),
345
+ JSON.stringify(pkg, null, 2)
346
+ );
347
+
348
+ logSection("📦 Installing dependencies");
349
+
350
+ await run("bun", ["install"]);
351
+
352
+ console.log(`\n✅ Project ready → http://localhost:${port}`);
353
+ }
package/jsconfig.json CHANGED
@@ -1,7 +1,7 @@
1
- {
2
- "compilerOptions": {
3
- "jsx": "react",
4
- "jsxFactory": "Vader.createElement",
5
- "jsxFragmentFactory": "Fragment"
6
- }
1
+ {
2
+ "compilerOptions": {
3
+ "jsx": "react",
4
+ "jsxFactory": "Vader.createElement",
5
+ "jsxFragmentFactory": "Fragment"
6
+ }
7
7
  }