juxscript 1.0.88 → 1.0.90

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.
Files changed (89) hide show
  1. package/bin/cli.js +243 -92
  2. package/index.js +21 -0
  3. package/lib/componentsv2/base/BaseEngine.d.ts +10 -0
  4. package/lib/componentsv2/base/BaseEngine.d.ts.map +1 -1
  5. package/lib/componentsv2/base/BaseEngine.js +28 -7
  6. package/lib/componentsv2/base/BaseEngine.js.map +1 -1
  7. package/lib/componentsv2/base/BaseEngine.ts +29 -0
  8. package/lib/componentsv2/base/OptionsContract.d.ts +20 -0
  9. package/lib/componentsv2/base/OptionsContract.d.ts.map +1 -0
  10. package/lib/componentsv2/base/OptionsContract.js +107 -0
  11. package/lib/componentsv2/base/OptionsContract.js.map +1 -0
  12. package/lib/componentsv2/base/OptionsContract.ts +139 -0
  13. package/lib/componentsv2/element/component.d.ts +22 -0
  14. package/lib/componentsv2/element/component.d.ts.map +1 -1
  15. package/lib/componentsv2/element/component.js +22 -0
  16. package/lib/componentsv2/element/component.js.map +1 -1
  17. package/lib/componentsv2/element/component.ts +23 -1
  18. package/lib/componentsv2/element/engine.d.ts +31 -14
  19. package/lib/componentsv2/element/engine.d.ts.map +1 -1
  20. package/lib/componentsv2/element/engine.js +74 -23
  21. package/lib/componentsv2/element/engine.js.map +1 -1
  22. package/lib/componentsv2/element/engine.ts +86 -29
  23. package/lib/componentsv2/element/skin.d.ts.map +1 -1
  24. package/lib/componentsv2/element/skin.js +7 -10
  25. package/lib/componentsv2/element/skin.js.map +1 -1
  26. package/lib/componentsv2/element/skin.ts +7 -11
  27. package/lib/componentsv2/grid/engine.d.ts +48 -3
  28. package/lib/componentsv2/grid/engine.d.ts.map +1 -1
  29. package/lib/componentsv2/grid/engine.js +109 -14
  30. package/lib/componentsv2/grid/engine.js.map +1 -1
  31. package/lib/componentsv2/grid/engine.ts +120 -16
  32. package/lib/componentsv2/input/engine.d.ts +48 -5
  33. package/lib/componentsv2/input/engine.d.ts.map +1 -1
  34. package/lib/componentsv2/input/engine.js +108 -15
  35. package/lib/componentsv2/input/engine.js.map +1 -1
  36. package/lib/componentsv2/input/engine.ts +119 -16
  37. package/lib/componentsv2/input/skin.d.ts.map +1 -1
  38. package/lib/componentsv2/input/skin.js +1 -4
  39. package/lib/componentsv2/input/skin.js.map +1 -1
  40. package/lib/componentsv2/input/skin.ts +1 -4
  41. package/lib/componentsv2/list/component.d.ts +28 -6
  42. package/lib/componentsv2/list/component.d.ts.map +1 -1
  43. package/lib/componentsv2/list/component.js +28 -6
  44. package/lib/componentsv2/list/component.js.map +1 -1
  45. package/lib/componentsv2/list/component.ts +28 -6
  46. package/lib/componentsv2/list/engine.d.ts +61 -9
  47. package/lib/componentsv2/list/engine.d.ts.map +1 -1
  48. package/lib/componentsv2/list/engine.js +156 -95
  49. package/lib/componentsv2/list/engine.js.map +1 -1
  50. package/lib/componentsv2/list/engine.ts +175 -108
  51. package/machinery/build3.js +21 -0
  52. package/machinery/compiler3.js +638 -0
  53. package/machinery/serve.js +255 -0
  54. package/machinery/watcher.js +53 -64
  55. package/package.json +11 -3
  56. package/lib/componentsv2/index.d.ts +0 -41
  57. package/lib/componentsv2/index.d.ts.map +0 -1
  58. package/lib/componentsv2/index.js +0 -223
  59. package/lib/componentsv2/index.js.map +0 -1
  60. package/lib/componentsv2/index.ts +0 -256
  61. package/lib/componentsv2/juxerror/component.d.ts +0 -28
  62. package/lib/componentsv2/juxerror/component.d.ts.map +0 -1
  63. package/lib/componentsv2/juxerror/component.js +0 -101
  64. package/lib/componentsv2/juxerror/component.js.map +0 -1
  65. package/lib/componentsv2/juxerror/component.ts +0 -125
  66. package/lib/componentsv2/juxerror/engine.d.ts +0 -35
  67. package/lib/componentsv2/juxerror/engine.d.ts.map +0 -1
  68. package/lib/componentsv2/juxerror/engine.js +0 -190
  69. package/lib/componentsv2/juxerror/engine.js.map +0 -1
  70. package/lib/componentsv2/juxerror/engine.ts +0 -241
  71. package/lib/componentsv2/juxerror/skin.d.ts +0 -11
  72. package/lib/componentsv2/juxerror/skin.d.ts.map +0 -1
  73. package/lib/componentsv2/juxerror/skin.js +0 -180
  74. package/lib/componentsv2/juxerror/skin.js.map +0 -1
  75. package/lib/componentsv2/juxerror/skin.ts +0 -200
  76. package/lib/componentsv2/juxerror/structure.css +0 -351
  77. package/machinery/ast.js +0 -347
  78. package/machinery/compiler.js +0 -706
  79. package/machinery/diagnose.js +0 -72
  80. package/machinery/doc-generator.js +0 -136
  81. package/machinery/imports.js +0 -155
  82. package/machinery/jux-module-pattern.md +0 -118
  83. package/machinery/server.js +0 -86
  84. package/machinery/ts-shim.js +0 -46
  85. package/machinery/verifier.js +0 -135
  86. package/tests/dropdown-test.js +0 -25
  87. package/tests/juxerrors/bad_syntax.jux +0 -8
  88. package/tests/juxerrors/ghost_dep.jux +0 -10
  89. package/tests/server_plugin_test.ts +0 -191
