juxscript 1.0.22 → 1.0.24
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/bin/cli.js +33 -40
- package/machinery/server.js +5 -29
- package/package.json +1 -1
- package/presets/hey.jux +34 -20
package/bin/cli.js
CHANGED
|
@@ -49,7 +49,6 @@ console.log(` Output: ${PATHS.frontendDist}`);
|
|
|
49
49
|
console.log(` Lib: ${PATHS.juxLib}\n`);
|
|
50
50
|
|
|
51
51
|
const command = process.argv[2];
|
|
52
|
-
const subCommand = process.argv[3]; // For serve <pagename>
|
|
53
52
|
const watchMode = process.argv.includes('--watch');
|
|
54
53
|
const bundleMode = process.argv.includes('--bundle');
|
|
55
54
|
|
|
@@ -234,18 +233,21 @@ async function buildProject(isServe = false) {
|
|
|
234
233
|
// Create structure
|
|
235
234
|
fs.mkdirSync(juxDir, { recursive: true });
|
|
236
235
|
|
|
237
|
-
// Copy hey.jux
|
|
238
|
-
const
|
|
239
|
-
const
|
|
236
|
+
// Copy hey.jux as the starter template
|
|
237
|
+
const heyJuxSrc = path.join(PATHS.packageRoot, 'presets', 'hey.jux');
|
|
238
|
+
const heyJuxDest = path.join(juxDir, 'index.jux');
|
|
240
239
|
|
|
241
|
-
if (fs.existsSync(
|
|
242
|
-
fs.copyFileSync(
|
|
243
|
-
console.log('+ Created jux/hey.jux
|
|
240
|
+
if (fs.existsSync(heyJuxSrc)) {
|
|
241
|
+
fs.copyFileSync(heyJuxSrc, heyJuxDest);
|
|
242
|
+
console.log('+ Created jux/index.jux from hey.jux template');
|
|
244
243
|
} else {
|
|
245
|
-
console.warn('⚠️ hey.jux template not found
|
|
244
|
+
console.warn('⚠️ hey.jux template not found, creating basic file');
|
|
245
|
+
const basicContent = `import { jux } from 'juxscript';\n\njux.heading('welcome').text('Welcome to JUX').render('#app');`;
|
|
246
|
+
fs.writeFileSync(heyJuxDest, basicContent);
|
|
247
|
+
console.log('+ Created jux/index.jux');
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
// Copy
|
|
250
|
+
// Copy preset styles to jux/styles/
|
|
249
251
|
const presetsSrc = path.join(PATHS.packageRoot, 'presets');
|
|
250
252
|
const stylesDest = path.join(juxDir, 'styles');
|
|
251
253
|
|
|
@@ -254,6 +256,7 @@ async function buildProject(isServe = false) {
|
|
|
254
256
|
|
|
255
257
|
const presetFiles = fs.readdirSync(presetsSrc);
|
|
256
258
|
presetFiles.forEach(file => {
|
|
259
|
+
// Only copy CSS files, skip hey.jux
|
|
257
260
|
if (file.endsWith('.css')) {
|
|
258
261
|
const srcFile = path.join(presetsSrc, file);
|
|
259
262
|
const destFile = path.join(stylesDest, file);
|
|
@@ -279,7 +282,7 @@ async function buildProject(isServe = false) {
|
|
|
279
282
|
}
|
|
280
283
|
};
|
|
281
284
|
fs.writeFileSync(pkgPath, JSON.stringify(pkgContent, null, 2));
|
|
282
|
-
console.log('
|
|
285
|
+
console.log('+ Created package.json');
|
|
283
286
|
}
|
|
284
287
|
|
|
285
288
|
// Create .gitignore
|
|
@@ -294,9 +297,10 @@ node_modules/
|
|
|
294
297
|
console.log('+ Created .gitignore');
|
|
295
298
|
}
|
|
296
299
|
|
|
297
|
-
console.log('
|
|
300
|
+
console.log('\n✅ JUX project initialized!\n');
|
|
298
301
|
console.log('Next steps:');
|
|
299
|
-
console.log('
|
|
302
|
+
console.log(' npm install # Install dependencies');
|
|
303
|
+
console.log(' npx jux serve # Start dev server with hot reload\n');
|
|
300
304
|
console.log('Check out the docs: https://juxscript.com/docs\n');
|
|
301
305
|
|
|
302
306
|
} else if (command === 'build') {
|
|
@@ -305,37 +309,28 @@ node_modules/
|
|
|
305
309
|
console.log(`✅ Build complete: ${PATHS.frontendDist}`);
|
|
306
310
|
|
|
307
311
|
} else if (command === 'serve') {
|
|
308
|
-
// ✅
|
|
309
|
-
const pageName = subCommand; // e.g., "hey" from "npx jux serve hey"
|
|
310
|
-
|
|
311
|
-
if (pageName) {
|
|
312
|
-
console.log(`🎯 Serving specific page: ${pageName}\n`);
|
|
313
|
-
}
|
|
314
|
-
|
|
312
|
+
// ✅ Always serves router bundle
|
|
315
313
|
await buildProject(true);
|
|
316
314
|
|
|
317
|
-
const port =
|
|
318
|
-
|
|
319
|
-
// Start server
|
|
320
|
-
await start(port, pageName);
|
|
315
|
+
const port = parseInt(process.argv[3]) || 3000;
|
|
316
|
+
await start(port);
|
|
321
317
|
|
|
322
318
|
} else {
|
|
323
319
|
console.log(`
|
|
324
320
|
JUX CLI - A JavaScript UX authorship platform
|
|
325
321
|
|
|
326
322
|
Usage:
|
|
327
|
-
npx jux init
|
|
328
|
-
npx jux build
|
|
329
|
-
npx jux serve [
|
|
330
|
-
npx jux serve [port] Start dev server on custom port
|
|
323
|
+
npx jux init Initialize a new JUX project
|
|
324
|
+
npx jux build Build router bundle to ./jux-dist/
|
|
325
|
+
npx jux serve [port] Start dev server with hot reload (default: 3000)
|
|
331
326
|
|
|
332
327
|
Project Structure:
|
|
333
328
|
my-project/
|
|
334
329
|
├── jux/ # Your .jux source files
|
|
335
|
-
│ ├──
|
|
336
|
-
│ └── pages/
|
|
337
|
-
├── jux-dist/
|
|
338
|
-
├── server/
|
|
330
|
+
│ ├── index.jux # Entry point
|
|
331
|
+
│ └── pages/ # Additional pages
|
|
332
|
+
├── jux-dist/ # Build output (git-ignore this)
|
|
333
|
+
├── server/ # Your backend
|
|
339
334
|
└── package.json
|
|
340
335
|
|
|
341
336
|
Import Style:
|
|
@@ -344,17 +339,15 @@ Import Style:
|
|
|
344
339
|
import 'juxscript/presets/notion.js';
|
|
345
340
|
|
|
346
341
|
Getting Started:
|
|
347
|
-
1. npx jux init
|
|
348
|
-
2. npm install
|
|
349
|
-
3. npx jux serve
|
|
350
|
-
4.
|
|
351
|
-
5. Serve jux-dist/ from your backend
|
|
342
|
+
1. npx jux init # Create project structure
|
|
343
|
+
2. npm install # Install dependencies
|
|
344
|
+
3. npx jux serve # Dev server with hot reload
|
|
345
|
+
4. Serve jux-dist/ from your backend
|
|
352
346
|
|
|
353
347
|
Examples:
|
|
354
|
-
npx jux build
|
|
355
|
-
npx jux serve
|
|
356
|
-
npx jux serve
|
|
357
|
-
npx jux serve 8080 Start dev server on port 8080
|
|
348
|
+
npx jux build Build production bundle
|
|
349
|
+
npx jux serve Start dev server on port 3000
|
|
350
|
+
npx jux serve 8080 Start dev server on port 8080
|
|
358
351
|
`);
|
|
359
352
|
}
|
|
360
353
|
})();
|
package/machinery/server.js
CHANGED
|
@@ -87,12 +87,9 @@ async function serve(port = 3000, distDir = './jux-dist') {
|
|
|
87
87
|
|
|
88
88
|
// Start HTTP server
|
|
89
89
|
server.listen(port, () => {
|
|
90
|
-
console.log(
|
|
91
|
-
console.log(`
|
|
92
|
-
|
|
93
|
-
console.log(` (Root redirects to /${pageName})`);
|
|
94
|
-
}
|
|
95
|
-
console.log('');
|
|
90
|
+
console.log(`🚀 JUX dev server running at http://localhost:${port}`);
|
|
91
|
+
console.log(` Serving: ${absoluteDistDir}`);
|
|
92
|
+
console.log(` Press Ctrl+C to stop\n`);
|
|
96
93
|
});
|
|
97
94
|
|
|
98
95
|
// Start file watcher
|
|
@@ -116,27 +113,6 @@ async function serve(port = 3000, distDir = './jux-dist') {
|
|
|
116
113
|
return { server };
|
|
117
114
|
}
|
|
118
115
|
|
|
119
|
-
export async function start(port = 3000
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
// ...existing code for static files...
|
|
123
|
-
|
|
124
|
-
// If pageName specified, redirect root to that page
|
|
125
|
-
if (pageName) {
|
|
126
|
-
app.get('/', (req, res) => {
|
|
127
|
-
res.redirect(`/${pageName}`);
|
|
128
|
-
});
|
|
129
|
-
console.log(`🎯 Root (/) redirects to /${pageName}`);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// ...existing code...
|
|
133
|
-
|
|
134
|
-
app.listen(port, () => {
|
|
135
|
-
console.log(`\n🚀 JUX dev server running`);
|
|
136
|
-
console.log(` Local: http://localhost:${port}${pageName ? '/' + pageName : ''}`);
|
|
137
|
-
if (pageName) {
|
|
138
|
-
console.log(` (Root redirects to /${pageName})`);
|
|
139
|
-
}
|
|
140
|
-
console.log('');
|
|
141
|
-
});
|
|
116
|
+
export async function start(port = 3000) {
|
|
117
|
+
return serve(port, './jux-dist');
|
|
142
118
|
}
|
package/package.json
CHANGED
package/presets/hey.jux
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jux } from 'juxscript';
|
|
2
2
|
|
|
3
|
-
// Welcome page
|
|
4
|
-
jux.hero('welcome
|
|
3
|
+
// Welcome page with examples
|
|
4
|
+
jux.hero('welcome', {
|
|
5
5
|
title: 'Welcome to JUX',
|
|
6
6
|
subtitle: 'A JavaScript UX authorship platform'
|
|
7
7
|
}).render('#app');
|
|
@@ -12,35 +12,49 @@ jux.container('getting-started')
|
|
|
12
12
|
.style('max-width: 800px; margin: 2rem auto; padding: 2rem;')
|
|
13
13
|
.render('#app');
|
|
14
14
|
|
|
15
|
-
jux.heading('
|
|
15
|
+
jux.heading('start-heading')
|
|
16
16
|
.level(2)
|
|
17
17
|
.text('Getting Started')
|
|
18
18
|
.render('#getting-started');
|
|
19
19
|
|
|
20
|
-
jux.paragraph('
|
|
21
|
-
.text('Edit
|
|
20
|
+
jux.paragraph('start-intro')
|
|
21
|
+
.text('Edit this file to build your app. Here are some quick tips:')
|
|
22
22
|
.style('margin: 1rem 0;')
|
|
23
23
|
.render('#getting-started');
|
|
24
24
|
|
|
25
|
-
jux.list('
|
|
25
|
+
jux.list('quick-tips', {
|
|
26
26
|
items: [
|
|
27
|
-
'Run npx jux
|
|
28
|
-
'Run npx jux
|
|
29
|
-
'
|
|
30
|
-
'
|
|
27
|
+
'Run npx jux serve for dev mode with hot reload',
|
|
28
|
+
'Run npx jux build to compile for production',
|
|
29
|
+
'Serve jux-dist/ from your backend',
|
|
30
|
+
'Check out the docs at juxscript.com/docs'
|
|
31
31
|
]
|
|
32
32
|
}).render('#getting-started');
|
|
33
33
|
|
|
34
34
|
jux.divider().render('#app');
|
|
35
35
|
|
|
36
|
-
jux.
|
|
37
|
-
.
|
|
38
|
-
.variant('primary')
|
|
39
|
-
.bind('click', () => {
|
|
40
|
-
jux.alert('demo-alert')
|
|
41
|
-
.type('success')
|
|
42
|
-
.message('Button clicked! You are ready to build with JUX.')
|
|
43
|
-
.render('#app');
|
|
44
|
-
})
|
|
45
|
-
.style('margin: 2rem auto; display: block;')
|
|
36
|
+
jux.container('example-container')
|
|
37
|
+
.style('max-width: 800px; margin: 2rem auto; padding: 2rem; background: #f9fafb; border-radius: 8px;')
|
|
46
38
|
.render('#app');
|
|
39
|
+
|
|
40
|
+
jux.heading('example-heading')
|
|
41
|
+
.level(3)
|
|
42
|
+
.text('Quick Example')
|
|
43
|
+
.render('#example-container');
|
|
44
|
+
|
|
45
|
+
jux.code('example-code')
|
|
46
|
+
.language('javascript')
|
|
47
|
+
.code(`import { jux, state } from 'juxscript';
|
|
48
|
+
|
|
49
|
+
// Create a reactive counter
|
|
50
|
+
const count = state(0);
|
|
51
|
+
|
|
52
|
+
jux.button('increment')
|
|
53
|
+
.label('Click me!')
|
|
54
|
+
.bind('click', () => count.value++)
|
|
55
|
+
.render('#app');
|
|
56
|
+
|
|
57
|
+
jux.paragraph('counter')
|
|
58
|
+
.sync('text', count, val => \`Count: \${val}\`)
|
|
59
|
+
.render('#app');`)
|
|
60
|
+
.render('#example-container');
|