juxscript 1.0.19 → 1.0.21
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 +121 -72
- package/lib/components/alert.ts +212 -165
- package/lib/components/badge.ts +93 -103
- package/lib/components/base/BaseComponent.ts +397 -0
- package/lib/components/base/FormInput.ts +322 -0
- package/lib/components/button.ts +63 -122
- package/lib/components/card.ts +109 -155
- package/lib/components/charts/areachart.ts +315 -0
- package/lib/components/charts/barchart.ts +421 -0
- package/lib/components/charts/doughnutchart.ts +263 -0
- package/lib/components/charts/lib/BaseChart.ts +402 -0
- package/lib/components/charts/lib/chart-types.ts +159 -0
- package/lib/components/charts/lib/chart-utils.ts +160 -0
- package/lib/components/charts/lib/chart.ts +707 -0
- package/lib/components/checkbox.ts +264 -127
- package/lib/components/code.ts +75 -108
- package/lib/components/container.ts +113 -130
- package/lib/components/data.ts +37 -5
- package/lib/components/datepicker.ts +195 -147
- package/lib/components/dialog.ts +187 -157
- package/lib/components/divider.ts +85 -191
- package/lib/components/docs-data.json +544 -2027
- package/lib/components/dropdown.ts +178 -136
- package/lib/components/element.ts +227 -171
- package/lib/components/fileupload.ts +285 -228
- package/lib/components/guard.ts +92 -0
- package/lib/components/heading.ts +46 -69
- package/lib/components/helpers.ts +13 -6
- package/lib/components/hero.ts +107 -95
- package/lib/components/icon.ts +160 -0
- package/lib/components/icons.ts +175 -0
- package/lib/components/include.ts +153 -5
- package/lib/components/input.ts +174 -374
- package/lib/components/kpicard.ts +16 -16
- package/lib/components/list.ts +378 -240
- package/lib/components/loading.ts +142 -211
- package/lib/components/menu.ts +103 -97
- package/lib/components/modal.ts +138 -144
- package/lib/components/nav.ts +169 -90
- package/lib/components/paragraph.ts +49 -150
- package/lib/components/progress.ts +118 -200
- package/lib/components/radio.ts +297 -149
- package/lib/components/script.ts +19 -87
- package/lib/components/select.ts +184 -186
- package/lib/components/sidebar.ts +152 -140
- package/lib/components/style.ts +19 -82
- package/lib/components/switch.ts +258 -188
- package/lib/components/table.ts +1117 -170
- package/lib/components/tabs.ts +162 -145
- package/lib/components/theme-toggle.ts +108 -169
- package/lib/components/tooltip.ts +86 -157
- package/lib/components/write.ts +108 -127
- package/lib/jux.ts +86 -41
- package/machinery/build.js +466 -0
- package/machinery/compiler.js +354 -105
- package/machinery/server.js +23 -100
- package/machinery/watcher.js +153 -130
- package/package.json +1 -2
- package/presets/base.css +1166 -0
- package/presets/notion.css +2 -1975
- package/lib/adapters/base-adapter.js +0 -35
- package/lib/adapters/index.js +0 -33
- package/lib/adapters/mysql-adapter.js +0 -65
- package/lib/adapters/postgres-adapter.js +0 -70
- package/lib/adapters/sqlite-adapter.js +0 -56
- package/lib/components/areachart.ts +0 -1246
- package/lib/components/areachartsmooth.ts +0 -1380
- package/lib/components/barchart.ts +0 -1250
- package/lib/components/chart.ts +0 -127
- package/lib/components/doughnutchart.ts +0 -1191
- package/lib/components/footer.ts +0 -165
- package/lib/components/header.ts +0 -187
- package/lib/components/layout.ts +0 -239
- package/lib/components/main.ts +0 -137
- package/lib/layouts/default.jux +0 -8
- package/lib/layouts/figma.jux +0 -0
- /package/lib/{themes → components/charts/lib}/charts.js +0 -0
package/bin/cli.js
CHANGED
|
@@ -1,6 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
copyLibToOutput,
|
|
5
|
+
copyProjectAssets,
|
|
6
|
+
transpileProjectTypeScript,
|
|
7
|
+
copyPresetsToOutput,
|
|
8
|
+
bundleJuxFilesToRouter,
|
|
9
|
+
generateIndexHtml
|
|
10
|
+
} from '../machinery/compiler.js';
|
|
4
11
|
import { generateDocs } from '../machinery/doc-generator.js';
|
|
5
12
|
import { start } from '../machinery/server.js';
|
|
6
13
|
import path from 'path';
|
|
@@ -42,13 +49,11 @@ console.log(` Output: ${PATHS.frontendDist}`);
|
|
|
42
49
|
console.log(` Lib: ${PATHS.juxLib}\n`);
|
|
43
50
|
|
|
44
51
|
const command = process.argv[2];
|
|
52
|
+
const watchMode = process.argv.includes('--watch');
|
|
53
|
+
const bundleMode = process.argv.includes('--bundle');
|
|
45
54
|
|
|
46
55
|
/**
|
|
47
56
|
* Recursively find .jux files in a directory
|
|
48
|
-
*
|
|
49
|
-
* @param {string} dir - Directory to search
|
|
50
|
-
* @param {string[]} fileList - Accumulator for found files
|
|
51
|
-
* @returns {string[]} Array of .jux file paths
|
|
52
57
|
*/
|
|
53
58
|
function findJuxFiles(dir, fileList = []) {
|
|
54
59
|
if (!fs.existsSync(dir)) return fileList;
|
|
@@ -72,11 +77,12 @@ function findJuxFiles(dir, fileList = []) {
|
|
|
72
77
|
}
|
|
73
78
|
|
|
74
79
|
/**
|
|
75
|
-
* Build the entire JUX project
|
|
80
|
+
* Build the entire JUX project (ALWAYS uses router bundle)
|
|
76
81
|
*
|
|
77
|
-
* @param {boolean} isServe - Whether building for dev server
|
|
82
|
+
* @param {boolean} isServe - Whether building for dev server
|
|
78
83
|
*/
|
|
79
84
|
async function buildProject(isServe = false) {
|
|
85
|
+
const buildStartTime = performance.now();
|
|
80
86
|
console.log('🔨 Building JUX frontend...\n');
|
|
81
87
|
|
|
82
88
|
try {
|
|
@@ -93,80 +99,121 @@ async function buildProject(isServe = false) {
|
|
|
93
99
|
}
|
|
94
100
|
fs.mkdirSync(PATHS.frontendDist, { recursive: true });
|
|
95
101
|
|
|
96
|
-
// Step 1: Generate documentation
|
|
102
|
+
// Step 1: Generate documentation
|
|
103
|
+
const docsStartTime = performance.now();
|
|
104
|
+
let docsTime = 0; // ✅ Declare with default value
|
|
97
105
|
console.log('📚 Generating documentation...');
|
|
98
106
|
try {
|
|
99
107
|
await generateDocs(PATHS.juxLib);
|
|
100
|
-
|
|
108
|
+
docsTime = performance.now() - docsStartTime;
|
|
109
|
+
console.log(`✅ Documentation generated (${docsTime.toFixed(0)}ms)\n`);
|
|
101
110
|
} catch (error) {
|
|
102
|
-
|
|
111
|
+
docsTime = performance.now() - docsStartTime; // ✅ Still calculate time even on error
|
|
112
|
+
console.warn(`⚠️ Failed to generate docs (${docsTime.toFixed(0)}ms):`, error.message);
|
|
103
113
|
}
|
|
104
114
|
|
|
105
115
|
// Step 2: Copy jux lib to frontend dist
|
|
116
|
+
const libStartTime = performance.now();
|
|
106
117
|
await copyLibToOutput(PATHS.juxLib, PATHS.frontendDist);
|
|
118
|
+
const libTime = performance.now() - libStartTime;
|
|
119
|
+
console.log(`⏱️ Lib copy time: ${libTime.toFixed(0)}ms\n`);
|
|
107
120
|
|
|
108
|
-
// Step
|
|
121
|
+
// Step 3: Copy presets folder
|
|
122
|
+
const presetsStartTime = performance.now();
|
|
109
123
|
await copyPresetsToOutput(PATHS.packageRoot, PATHS.frontendDist);
|
|
124
|
+
const presetsTime = performance.now() - presetsStartTime;
|
|
125
|
+
console.log(`⏱️ Presets copy time: ${presetsTime.toFixed(0)}ms\n`);
|
|
110
126
|
|
|
111
|
-
// Step
|
|
127
|
+
// Step 4: Copy project assets (CSS, JS, images)
|
|
128
|
+
const assetsStartTime = performance.now();
|
|
112
129
|
await copyProjectAssets(PATHS.juxSource, PATHS.frontendDist);
|
|
130
|
+
const assetsTime = performance.now() - assetsStartTime;
|
|
131
|
+
console.log(`⏱️ Assets copy time: ${assetsTime.toFixed(0)}ms\n`);
|
|
113
132
|
|
|
114
|
-
// Step
|
|
133
|
+
// Step 5: Transpile TypeScript files
|
|
134
|
+
const tsStartTime = performance.now();
|
|
115
135
|
await transpileProjectTypeScript(PATHS.juxSource, PATHS.frontendDist);
|
|
136
|
+
const tsTime = performance.now() - tsStartTime;
|
|
137
|
+
console.log(`⏱️ TypeScript transpile time: ${tsTime.toFixed(0)}ms\n`);
|
|
116
138
|
|
|
117
|
-
// Step
|
|
139
|
+
// Step 6: Bundle all .jux files into router
|
|
118
140
|
const projectJuxFiles = findJuxFiles(PATHS.juxSource);
|
|
119
141
|
console.log(`📝 Found ${projectJuxFiles.length} .jux file(s) in /jux\n`);
|
|
120
142
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
distDir: PATHS.frontendDist,
|
|
125
|
-
projectRoot: PATHS.juxSource,
|
|
126
|
-
isServe
|
|
127
|
-
});
|
|
128
|
-
} catch (err) {
|
|
129
|
-
console.error(`Error compiling ${file}:`, err.message);
|
|
130
|
-
}
|
|
143
|
+
if (projectJuxFiles.length === 0) {
|
|
144
|
+
console.warn('⚠️ No .jux files found to bundle');
|
|
145
|
+
process.exit(1);
|
|
131
146
|
}
|
|
132
147
|
|
|
133
|
-
//
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
}
|
|
148
|
+
// ✅ Bundle and get the generated filename
|
|
149
|
+
const bundleStartTime = performance.now();
|
|
150
|
+
const mainJsFilename = await bundleJuxFilesToRouter(PATHS.juxSource, PATHS.frontendDist, {
|
|
151
|
+
routePrefix: ''
|
|
152
|
+
});
|
|
153
|
+
const bundleTime = performance.now() - bundleStartTime;
|
|
154
|
+
|
|
155
|
+
// Generate routes for index.html
|
|
156
|
+
const routes = projectJuxFiles.map(juxFile => {
|
|
157
|
+
const relativePath = path.relative(PATHS.juxSource, juxFile);
|
|
158
|
+
const parsedPath = path.parse(relativePath);
|
|
159
|
+
|
|
160
|
+
const rawFunctionName = parsedPath.dir
|
|
161
|
+
? `${parsedPath.dir.replace(/\//g, '_')}_${parsedPath.name}`
|
|
162
|
+
: parsedPath.name;
|
|
163
|
+
|
|
164
|
+
const functionName = rawFunctionName
|
|
165
|
+
.replace(/[-_]/g, ' ')
|
|
166
|
+
.split(' ')
|
|
167
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
168
|
+
.join('');
|
|
169
|
+
|
|
170
|
+
const routePath = '/' + (parsedPath.dir ? `${parsedPath.dir}/` : '') + parsedPath.name;
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
path: routePath.replace(/\/+/g, '/'),
|
|
174
|
+
functionName
|
|
175
|
+
};
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// ✅ Generate unified index.html
|
|
179
|
+
const indexStartTime = performance.now();
|
|
180
|
+
generateIndexHtml(PATHS.frontendDist, routes, mainJsFilename);
|
|
181
|
+
const indexTime = performance.now() - indexStartTime;
|
|
182
|
+
|
|
183
|
+
const totalBuildTime = performance.now() - buildStartTime;
|
|
184
|
+
|
|
185
|
+
console.log(`\n✅ Bundled ${projectJuxFiles.length} page(s) → ${PATHS.frontendDist}/${mainJsFilename}\n`);
|
|
186
|
+
|
|
187
|
+
// ✅ Build summary with timing breakdown
|
|
188
|
+
console.log(`📊 Build Summary:`);
|
|
189
|
+
console.log(` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
190
|
+
console.log(` Documentation: ${docsTime.toFixed(0)}ms`);
|
|
191
|
+
console.log(` Library copy: ${libTime.toFixed(0)}ms`);
|
|
192
|
+
console.log(` Presets copy: ${presetsTime.toFixed(0)}ms`);
|
|
193
|
+
console.log(` Assets copy: ${assetsTime.toFixed(0)}ms`);
|
|
194
|
+
console.log(` TypeScript: ${tsTime.toFixed(0)}ms`);
|
|
195
|
+
console.log(` Router bundle: ${bundleTime.toFixed(0)}ms`);
|
|
196
|
+
console.log(` Index generation: ${indexTime.toFixed(0)}ms`);
|
|
197
|
+
console.log(` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━`);
|
|
198
|
+
console.log(` Total build time: ${totalBuildTime.toFixed(0)}ms\n`);
|
|
199
|
+
|
|
200
|
+
// Show usage
|
|
201
|
+
if (!isServe) {
|
|
202
|
+
console.log('📦 Serve from your backend:');
|
|
203
|
+
console.log(` Express: app.use(express.static('jux-dist'))`);
|
|
204
|
+
console.log(` Flask: app = Flask(__name__, static_folder='jux-dist')`);
|
|
205
|
+
console.log(` FastAPI: app.mount("/", StaticFiles(directory="jux-dist"), name="static")`);
|
|
206
|
+
console.log('');
|
|
207
|
+
console.log('📍 Available routes:');
|
|
208
|
+
routes.forEach(r => {
|
|
209
|
+
console.log(` ${r.path}`);
|
|
210
|
+
});
|
|
211
|
+
console.log('');
|
|
156
212
|
}
|
|
157
213
|
|
|
158
|
-
console.log(`\n✅ Built ${projectJuxFiles.length} file(s) → ${PATHS.frontendDist}\n`);
|
|
159
|
-
|
|
160
|
-
// Show backend integration examples
|
|
161
|
-
console.log('📦 Serve from your backend:');
|
|
162
|
-
console.log(` Express: app.use(express.static('jux-dist'))`);
|
|
163
|
-
console.log(` Flask: app = Flask(__name__, static_folder='jux-dist')`);
|
|
164
|
-
console.log(` FastAPI: app.mount("/", StaticFiles(directory="jux-dist"), name="static")`);
|
|
165
|
-
console.log(` Laravel: Route::view('/', 'jux-dist/index.html')`);
|
|
166
|
-
console.log('');
|
|
167
|
-
|
|
168
214
|
} catch (err) {
|
|
169
|
-
|
|
215
|
+
const failTime = performance.now() - buildStartTime;
|
|
216
|
+
console.error(`❌ Build error after ${failTime.toFixed(0)}ms:`, err.message);
|
|
170
217
|
console.error(err.stack);
|
|
171
218
|
process.exit(1);
|
|
172
219
|
}
|
|
@@ -261,10 +308,12 @@ node_modules/
|
|
|
261
308
|
console.log(' 4. Serve jux-dist/ from your backend\n');
|
|
262
309
|
|
|
263
310
|
} else if (command === 'build') {
|
|
311
|
+
// ✅ Always builds router bundle
|
|
264
312
|
await buildProject(false);
|
|
265
313
|
console.log(`✅ Build complete: ${PATHS.frontendDist}`);
|
|
266
314
|
|
|
267
315
|
} else if (command === 'serve') {
|
|
316
|
+
// ✅ Always serves router bundle
|
|
268
317
|
await buildProject(true);
|
|
269
318
|
|
|
270
319
|
const port = parseInt(process.argv[3]) || 3000;
|
|
@@ -275,17 +324,17 @@ node_modules/
|
|
|
275
324
|
JUX CLI - A JavaScript UX authorship platform
|
|
276
325
|
|
|
277
326
|
Usage:
|
|
278
|
-
npx jux init
|
|
279
|
-
npx jux build
|
|
280
|
-
npx jux serve [port]
|
|
327
|
+
npx jux init Initialize a new JUX project
|
|
328
|
+
npx jux build Build router bundle to ./jux-dist/
|
|
329
|
+
npx jux serve [port] Start dev server with hot reload (default: 3000)
|
|
281
330
|
|
|
282
331
|
Project Structure:
|
|
283
332
|
my-project/
|
|
284
|
-
├── jux/
|
|
285
|
-
│ ├── index.jux
|
|
286
|
-
│ └── pages/
|
|
287
|
-
├── jux-dist/
|
|
288
|
-
├── server/
|
|
333
|
+
├── jux/ # Your .jux source files
|
|
334
|
+
│ ├── index.jux # Entry point
|
|
335
|
+
│ └── pages/ # Additional pages
|
|
336
|
+
├── jux-dist/ # Build output (git-ignore this)
|
|
337
|
+
├── server/ # Your backend
|
|
289
338
|
└── package.json
|
|
290
339
|
|
|
291
340
|
Import Style:
|
|
@@ -294,15 +343,15 @@ Import Style:
|
|
|
294
343
|
import 'juxscript/presets/notion.js';
|
|
295
344
|
|
|
296
345
|
Getting Started:
|
|
297
|
-
1. npx jux init
|
|
298
|
-
2. npm install
|
|
299
|
-
3. npx jux
|
|
346
|
+
1. npx jux init # Create project structure
|
|
347
|
+
2. npm install # Install dependencies
|
|
348
|
+
3. npx jux serve # Dev server with hot reload
|
|
300
349
|
4. Serve jux-dist/ from your backend
|
|
301
350
|
|
|
302
351
|
Examples:
|
|
303
|
-
npx jux build
|
|
304
|
-
npx jux serve
|
|
305
|
-
npx jux serve 8080
|
|
352
|
+
npx jux build Build production bundle
|
|
353
|
+
npx jux serve Start dev server on port 3000
|
|
354
|
+
npx jux serve 8080 Start dev server on port 8080
|
|
306
355
|
`);
|
|
307
356
|
}
|
|
308
357
|
})();
|