juxscript 1.0.8 → 1.0.10
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 +12 -4
- package/bin/cli.js +66 -38
- package/lib/components/divider.ts +233 -0
- package/lib/components/docs-data.json +70 -1
- package/lib/components/hero1/hero1.ts +196 -0
- package/lib/components/hero1/index.js +4 -0
- package/lib/components/kpicard.ts +43 -8
- package/lib/components/sidebar.ts +13 -5
- package/lib/jux.ts +8 -4
- package/machinery/compiler.js +21 -4
- package/machinery/server.js +19 -16
- package/package.json +33 -51
- package/lib/presets/global.css +0 -1131
- package/lib/presets/notion.css +0 -521
- package/lib/presets/notion.jux +0 -27
- package/machinery/generators/css.js +0 -128
- package/machinery/generators/html.js +0 -107
|
@@ -242,6 +242,11 @@ export class KPICard {
|
|
|
242
242
|
return this;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
+
// Remove existing element if it exists
|
|
246
|
+
if (this._element && this._element.parentNode) {
|
|
247
|
+
this._element.parentNode.removeChild(this._element);
|
|
248
|
+
}
|
|
249
|
+
|
|
245
250
|
this._loadThemeFont();
|
|
246
251
|
this._buildCard(element as HTMLElement);
|
|
247
252
|
return this;
|
|
@@ -253,8 +258,11 @@ export class KPICard {
|
|
|
253
258
|
const element = document.querySelector(this._container);
|
|
254
259
|
if (!element) return;
|
|
255
260
|
|
|
256
|
-
//
|
|
257
|
-
|
|
261
|
+
// Remove existing element
|
|
262
|
+
if (this._element && this._element.parentNode) {
|
|
263
|
+
this._element.parentNode.removeChild(this._element);
|
|
264
|
+
}
|
|
265
|
+
|
|
258
266
|
this._loadThemeFont();
|
|
259
267
|
this._buildCard(element as HTMLElement);
|
|
260
268
|
}
|
|
@@ -317,6 +325,9 @@ export class KPICard {
|
|
|
317
325
|
const baseHeight = 200;
|
|
318
326
|
const scaleFactor = Math.min(width / baseWidth, height / baseHeight);
|
|
319
327
|
|
|
328
|
+
// Determine if we're in dark mode based on style mode
|
|
329
|
+
const isDarkMode = styleMode === 'gradient' || styleMode === 'glass';
|
|
330
|
+
|
|
320
331
|
const content = document.createElement('div');
|
|
321
332
|
content.className = 'jux-kpicard-content';
|
|
322
333
|
content.style.cssText = `
|
|
@@ -331,10 +342,19 @@ export class KPICard {
|
|
|
331
342
|
const titleEl = document.createElement('div');
|
|
332
343
|
titleEl.className = 'jux-kpicard-title';
|
|
333
344
|
titleEl.textContent = title;
|
|
345
|
+
|
|
346
|
+
// Smart color selection based on theme
|
|
347
|
+
let titleColor = '#6b7280'; // default light mode
|
|
348
|
+
if (styleMode === 'gradient') {
|
|
349
|
+
titleColor = 'rgba(255, 255, 255, 0.95)';
|
|
350
|
+
} else if (styleMode === 'glass') {
|
|
351
|
+
titleColor = 'rgba(31, 41, 55, 0.9)'; // dark text for glass effect
|
|
352
|
+
}
|
|
353
|
+
|
|
334
354
|
titleEl.style.cssText = `
|
|
335
355
|
font-size: ${16 * scaleFactor}px;
|
|
336
356
|
font-weight: 500;
|
|
337
|
-
color: ${
|
|
357
|
+
color: ${titleColor};
|
|
338
358
|
margin-bottom: ${16 * scaleFactor}px;
|
|
339
359
|
font-family: ${themeConfig.variables['--chart-font-family']};
|
|
340
360
|
`;
|
|
@@ -352,10 +372,19 @@ export class KPICard {
|
|
|
352
372
|
const valueEl = document.createElement('div');
|
|
353
373
|
valueEl.className = 'jux-kpicard-value';
|
|
354
374
|
valueEl.textContent = `${prefix}${value}${suffix}`;
|
|
375
|
+
|
|
376
|
+
// Smart color selection for value
|
|
377
|
+
let valueColor = '#1f2937'; // default dark
|
|
378
|
+
if (styleMode === 'gradient') {
|
|
379
|
+
valueColor = '#ffffff';
|
|
380
|
+
} else if (styleMode === 'glass') {
|
|
381
|
+
valueColor = '#111827'; // very dark for glass
|
|
382
|
+
}
|
|
383
|
+
|
|
355
384
|
valueEl.style.cssText = `
|
|
356
385
|
font-size: ${56 * scaleFactor}px;
|
|
357
386
|
font-weight: 800;
|
|
358
|
-
color: ${
|
|
387
|
+
color: ${valueColor};
|
|
359
388
|
line-height: 1;
|
|
360
389
|
font-family: ${themeConfig.variables['--chart-font-family']};
|
|
361
390
|
${styleMode === 'glow' ? `text-shadow: 0 0 ${20 * scaleFactor}px ${themeConfig.colors[0]}40;` : ''}
|
|
@@ -391,12 +420,18 @@ export class KPICard {
|
|
|
391
420
|
const arrow = this._createArrowSVG(delta > 0, styleMode === 'gradient', scaleFactor);
|
|
392
421
|
deltaContainer.appendChild(arrow);
|
|
393
422
|
|
|
394
|
-
// Delta text
|
|
423
|
+
// Delta text with smart coloring
|
|
395
424
|
const deltaText = document.createElement('span');
|
|
396
425
|
deltaText.textContent = `${delta > 0 ? '+' : ''}${delta}%`;
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
426
|
+
|
|
427
|
+
let deltaColor;
|
|
428
|
+
if (styleMode === 'gradient') {
|
|
429
|
+
deltaColor = delta > 0 ? 'rgba(255, 255, 255, 0.95)' : 'rgba(255, 200, 200, 0.95)';
|
|
430
|
+
} else if (styleMode === 'glass') {
|
|
431
|
+
deltaColor = delta > 0 ? '#10b981' : '#ef4444';
|
|
432
|
+
} else {
|
|
433
|
+
deltaColor = delta > 0 ? '#10b981' : '#ef4444';
|
|
434
|
+
}
|
|
400
435
|
|
|
401
436
|
deltaText.style.cssText = `
|
|
402
437
|
font-size: ${18 * scaleFactor}px;
|
|
@@ -18,7 +18,7 @@ export interface SidebarOptions {
|
|
|
18
18
|
*/
|
|
19
19
|
type SidebarState = {
|
|
20
20
|
title: string;
|
|
21
|
-
width: string;
|
|
21
|
+
width: string | null;
|
|
22
22
|
position: string;
|
|
23
23
|
collapsible: boolean;
|
|
24
24
|
collapsed: boolean;
|
|
@@ -49,7 +49,7 @@ export class Sidebar {
|
|
|
49
49
|
|
|
50
50
|
this.state = {
|
|
51
51
|
title: options.title ?? '',
|
|
52
|
-
width: options.width ??
|
|
52
|
+
width: options.width ?? null, // No default width - let CSS handle it
|
|
53
53
|
position: options.position ?? 'left',
|
|
54
54
|
collapsible: options.collapsible ?? false,
|
|
55
55
|
collapsed: options.collapsed ?? false,
|
|
@@ -117,10 +117,14 @@ export class Sidebar {
|
|
|
117
117
|
|
|
118
118
|
if (collapsed) {
|
|
119
119
|
sidebar.classList.add('jux-sidebar-collapsed');
|
|
120
|
-
|
|
120
|
+
if (width) {
|
|
121
|
+
sidebar.style.width = '0';
|
|
122
|
+
}
|
|
121
123
|
} else {
|
|
122
124
|
sidebar.classList.remove('jux-sidebar-collapsed');
|
|
123
|
-
|
|
125
|
+
if (width) {
|
|
126
|
+
sidebar.style.width = width;
|
|
127
|
+
}
|
|
124
128
|
}
|
|
125
129
|
|
|
126
130
|
const toggleBtn = sidebar.querySelector('.jux-sidebar-toggle');
|
|
@@ -152,7 +156,11 @@ export class Sidebar {
|
|
|
152
156
|
const sidebar = document.createElement('aside');
|
|
153
157
|
sidebar.className = `jux-sidebar jux-sidebar-${position}`;
|
|
154
158
|
sidebar.id = this._id;
|
|
155
|
-
|
|
159
|
+
|
|
160
|
+
// Only set width if explicitly provided
|
|
161
|
+
if (width) {
|
|
162
|
+
sidebar.style.width = collapsed ? '0' : width;
|
|
163
|
+
}
|
|
156
164
|
|
|
157
165
|
if (className) {
|
|
158
166
|
sidebar.className += ` ${className}`;
|
package/lib/jux.ts
CHANGED
|
@@ -51,9 +51,10 @@ import { heading, Heading, type HeadingOptions } from './components/heading.js';
|
|
|
51
51
|
import { paragraph, Paragraph, type ParagraphOptions } from './components/paragraph.js';
|
|
52
52
|
import { barchart, BarChart, type BarChartOptions, type BarChartDataPoint } from './components/barchart.js';
|
|
53
53
|
import { areachart, AreaChart, type AreaChartOptions, type AreaChartDataPoint } from './components/areachart.js';
|
|
54
|
-
import { areachartsmooth, AreaChartSmooth, type AreaChartSmoothOptions, AreaChartSmoothDataPoint
|
|
54
|
+
import { areachartsmooth, AreaChartSmooth, type AreaChartSmoothOptions, AreaChartSmoothDataPoint } from './components/areachartsmooth.js';
|
|
55
55
|
import { doughnutchart, DoughnutChart, type DoughnutChartOptions, type DoughnutChartDataPoint } from './components/doughnutchart.js';
|
|
56
56
|
import { kpicard, KPICard, type KPICardOptions } from './components/kpicard.js';
|
|
57
|
+
import { divider, Divider, type DividerOptions } from './components/divider.js';
|
|
57
58
|
|
|
58
59
|
/* -------------------------
|
|
59
60
|
* Type Exports
|
|
@@ -116,7 +117,8 @@ export type {
|
|
|
116
117
|
AreaChartSmoothDataPoint,
|
|
117
118
|
DoughnutChartOptions,
|
|
118
119
|
DoughnutChartDataPoint,
|
|
119
|
-
KPICardOptions
|
|
120
|
+
KPICardOptions,
|
|
121
|
+
DividerOptions
|
|
120
122
|
};
|
|
121
123
|
|
|
122
124
|
/* -------------------------
|
|
@@ -172,7 +174,8 @@ export {
|
|
|
172
174
|
AreaChart,
|
|
173
175
|
AreaChartSmooth,
|
|
174
176
|
DoughnutChart,
|
|
175
|
-
KPICard
|
|
177
|
+
KPICard,
|
|
178
|
+
Divider
|
|
176
179
|
};
|
|
177
180
|
|
|
178
181
|
/* -------------------------
|
|
@@ -234,6 +237,7 @@ export interface JuxAPI {
|
|
|
234
237
|
areachartsmooth: typeof areachartsmooth;
|
|
235
238
|
doughnutchart: typeof doughnutchart;
|
|
236
239
|
kpicard: typeof kpicard;
|
|
240
|
+
divider: typeof divider;
|
|
237
241
|
}
|
|
238
242
|
|
|
239
243
|
/* -------------------------
|
|
@@ -311,8 +315,8 @@ class Jux implements JuxAPI {
|
|
|
311
315
|
areachartsmooth = areachartsmooth;
|
|
312
316
|
doughnutchart = doughnutchart;
|
|
313
317
|
kpicard = kpicard;
|
|
318
|
+
divider = divider;
|
|
314
319
|
}
|
|
315
|
-
|
|
316
320
|
/**
|
|
317
321
|
* Global jux singleton instance
|
|
318
322
|
*/
|
package/machinery/compiler.js
CHANGED
|
@@ -2,6 +2,23 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import esbuild from 'esbuild';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* Generate import map script tag
|
|
7
|
+
*/
|
|
8
|
+
function generateImportMapScript() {
|
|
9
|
+
return `<script type="importmap">
|
|
10
|
+
{
|
|
11
|
+
"imports": {
|
|
12
|
+
"juxscript": "./lib/jux.js",
|
|
13
|
+
"juxscript/": "./lib/",
|
|
14
|
+
"juxscript/reactivity": "./lib/reactivity/state.js",
|
|
15
|
+
"juxscript/presets/": "./lib/presets/",
|
|
16
|
+
"juxscript/components/": "./lib/components/"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
</script>`;
|
|
20
|
+
}
|
|
21
|
+
|
|
5
22
|
/**
|
|
6
23
|
* Compile a .jux file to .js and .html
|
|
7
24
|
*
|
|
@@ -36,7 +53,6 @@ export async function compileJuxFile(juxFilePath, options = {}) {
|
|
|
36
53
|
// Calculate depth for relative paths
|
|
37
54
|
const depth = parsedPath.dir.split(path.sep).filter(p => p).length;
|
|
38
55
|
const libPath = depth === 0 ? './lib/jux.js' : '../'.repeat(depth) + 'lib/jux.js';
|
|
39
|
-
const styleBasePath = depth === 0 ? './lib/presets/' : '../'.repeat(depth) + 'lib/presets/';
|
|
40
56
|
|
|
41
57
|
// Transform imports
|
|
42
58
|
let transformedContent = juxContent;
|
|
@@ -68,8 +84,9 @@ export async function compileJuxFile(juxFilePath, options = {}) {
|
|
|
68
84
|
|
|
69
85
|
console.log(` ✓ JS: ${path.relative(projectRoot, jsOutputPath)}`);
|
|
70
86
|
|
|
71
|
-
// Generate HTML with correct script path
|
|
87
|
+
// Generate HTML with import map and correct script path
|
|
72
88
|
const scriptPath = `./${parsedPath.name}.js`;
|
|
89
|
+
const importMapScript = generateImportMapScript();
|
|
73
90
|
|
|
74
91
|
const html = `<!DOCTYPE html>
|
|
75
92
|
<html lang="en">
|
|
@@ -77,12 +94,12 @@ export async function compileJuxFile(juxFilePath, options = {}) {
|
|
|
77
94
|
<meta charset="UTF-8">
|
|
78
95
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
79
96
|
<title>${parsedPath.name}</title>
|
|
80
|
-
<!-- JUX Core Styles -->
|
|
81
|
-
<link rel="stylesheet" href="${styleBasePath}global.css">
|
|
82
97
|
</head>
|
|
83
98
|
<body data-theme="">
|
|
84
99
|
<!-- App container -->
|
|
85
100
|
<div id="app" data-jux-page="${parsedPath.name}"></div>
|
|
101
|
+
|
|
102
|
+
${importMapScript}
|
|
86
103
|
<script type="module" src="${scriptPath}"></script>
|
|
87
104
|
${isServe ? `
|
|
88
105
|
<!-- Hot reload -->
|
package/machinery/server.js
CHANGED
|
@@ -12,7 +12,7 @@ const __dirname = path.dirname(__filename);
|
|
|
12
12
|
|
|
13
13
|
let db = null;
|
|
14
14
|
|
|
15
|
-
async function serve(port = 3000, distDir = './jux-dist') {
|
|
15
|
+
async function serve(port = 3000, distDir = './jux-dist') {
|
|
16
16
|
const app = express();
|
|
17
17
|
const absoluteDistDir = path.resolve(distDir);
|
|
18
18
|
const projectRoot = path.resolve('.');
|
|
@@ -29,14 +29,14 @@ async function serve(port = 3000, distDir = './jux-dist') { // Changed default
|
|
|
29
29
|
app.post('/api/query', async (req, res) => {
|
|
30
30
|
try {
|
|
31
31
|
const { sql, params = [] } = req.body;
|
|
32
|
-
|
|
32
|
+
|
|
33
33
|
if (!db) {
|
|
34
34
|
return res.status(500).json({ error: 'Database not initialized' });
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
const stmt = db.prepare(sql);
|
|
38
38
|
stmt.bind(params);
|
|
39
|
-
|
|
39
|
+
|
|
40
40
|
const rows = [];
|
|
41
41
|
while (stmt.step()) {
|
|
42
42
|
rows.push(stmt.getAsObject());
|
|
@@ -61,16 +61,20 @@ async function serve(port = 3000, distDir = './jux-dist') { // Changed default
|
|
|
61
61
|
// Serve HTML files with clean URLs
|
|
62
62
|
const heyPath = path.join(absoluteDistDir, 'hey.html');
|
|
63
63
|
const indexPath = path.join(absoluteDistDir, 'index.html');
|
|
64
|
-
|
|
64
|
+
|
|
65
65
|
app.use((req, res, next) => {
|
|
66
|
-
let requestPath = req.path.endsWith('/') && req.path.length > 1
|
|
67
|
-
? req.path.slice(0, -1)
|
|
66
|
+
let requestPath = req.path.endsWith('/') && req.path.length > 1
|
|
67
|
+
? req.path.slice(0, -1)
|
|
68
68
|
: req.path;
|
|
69
69
|
|
|
70
70
|
// Root path - serve hey.html or index.html
|
|
71
71
|
if (requestPath === '/') {
|
|
72
|
-
if (fs.existsSync(heyPath))
|
|
73
|
-
|
|
72
|
+
if (fs.existsSync(heyPath)) {
|
|
73
|
+
return res.sendFile(heyPath);
|
|
74
|
+
}
|
|
75
|
+
if (fs.existsSync(indexPath)) {
|
|
76
|
+
return res.sendFile(indexPath);
|
|
77
|
+
}
|
|
74
78
|
}
|
|
75
79
|
|
|
76
80
|
// Try to serve as HTML file
|
|
@@ -87,7 +91,7 @@ async function serve(port = 3000, distDir = './jux-dist') { // Changed default
|
|
|
87
91
|
|
|
88
92
|
next();
|
|
89
93
|
});
|
|
90
|
-
|
|
94
|
+
|
|
91
95
|
// Serve static files (CSS, JS, images, etc.)
|
|
92
96
|
app.use(express.static(absoluteDistDir));
|
|
93
97
|
|
|
@@ -96,25 +100,24 @@ async function serve(port = 3000, distDir = './jux-dist') { // Changed default
|
|
|
96
100
|
const notFoundPath = path.join(absoluteDistDir, '404.html');
|
|
97
101
|
const requestedPath = path.join(absoluteDistDir, req.path);
|
|
98
102
|
const fileType = path.extname(req.path) || 'directory';
|
|
99
|
-
|
|
103
|
+
|
|
100
104
|
// Log to console for debugging
|
|
101
105
|
console.log(`❌ 404: ${req.path}`);
|
|
102
106
|
console.log(` Looked for: ${requestedPath}`);
|
|
103
107
|
console.log(` Type: ${fileType}`);
|
|
104
108
|
console.log(` Referer: ${req.get('referer') || 'direct'}`);
|
|
105
|
-
|
|
109
|
+
|
|
106
110
|
// If custom 404.html exists and this isn't already /404
|
|
107
111
|
if (fs.existsSync(notFoundPath) && req.path !== '/404') {
|
|
108
|
-
// Add debug info as query params
|
|
109
112
|
const debugUrl = `/404?path=${encodeURIComponent(req.path)}&type=${fileType}&from=${encodeURIComponent(req.get('referer') || 'direct')}`;
|
|
110
113
|
return res.redirect(debugUrl);
|
|
111
114
|
}
|
|
112
|
-
|
|
115
|
+
|
|
113
116
|
// Serve custom 404 page
|
|
114
117
|
if (fs.existsSync(notFoundPath)) {
|
|
115
118
|
return res.status(404).sendFile(notFoundPath);
|
|
116
119
|
}
|
|
117
|
-
|
|
120
|
+
|
|
118
121
|
// Fallback: minimal 404 response
|
|
119
122
|
res.status(404).send('<h1>404 - Not Found</h1>');
|
|
120
123
|
});
|
|
@@ -175,7 +178,7 @@ async function serve(port = 3000, distDir = './jux-dist') { // Changed default
|
|
|
175
178
|
async function initDatabase() {
|
|
176
179
|
const SQL = await initSqlJs();
|
|
177
180
|
const dbPath = path.join(__dirname, '../db/jux.db');
|
|
178
|
-
|
|
181
|
+
|
|
179
182
|
if (fs.existsSync(dbPath)) {
|
|
180
183
|
const buffer = fs.readFileSync(dbPath);
|
|
181
184
|
db = new SQL.Database(buffer);
|
|
@@ -188,5 +191,5 @@ async function initDatabase() {
|
|
|
188
191
|
|
|
189
192
|
export async function start(port = 3000) {
|
|
190
193
|
await initDatabase();
|
|
191
|
-
return serve(port, './jux-dist');
|
|
194
|
+
return serve(port, './jux-dist');
|
|
192
195
|
}
|
package/package.json
CHANGED
|
@@ -1,84 +1,66 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "juxscript",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A JavaScript UX authorship platform",
|
|
6
6
|
"main": "lib/jux.js",
|
|
7
7
|
"types": "lib/jux.d.ts",
|
|
8
|
+
"access": "public",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/jux/juxscript.git"
|
|
12
|
+
},
|
|
8
13
|
"exports": {
|
|
9
14
|
".": {
|
|
10
15
|
"types": "./lib/jux.d.ts",
|
|
11
16
|
"import": "./lib/jux.js",
|
|
12
17
|
"default": "./lib/jux.js"
|
|
13
18
|
},
|
|
14
|
-
"./
|
|
15
|
-
|
|
19
|
+
"./reactivity": {
|
|
20
|
+
"types": "./lib/reactivity/index.d.ts",
|
|
21
|
+
"import": "./lib/reactivity/index.js",
|
|
22
|
+
"default": "./lib/reactivity/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./components/*": "./lib/components/*/index.js",
|
|
25
|
+
"./presets/*": "./presets/*.*",
|
|
16
26
|
"./package.json": "./package.json"
|
|
17
27
|
},
|
|
18
|
-
"typesVersions": {
|
|
19
|
-
"*": {
|
|
20
|
-
"*": [
|
|
21
|
-
"lib/*"
|
|
22
|
-
],
|
|
23
|
-
"lib/*": [
|
|
24
|
-
"lib/*"
|
|
25
|
-
],
|
|
26
|
-
"lib/components/*": [
|
|
27
|
-
"lib/components/*"
|
|
28
|
-
]
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
"bin": {
|
|
32
|
-
"jux": "./bin/cli.js"
|
|
33
|
-
},
|
|
34
|
-
"scripts": {
|
|
35
|
-
"dev": "cd examples && npx jux serve",
|
|
36
|
-
"build:examples": "cd examples && rm -rf dist && npx jux build",
|
|
37
|
-
"build": "tsc",
|
|
38
|
-
"test": "node test/run-tests.js",
|
|
39
|
-
"generate:icons": "node scripts/generate-icon-types.js"
|
|
40
|
-
},
|
|
41
28
|
"files": [
|
|
42
29
|
"lib",
|
|
43
30
|
"bin",
|
|
44
31
|
"machinery",
|
|
45
32
|
"types",
|
|
46
|
-
"lib/**/*.d.ts",
|
|
47
33
|
"README.md",
|
|
48
34
|
"LICENSE"
|
|
49
35
|
],
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
},
|
|
53
|
-
"repository": {
|
|
54
|
-
"type": "git",
|
|
55
|
-
"url": "https://github.com/juxscript/jux.git"
|
|
36
|
+
"bin": {
|
|
37
|
+
"jux": "./bin/cli.js"
|
|
56
38
|
},
|
|
57
39
|
"keywords": [
|
|
58
|
-
"jux",
|
|
59
40
|
"ui",
|
|
60
|
-
"
|
|
41
|
+
"ux",
|
|
42
|
+
"components",
|
|
43
|
+
"framework",
|
|
44
|
+
"reactive",
|
|
61
45
|
"javascript"
|
|
62
46
|
],
|
|
63
|
-
"
|
|
64
|
-
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsc",
|
|
49
|
+
"dev": "tsc --watch",
|
|
50
|
+
"prepublishOnly": "npm run build"
|
|
51
|
+
},
|
|
65
52
|
"dependencies": {
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"esbuild": "^0.27.2",
|
|
70
|
-
"express": "^5.2.1",
|
|
53
|
+
"chokidar": "^3.5.3",
|
|
54
|
+
"esbuild": "^0.19.0",
|
|
55
|
+
"express": "^4.18.2",
|
|
71
56
|
"glob": "^13.0.0",
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"terser": "^5.44.1",
|
|
75
|
-
"ws": "^8.19.0"
|
|
76
|
-
},
|
|
77
|
-
"optionalDependencies": {
|
|
78
|
-
"mysql2": "^3.6.5",
|
|
79
|
-
"pg": "^8.11.3"
|
|
57
|
+
"sql.js": "^1.8.0",
|
|
58
|
+
"ws": "^8.13.0"
|
|
80
59
|
},
|
|
81
60
|
"devDependencies": {
|
|
82
|
-
"
|
|
61
|
+
"@types/express": "^4.17.17",
|
|
62
|
+
"@types/node": "^20.0.0",
|
|
63
|
+
"@types/ws": "^8.5.5",
|
|
64
|
+
"typescript": "^5.0.0"
|
|
83
65
|
}
|
|
84
66
|
}
|