@@ -1,135 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import http from 'http';
4
- import * as acorn from 'acorn';
5
-
6
- /**
7
- * Checks the static `distDir` for critical files and valid import map references.
8
- * Returns true if healthy, false if broken.
9
- */
10
- export function verifyStaticBuild(distDir) {
11
- const errors = [];
12
-
13
- if (!fs.existsSync(distDir)) {
14
- console.error('❌ Dist dir does not exist');
15
- return false;
16
- }
17
-
18
- // 1. Critical Files Existence
19
- const critical = ['index.html', 'main.js'];
20
- for (const f of critical) {
21
- if (!fs.existsSync(path.join(distDir, f))) {
22
- errors.push(`Missing critical artifact: ${f}`);
23
- }
24
- }
25
-
26
- // 2. Import Map Integrity Check
27
- let importMap = {};
28
- try {
29
- const indexPath = path.join(distDir, 'index.html');
30
- if (fs.existsSync(indexPath)) {
31
- const html = fs.readFileSync(indexPath, 'utf8');
32
- const match = html.match(/<script type="importmap">([\s\S]*?)<\/script>/);
33
-
34
- if (match && match[1]) {
35
- importMap = JSON.parse(match[1]).imports || {};
36
- Object.entries(importMap).forEach(([key, url]) => {
37
- // Skip folders (trailing slash) and CDN links
38
- if (typeof url === 'string' && !url.endsWith('/') && !url.startsWith('http')) {
39
- const fsPath = url.replace(/^\//, '').split('?')[0];
40
- const fullPath = path.join(distDir, fsPath);
41
-
42
- if (!fs.existsSync(fullPath)) {
43
- errors.push(`Broken Import Map: "${key}" -> ${url} (File not found)`);
44
- }
45
- }
46
- });
47
- }
48
- }
49
- } catch (e) {
50
- errors.push(`Import Map Verification Error: ${e.message}`);
51
- }
52
-
53
- // 3. Bundle Import Verification (Detect Ghost Dependencies)
54
- const mainJsPath = path.join(distDir, 'main.js');
55
- if (fs.existsSync(mainJsPath)) {
56
- try {
57
- const code = fs.readFileSync(mainJsPath, 'utf8');
58
- const ast = acorn.parse(code, { ecmaVersion: 'latest', sourceType: 'module' });
59
-
60
- ast.body.forEach(node => {
61
- if (node.type === 'ImportDeclaration') {
62
- const source = node.source.value;
63
-
64
- if (source.startsWith('/') || source.startsWith('.')) {
65
- return;
66
- }
67
-
68
- // ✅ FIX: Check if the file exists locally in dist (e.g. copied assets)
69
- // If it exists on disk, it's not a ghost dependency from node_modules
70
- // This handles cases where a file was copied but imported as a bare specifier (though compiler should fix that too)
71
- if (fs.existsSync(path.join(distDir, source))) {
72
- return;
73
- }
74
-
75
- if (!importMap[source] && !importMap[source + '/']) {
76
- errors.push(`Ghost Dependency: '${source}' is imported in main.js but missing from Import Map.`);
77
- }
78
- }
79
- });
80
- } catch (e) {
81
- errors.push(`Failed to parse main.js for verification: ${e.message}`);
82
- }
83
- }
84
-
85
- if (errors.length > 0) {
86
- console.error(`\n❌ BUILD VERIFICATION FAILED (${errors.length} errors):`);
87
- errors.forEach(e => console.error(` - ${e}`));
88
- console.log('');
89
- return false;
90
- }
91
-
92
- return true;
93
- }
94
-
95
- export function verifyRuntime(port) {
96
- return new Promise((resolve) => {
97
- const errors = [];
98
-
99
- // Helper to check a single URL
100
- const check = (urlPath, expectedMime) => new Promise(r => {
101
- const req = http.get(`http://localhost:${port}${urlPath}`, res => {
102
- if (res.statusCode !== 200 && res.statusCode !== 304) {
103
- errors.push(`GET ${urlPath} : Status ${res.statusCode} (Expected 200)`);
104
- } else {
105
- const ct = res.headers['content-type'] || '';
106
- if (expectedMime && !ct.includes(expectedMime)) {
107
- errors.push(`GET ${urlPath} : Bad MIME type. Got "${ct}", expected "${expectedMime}".`);
108
- }
109
- }
110
- res.resume();
111
- r();
112
- });
113
-
114
- req.on('error', e => {
115
- errors.push(`GET ${urlPath} : Connection failed - ${e.message}`);
116
- r();
117
- });
118
- });
119
-
120
- // Run checks in parallel
121
- Promise.all([
122
- check('/', 'text/html'),
123
- check('/main.js', 'application/javascript'),
124
- ]).then(() => {
125
- if (errors.length > 0) {
126
- console.error(`\n💥 RUNTIME VERIFICATION FAILED (${errors.length} errors):`);
127
- errors.forEach(e => console.error(` - ${e}`));
128
- console.log('');
129
- resolve(false);
130
- } else {
131
- resolve(true);
132
- }
133
- });
134
- });
135
- }
@@ -1,25 +0,0 @@
1
- import { dropdown } from '../lib/components/dropdown.js';
2
-
3
-
4
- const dd = dropdown('test-dropdown', {
5
- items: [
6
- { value: 'option1', label: 'Option 1' },
7
- { value: 'option2', label: 'Option 2' },
8
- { value: 'option3', label: 'Option 3' }
9
- ],
10
- placeholder: 'Select an option',
11
- searchable: true,
12
- multiSelect: false
13
- });
14
- //dd.open();
15
-
16
- console.log('Current Props', dd.props)
17
-
18
-
19
-
20
- dd.select('option3');
21
- dd.open();
22
-
23
- console.log('Dropdown opened:', dd.props);
24
- //dd.selectItem('option2');
25
- //console.log('Selected item:', dd.getSelectedItems());
@@ -1,8 +0,0 @@
1
- import { jux } from 'juxscript';
2
-
3
- // This is valid
4
- jux.hero('syntax-test', { title: 'Syntax Test' }).render('#app');
5
-
6
- // This is INVALID syntax and should fail the compiler
7
-
8
- const brokenVariable = ;
@@ -1,10 +0,0 @@
1
- import { jux } from 'juxscript';
2
-
3
- // ❌ This dependency does not exist in node_modules
4
- // The compiler will warn, but might proceed.
5
- // The Verifier should CATCH this because 'phantom-lib' won't be in the import map.
6
- import { magic } from 'phantom-lib';
7
-
8
- jux.hero('dep-test', { title: 'Ghost Dependency' }).render('#app');
9
-
10
- console.log(magic);
@@ -1,191 +0,0 @@
1
- import { ListEngine, ListItem } from '../lib/componentsv2/list/engine.js';
2
- import { ServerSQLitePlugin } from '../lib/componentsv2/plugins/ServerSQLitePlugin.js';
3
- import Database from 'better-sqlite3';
4
- import fs from 'fs';
5
- import path from 'path';
6
-
7
- const DB_PATH = path.resolve('temp/jux_test.db');
8
- const PRESERVE_DB = process.argv.includes('--preserve-db');
9
-
10
- // --- Integrity System ---
11
- const SNAPSHOTS: Record<string, any[]> = {};
12
- const EXPECTATIONS: Record<string, any[]> = {};
13
-
14
- function capture(phase: string, items: ListItem[]) {
15
- // Deep copy and simplify to core data shape
16
- SNAPSHOTS[phase] = items.map(i => ({
17
- id: i.id,
18
- text: i.text,
19
- classes: i.classes,
20
- details: i.details
21
- }));
22
- }
23
-
24
- function expectShape(phase: string, shape: any[]) {
25
- EXPECTATIONS[phase] = shape;
26
- }
27
-
28
- /**
29
- * Generate a precision checksum for data integrity.
30
- */
31
- function getChecksum(data: any): string {
32
- const str = JSON.stringify(data);
33
- let hash = 5381;
34
- for (let i = 0; i < str.length; i++) {
35
- hash = ((hash << 5) + hash) + str.charCodeAt(i);
36
- }
37
- return (hash >>> 0).toString(16).toUpperCase().padStart(8, '0');
38
- }
39
-
40
- async function runTest() {
41
- console.log('--- STARTING RIGOROUS SERVER-SIDE PLUGIN TEST ---');
42
- if (PRESERVE_DB) console.log('ℹ️ MODE: Preserving Database File');
43
-
44
- // Ensure temp directory exists
45
- const tempDir = path.dirname(DB_PATH);
46
- if (!fs.existsSync(tempDir)) {
47
- fs.mkdirSync(tempDir, { recursive: true });
48
- }
49
-
50
- // Cleanup previous runs
51
- if (fs.existsSync(DB_PATH)) fs.unlinkSync(DB_PATH);
52
-
53
- // 1. Initialize DB
54
- const db = new Database(DB_PATH);
55
-
56
- // 🔍 PROOF OF LIFE
57
- const sqliteVersion = db.prepare('select sqlite_version()').pluck().get();
58
- const TEST_TIMESTAMP = new Date().toISOString();
59
- const EPHEMERAL_TAG = ` [v${sqliteVersion}::${TEST_TIMESTAMP}]`;
60
- console.log(`🔌 CONNECTION ACTIVE: SQLite ${sqliteVersion} | Run ID: ${TEST_TIMESTAMP}`);
61
-
62
- const engine = new ListEngine('server-list-01');
63
-
64
- // --- DATA CONTRACTS ---
65
- const SHAPE_1_EMPTY: any[] = [];
66
-
67
- const SHAPE_2_HYDRATED = [
68
- { id: '1', text: `Alice${EPHEMERAL_TAG}`, classes: ['admin'], details: { active: true } },
69
- { id: '2', text: `Bob${EPHEMERAL_TAG}`, classes: ['user'], details: { active: true } },
70
- { id: '3', text: `Charlie${EPHEMERAL_TAG}`, classes: ['guest'], details: { active: false } }
71
- ];
72
-
73
- const SHAPE_3_MODIFIED = [
74
- { id: '1', text: `Alice${EPHEMERAL_TAG}`, classes: ['superadmin'], details: { active: true } },
75
- { id: '2', text: `Bob${EPHEMERAL_TAG}`, classes: ['user'], details: { active: true } },
76
- { id: '4', text: `Dave${EPHEMERAL_TAG}`, classes: ['user'], details: {} }
77
- ];
78
-
79
- // Register Contracts
80
- expectShape('PHASE 1: Empty', SHAPE_1_EMPTY);
81
- expectShape('PHASE 2: Hydrated', SHAPE_2_HYDRATED);
82
- expectShape('PHASE 3: Modified', SHAPE_3_MODIFIED);
83
-
84
- // === EXECUTION ===
85
-
86
- // Phase 1
87
- console.log('\n▶ PHASE 1: Initialization');
88
- capture('PHASE 1: Empty', engine.state.items);
89
-
90
- // Phase 2
91
- console.log('\n▶ PHASE 2: Schema & Hydration');
92
- db.exec(`CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT NOT NULL, role TEXT DEFAULT 'user', meta TEXT);`);
93
- const insert = db.prepare('INSERT INTO users (username, role, meta) VALUES (?, ?, ?)');
94
- insert.run('Alice', 'admin', JSON.stringify({ active: true }));
95
- insert.run('Bob', 'user', JSON.stringify({ active: true }));
96
- insert.run('Charlie', 'guest', JSON.stringify({ active: false }));
97
-
98
- // Inject Decoupled Plugin
99
- const plugin = ServerSQLitePlugin({
100
- database: db,
101
- query: `SELECT id, username || '${EPHEMERAL_TAG}' as username, role, meta FROM users`,
102
- bindTo: 'items', // ✅ Bind to ListEngine's 'items' property
103
- mapRow: (row: any) => ({
104
- id: String(row.id),
105
- text: row.username,
106
- classes: row.role ? [row.role] : [],
107
- details: row.meta ? JSON.parse(row.meta) : {}
108
- }),
109
- autoLoad: true
110
- });
111
- engine.addPlugin(plugin);
112
-
113
- capture('PHASE 2: Hydrated', engine.state.items);
114
-
115
- // Phase 3
116
- console.log('\n▶ PHASE 3: External Access');
117
- db.prepare("UPDATE users SET role = 'superadmin' WHERE username = 'Alice'").run();
118
- db.prepare("DELETE FROM users WHERE username = 'Charlie'").run();
119
- db.prepare("INSERT INTO users (username, role, meta) VALUES (?, ?, ?)").run('Dave', 'user', '{}');
120
-
121
- // @ts-ignore
122
- engine['emit']('db:reload', {});
123
-
124
- capture('PHASE 3: Modified', engine.state.items);
125
-
126
- // === VERIFICATION REPORT ===
127
- console.log('\n=============================================================');
128
- console.log(' 🛡️ INTEGRITY CHECKSUM REPORT ');
129
- console.log('=============================================================');
130
- console.log(` CONNECTION ACTIVE: SQLite ${sqliteVersion} | Run ID: ${TEST_TIMESTAMP}`);
131
- console.log('-------------------------------------------------------------');
132
- console.log(' PHASES | CHECKSUM | EXPECTED | STATUS ');
133
- console.log('-------------------------|----------|----------|-------------');
134
-
135
- let allPassed = true;
136
- Object.keys(EXPECTATIONS).forEach(phase => {
137
- const actual = SNAPSHOTS[phase] || [];
138
- const expected = EXPECTATIONS[phase];
139
-
140
- const actHash = getChecksum(actual);
141
- const expHash = getChecksum(expected);
142
- const match = actHash === expHash;
143
-
144
- if (!match) allPassed = false;
145
-
146
- const status = match ? '✅ PASS' : '❌ FAIL';
147
- console.log(` ${phase.padEnd(23)} | ${actHash} | ${expHash} | ${status}`);
148
- });
149
-
150
- console.log('-------------------------------------------------------------');
151
-
152
- // === HISTORY DUMP ===
153
- console.log('\n==================================================');
154
- console.log(' 📜 STATE LEDGER ');
155
- console.log('==================================================');
156
- engine.stateHistory.forEach((snap, i) => {
157
- const s = JSON.parse(snap);
158
- console.log(`${i.toString().padStart(2, '0')} | Items: ${s.items.length} | Loading: ${String(s.loading).padEnd(5)} | Msg: ${s.noItemsMessage || 'None'}`);
159
- });
160
-
161
- console.log('\n==================================================');
162
- console.log(' 📡 EVENT TOPOLOGY ');
163
- console.log('==================================================');
164
- engine.emitHistory.forEach((entryStr, i) => {
165
- try {
166
- const entry = JSON.parse(entryStr);
167
- const time = entry.timestamp.split('T')[1].slice(0, 8);
168
- const dataSummary = JSON.stringify(entry.data).substring(0, 60);
169
- console.log(`#${i.toString().padStart(2, '0')} [${time}] ${entry.event.padEnd(15)} -> ${dataSummary}`);
170
- } catch (e) { }
171
- });
172
-
173
- engine.dispose();
174
- db.close();
175
-
176
- // Cleanup
177
- if (PRESERVE_DB) {
178
- console.log(`\n💾 DATABASE PRESERVED: ${DB_PATH}`);
179
- } else {
180
- if (fs.existsSync(DB_PATH)) fs.unlinkSync(DB_PATH);
181
- }
182
-
183
- if (allPassed) {
184
- console.log('\n🌟🌟🌟 RESOUNDING ALL TESTS PASSED 🌟🌟🌟\n');
185
- } else {
186
- console.error('\n💥 VERIFICATION FAILED: Checksum Mismatch detected.\n');
187
- process.exit(1);
188
- }
189
- }
190
-
191
- runTest();