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.
- package/bin/cli.js +243 -92
- package/index.js +21 -0
- package/lib/componentsv2/base/BaseEngine.d.ts +10 -0
- package/lib/componentsv2/base/BaseEngine.d.ts.map +1 -1
- package/lib/componentsv2/base/BaseEngine.js +28 -7
- package/lib/componentsv2/base/BaseEngine.js.map +1 -1
- package/lib/componentsv2/base/BaseEngine.ts +29 -0
- package/lib/componentsv2/base/OptionsContract.d.ts +20 -0
- package/lib/componentsv2/base/OptionsContract.d.ts.map +1 -0
- package/lib/componentsv2/base/OptionsContract.js +107 -0
- package/lib/componentsv2/base/OptionsContract.js.map +1 -0
- package/lib/componentsv2/base/OptionsContract.ts +139 -0
- package/lib/componentsv2/element/component.d.ts +22 -0
- package/lib/componentsv2/element/component.d.ts.map +1 -1
- package/lib/componentsv2/element/component.js +22 -0
- package/lib/componentsv2/element/component.js.map +1 -1
- package/lib/componentsv2/element/component.ts +23 -1
- package/lib/componentsv2/element/engine.d.ts +31 -14
- package/lib/componentsv2/element/engine.d.ts.map +1 -1
- package/lib/componentsv2/element/engine.js +74 -23
- package/lib/componentsv2/element/engine.js.map +1 -1
- package/lib/componentsv2/element/engine.ts +86 -29
- package/lib/componentsv2/element/skin.d.ts.map +1 -1
- package/lib/componentsv2/element/skin.js +7 -10
- package/lib/componentsv2/element/skin.js.map +1 -1
- package/lib/componentsv2/element/skin.ts +7 -11
- package/lib/componentsv2/grid/engine.d.ts +48 -3
- package/lib/componentsv2/grid/engine.d.ts.map +1 -1
- package/lib/componentsv2/grid/engine.js +109 -14
- package/lib/componentsv2/grid/engine.js.map +1 -1
- package/lib/componentsv2/grid/engine.ts +120 -16
- package/lib/componentsv2/input/engine.d.ts +48 -5
- package/lib/componentsv2/input/engine.d.ts.map +1 -1
- package/lib/componentsv2/input/engine.js +108 -15
- package/lib/componentsv2/input/engine.js.map +1 -1
- package/lib/componentsv2/input/engine.ts +119 -16
- package/lib/componentsv2/input/skin.d.ts.map +1 -1
- package/lib/componentsv2/input/skin.js +1 -4
- package/lib/componentsv2/input/skin.js.map +1 -1
- package/lib/componentsv2/input/skin.ts +1 -4
- package/lib/componentsv2/list/component.d.ts +28 -6
- package/lib/componentsv2/list/component.d.ts.map +1 -1
- package/lib/componentsv2/list/component.js +28 -6
- package/lib/componentsv2/list/component.js.map +1 -1
- package/lib/componentsv2/list/component.ts +28 -6
- package/lib/componentsv2/list/engine.d.ts +61 -9
- package/lib/componentsv2/list/engine.d.ts.map +1 -1
- package/lib/componentsv2/list/engine.js +156 -95
- package/lib/componentsv2/list/engine.js.map +1 -1
- package/lib/componentsv2/list/engine.ts +175 -108
- package/machinery/build3.js +21 -0
- package/machinery/compiler3.js +638 -0
- package/machinery/serve.js +255 -0
- package/machinery/watcher.js +53 -64
- package/package.json +11 -3
- package/lib/componentsv2/index.d.ts +0 -41
- package/lib/componentsv2/index.d.ts.map +0 -1
- package/lib/componentsv2/index.js +0 -223
- package/lib/componentsv2/index.js.map +0 -1
- package/lib/componentsv2/index.ts +0 -256
- package/lib/componentsv2/juxerror/component.d.ts +0 -28
- package/lib/componentsv2/juxerror/component.d.ts.map +0 -1
- package/lib/componentsv2/juxerror/component.js +0 -101
- package/lib/componentsv2/juxerror/component.js.map +0 -1
- package/lib/componentsv2/juxerror/component.ts +0 -125
- package/lib/componentsv2/juxerror/engine.d.ts +0 -35
- package/lib/componentsv2/juxerror/engine.d.ts.map +0 -1
- package/lib/componentsv2/juxerror/engine.js +0 -190
- package/lib/componentsv2/juxerror/engine.js.map +0 -1
- package/lib/componentsv2/juxerror/engine.ts +0 -241
- package/lib/componentsv2/juxerror/skin.d.ts +0 -11
- package/lib/componentsv2/juxerror/skin.d.ts.map +0 -1
- package/lib/componentsv2/juxerror/skin.js +0 -180
- package/lib/componentsv2/juxerror/skin.js.map +0 -1
- package/lib/componentsv2/juxerror/skin.ts +0 -200
- package/lib/componentsv2/juxerror/structure.css +0 -351
- package/machinery/ast.js +0 -347
- package/machinery/compiler.js +0 -706
- package/machinery/diagnose.js +0 -72
- package/machinery/doc-generator.js +0 -136
- package/machinery/imports.js +0 -155
- package/machinery/jux-module-pattern.md +0 -118
- package/machinery/server.js +0 -86
- package/machinery/ts-shim.js +0 -46
- package/machinery/verifier.js +0 -135
- package/tests/dropdown-test.js +0 -25
- package/tests/juxerrors/bad_syntax.jux +0 -8
- package/tests/juxerrors/ghost_dep.jux +0 -10
- package/tests/server_plugin_test.ts +0 -191
package/machinery/verifier.js
DELETED
|
@@ -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
|
-
}
|
package/tests/dropdown-test.js
DELETED
|
@@ -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,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();
|