bertui 1.2.9 → 2.0.0
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 +44 -242
- package/TYPES_PATCH.md +17 -0
- package/bin/bertui.js +2 -7
- package/package.json +32 -98
- package/src/config.ts +4 -0
- package/src/index.ts +32 -0
- package/src/optional.ts +49 -0
- package/src/router.ts +3 -0
- package/tsconfig.json +29 -0
- package/LICENSE +0 -21
- package/index.js +0 -103
- package/src/analyzer/index.js +0 -370
- package/src/build/compiler/file-transpiler.js +0 -216
- package/src/build/compiler/index.js +0 -31
- package/src/build/compiler/route-discoverer.js +0 -49
- package/src/build/compiler/router-generator.js +0 -105
- package/src/build/css-builder.js +0 -81
- package/src/build/generators/html-generator.js +0 -263
- package/src/build/generators/robots-generator.js +0 -58
- package/src/build/generators/sitemap-generator.js +0 -63
- package/src/build/image-optimizer.js +0 -137
- package/src/build/processors/asset-processor.js +0 -19
- package/src/build/processors/css-builder.js +0 -142
- package/src/build/server-island-validator.js +0 -67
- package/src/build/ssr-renderer.js +0 -64
- package/src/build.js +0 -273
- package/src/cli.js +0 -131
- package/src/client/compiler.js +0 -522
- package/src/client/fast-refresh.js +0 -72
- package/src/client/hmr-runtime.js +0 -59
- package/src/compiler/index.js +0 -25
- package/src/compiler/router-generator-pure.js +0 -104
- package/src/compiler/transform.js +0 -149
- package/src/config/defaultConfig.js +0 -37
- package/src/config/index.js +0 -2
- package/src/config/loadConfig.js +0 -64
- package/src/config/og-image.png +0 -0
- package/src/css/index.js +0 -46
- package/src/css/processor.js +0 -172
- package/src/dev.js +0 -68
- package/src/hydration/index.js +0 -151
- package/src/image-optimizer/index.js +0 -103
- package/src/images/index.js +0 -102
- package/src/images/processor.js +0 -169
- package/src/layouts/index.js +0 -165
- package/src/loading/index.js +0 -210
- package/src/logger/logger.js +0 -320
- package/src/logger/notes.md +0 -20
- package/src/middleware/index.js +0 -182
- package/src/router/Router.js +0 -150
- package/src/router/SSRRouter.js +0 -156
- package/src/router/index.js +0 -3
- package/src/scaffolder/index.js +0 -310
- package/src/serve.js +0 -193
- package/src/server/dev-handler.js +0 -195
- package/src/server/dev-server-utils.js +0 -406
- package/src/server/dev-server.js +0 -15
- package/src/server/hmr-handler.js +0 -148
- package/src/server/index.js +0 -3
- package/src/server/notes.md +0 -1
- package/src/server/request-handler.js +0 -36
- package/src/server-islands/extractor.js +0 -198
- package/src/server-islands/index.js +0 -59
- package/src/styles/bertui.css +0 -210
- package/src/utils/cache.js +0 -297
- package/src/utils/env.js +0 -87
- package/src/utils/importhow.js +0 -52
- package/src/utils/index.js +0 -11
- package/src/utils/meta-extractor.js +0 -127
- package/types/bin/bertui.d.ts +0 -3
- package/types/bin/bertui.d.ts.map +0 -1
- package/types/error-overlay.d.ts +0 -2
- package/types/error-overlay.d.ts.map +0 -1
- package/types/index.d.ts +0 -26
- package/types/index.d.ts.map +0 -1
- package/types/scripts/fix-wasm-exports.d.ts +0 -2
- package/types/scripts/fix-wasm-exports.d.ts.map +0 -1
- package/types/src/analyzer/index.d.ts +0 -8
- package/types/src/analyzer/index.d.ts.map +0 -1
- package/types/src/build/compiler/file-transpiler.d.ts +0 -5
- package/types/src/build/compiler/file-transpiler.d.ts.map +0 -1
- package/types/src/build/compiler/index.d.ts +0 -12
- package/types/src/build/compiler/index.d.ts.map +0 -1
- package/types/src/build/compiler/route-discoverer.d.ts +0 -2
- package/types/src/build/compiler/route-discoverer.d.ts.map +0 -1
- package/types/src/build/compiler/router-generator.d.ts +0 -2
- package/types/src/build/compiler/router-generator.d.ts.map +0 -1
- package/types/src/build/css-builder.d.ts +0 -18
- package/types/src/build/css-builder.d.ts.map +0 -1
- package/types/src/build/generators/html-generator.d.ts +0 -2
- package/types/src/build/generators/html-generator.d.ts.map +0 -1
- package/types/src/build/generators/robots-generator.d.ts +0 -11
- package/types/src/build/generators/robots-generator.d.ts.map +0 -1
- package/types/src/build/generators/sitemap-generator.d.ts +0 -5
- package/types/src/build/generators/sitemap-generator.d.ts.map +0 -1
- package/types/src/build/image-optimizer.d.ts +0 -11
- package/types/src/build/image-optimizer.d.ts.map +0 -1
- package/types/src/build/processors/asset-processor.d.ts +0 -2
- package/types/src/build/processors/asset-processor.d.ts.map +0 -1
- package/types/src/build/processors/css-builder.d.ts +0 -2
- package/types/src/build/processors/css-builder.d.ts.map +0 -1
- package/types/src/build/server-island-validator.d.ts +0 -27
- package/types/src/build/server-island-validator.d.ts.map +0 -1
- package/types/src/build.d.ts +0 -5
- package/types/src/build.d.ts.map +0 -1
- package/types/src/cli.d.ts +0 -2
- package/types/src/cli.d.ts.map +0 -1
- package/types/src/client/compiler.d.ts +0 -16
- package/types/src/client/compiler.d.ts.map +0 -1
- package/types/src/client/fast-refresh.d.ts +0 -3
- package/types/src/client/fast-refresh.d.ts.map +0 -1
- package/types/src/client/hmr-runtime.d.ts +0 -4
- package/types/src/client/hmr-runtime.d.ts.map +0 -1
- package/types/src/compiler/index.d.ts +0 -8
- package/types/src/compiler/index.d.ts.map +0 -1
- package/types/src/compiler/router-generator-pure.d.ts +0 -2
- package/types/src/compiler/router-generator-pure.d.ts.map +0 -1
- package/types/src/compiler/transform.d.ts +0 -36
- package/types/src/compiler/transform.d.ts.map +0 -1
- package/types/src/config/defaultConfig.d.ts +0 -26
- package/types/src/config/defaultConfig.d.ts.map +0 -1
- package/types/src/config/index.d.ts +0 -3
- package/types/src/config/index.d.ts.map +0 -1
- package/types/src/config/loadConfig.d.ts +0 -2
- package/types/src/config/loadConfig.d.ts.map +0 -1
- package/types/src/css/index.d.ts +0 -6
- package/types/src/css/index.d.ts.map +0 -1
- package/types/src/css/processor.d.ts +0 -23
- package/types/src/css/processor.d.ts.map +0 -1
- package/types/src/dev.d.ts +0 -2
- package/types/src/dev.d.ts.map +0 -1
- package/types/src/hydration/index.d.ts +0 -33
- package/types/src/hydration/index.d.ts.map +0 -1
- package/types/src/image-optimizer/index.d.ts +0 -24
- package/types/src/image-optimizer/index.d.ts.map +0 -1
- package/types/src/images/index.d.ts +0 -12
- package/types/src/images/index.d.ts.map +0 -1
- package/types/src/images/processor.d.ts +0 -30
- package/types/src/images/processor.d.ts.map +0 -1
- package/types/src/layouts/index.d.ts +0 -28
- package/types/src/layouts/index.d.ts.map +0 -1
- package/types/src/loading/index.d.ts +0 -28
- package/types/src/loading/index.d.ts.map +0 -1
- package/types/src/logger/logger.d.ts +0 -30
- package/types/src/logger/logger.d.ts.map +0 -1
- package/types/src/middleware/index.d.ts +0 -61
- package/types/src/middleware/index.d.ts.map +0 -1
- package/types/src/router/Router.d.ts +0 -16
- package/types/src/router/Router.d.ts.map +0 -1
- package/types/src/router/SSRRouter.d.ts +0 -20
- package/types/src/router/SSRRouter.d.ts.map +0 -1
- package/types/src/router/index.d.ts +0 -3
- package/types/src/router/index.d.ts.map +0 -1
- package/types/src/scaffolder/index.d.ts +0 -14
- package/types/src/scaffolder/index.d.ts.map +0 -1
- package/types/src/serve.d.ts +0 -3
- package/types/src/serve.d.ts.map +0 -1
- package/types/src/server/dev-handler.d.ts +0 -13
- package/types/src/server/dev-handler.d.ts.map +0 -1
- package/types/src/server/dev-server-utils.d.ts +0 -6
- package/types/src/server/dev-server-utils.d.ts.map +0 -1
- package/types/src/server/dev-server.d.ts +0 -18
- package/types/src/server/dev-server.d.ts.map +0 -1
- package/types/src/server/hmr-handler.d.ts +0 -19
- package/types/src/server/hmr-handler.d.ts.map +0 -1
- package/types/src/server/index.d.ts +0 -4
- package/types/src/server/index.d.ts.map +0 -1
- package/types/src/server/request-handler.d.ts +0 -19
- package/types/src/server/request-handler.d.ts.map +0 -1
- package/types/src/server-islands/extractor.d.ts +0 -16
- package/types/src/server-islands/extractor.d.ts.map +0 -1
- package/types/src/server-islands/index.d.ts +0 -3
- package/types/src/server-islands/index.d.ts.map +0 -1
- package/types/src/utils/cache.d.ts +0 -52
- package/types/src/utils/cache.d.ts.map +0 -1
- package/types/src/utils/env.d.ts +0 -20
- package/types/src/utils/env.d.ts.map +0 -1
- package/types/src/utils/importhow.d.ts +0 -15
- package/types/src/utils/importhow.d.ts.map +0 -1
- package/types/src/utils/index.d.ts +0 -3
- package/types/src/utils/index.d.ts.map +0 -1
- package/types/src/utils/meta-extractor.d.ts +0 -13
- package/types/src/utils/meta-extractor.d.ts.map +0 -1
package/src/loading/index.js
DELETED
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
// bertui/src/loading/index.js
|
|
2
|
-
// Built-in loading states - per route loading UI
|
|
3
|
-
|
|
4
|
-
import { join, extname, basename } from 'path';
|
|
5
|
-
import { existsSync, readdirSync } from 'fs';
|
|
6
|
-
import logger from '../logger/logger.js';
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Default loading spinner HTML injected into pages
|
|
10
|
-
* Beautiful, zero-dependency, CSS-only spinner
|
|
11
|
-
*/
|
|
12
|
-
export const DEFAULT_LOADING_HTML = `
|
|
13
|
-
<div id="bertui-loading" style="
|
|
14
|
-
position: fixed;
|
|
15
|
-
top: 0;
|
|
16
|
-
left: 0;
|
|
17
|
-
width: 100%;
|
|
18
|
-
height: 100%;
|
|
19
|
-
background: rgba(255,255,255,0.95);
|
|
20
|
-
display: flex;
|
|
21
|
-
flex-direction: column;
|
|
22
|
-
align-items: center;
|
|
23
|
-
justify-content: center;
|
|
24
|
-
z-index: 99999;
|
|
25
|
-
font-family: system-ui, sans-serif;
|
|
26
|
-
transition: opacity 0.2s ease;
|
|
27
|
-
">
|
|
28
|
-
<div style="
|
|
29
|
-
width: 40px;
|
|
30
|
-
height: 40px;
|
|
31
|
-
border: 3px solid #e5e7eb;
|
|
32
|
-
border-top-color: #10b981;
|
|
33
|
-
border-radius: 50%;
|
|
34
|
-
animation: bertui-spin 0.7s linear infinite;
|
|
35
|
-
"></div>
|
|
36
|
-
<p style="margin-top: 16px; color: #6b7280; font-size: 14px; font-weight: 500;">Loading...</p>
|
|
37
|
-
</div>
|
|
38
|
-
<style>
|
|
39
|
-
@keyframes bertui-spin {
|
|
40
|
-
to { transform: rotate(360deg); }
|
|
41
|
-
}
|
|
42
|
-
</style>
|
|
43
|
-
<script>
|
|
44
|
-
// Remove loading screen once React mounts
|
|
45
|
-
window.__BERTUI_HIDE_LOADING__ = function() {
|
|
46
|
-
const el = document.getElementById('bertui-loading');
|
|
47
|
-
if (el) {
|
|
48
|
-
el.style.opacity = '0';
|
|
49
|
-
setTimeout(() => el.remove(), 200);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
// Fallback: remove after 5s no matter what
|
|
54
|
-
setTimeout(() => window.__BERTUI_HIDE_LOADING__?.(), 5000);
|
|
55
|
-
|
|
56
|
-
// React root observer - hide when #root gets children
|
|
57
|
-
const observer = new MutationObserver(() => {
|
|
58
|
-
const root = document.getElementById('root');
|
|
59
|
-
if (root && root.children.length > 0) {
|
|
60
|
-
window.__BERTUI_HIDE_LOADING__?.();
|
|
61
|
-
observer.disconnect();
|
|
62
|
-
}
|
|
63
|
-
});
|
|
64
|
-
const root = document.getElementById('root');
|
|
65
|
-
if (root) observer.observe(root, { childList: true, subtree: true });
|
|
66
|
-
</script>
|
|
67
|
-
`;
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Discover per-route loading components from src/pages/
|
|
71
|
-
* Convention: create a loading.tsx next to your page file
|
|
72
|
-
* e.g., src/pages/blog/loading.tsx → shown while /blog loads
|
|
73
|
-
*/
|
|
74
|
-
export async function discoverLoadingComponents(root) {
|
|
75
|
-
const pagesDir = join(root, 'src', 'pages');
|
|
76
|
-
if (!existsSync(pagesDir)) return {};
|
|
77
|
-
|
|
78
|
-
const loadingComponents = {};
|
|
79
|
-
|
|
80
|
-
function scan(dir, routeBase = '') {
|
|
81
|
-
const entries = readdirSync(dir, { withFileTypes: true });
|
|
82
|
-
|
|
83
|
-
for (const entry of entries) {
|
|
84
|
-
const fullPath = join(dir, entry.name);
|
|
85
|
-
|
|
86
|
-
if (entry.isDirectory()) {
|
|
87
|
-
scan(fullPath, `${routeBase}/${entry.name}`);
|
|
88
|
-
} else if (entry.isFile()) {
|
|
89
|
-
const ext = extname(entry.name);
|
|
90
|
-
const name = basename(entry.name, ext);
|
|
91
|
-
|
|
92
|
-
if (name === 'loading' && ['.jsx', '.tsx', '.js', '.ts'].includes(ext)) {
|
|
93
|
-
const route = routeBase || '/';
|
|
94
|
-
loadingComponents[route] = {
|
|
95
|
-
path: fullPath,
|
|
96
|
-
route,
|
|
97
|
-
};
|
|
98
|
-
logger.debug(`⏳ Loading component: ${route} → ${entry.name}`);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
scan(pagesDir);
|
|
105
|
-
|
|
106
|
-
if (Object.keys(loadingComponents).length > 0) {
|
|
107
|
-
logger.success(`✅ ${Object.keys(loadingComponents).length} loading component(s) found`);
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
return loadingComponents;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/**
|
|
114
|
-
* Compile loading components to .bertui/compiled/loading/
|
|
115
|
-
*/
|
|
116
|
-
export async function compileLoadingComponents(root, compiledDir) {
|
|
117
|
-
const components = await discoverLoadingComponents(root);
|
|
118
|
-
if (Object.keys(components).length === 0) return components;
|
|
119
|
-
|
|
120
|
-
const outDir = join(compiledDir, 'loading');
|
|
121
|
-
const { mkdirSync } = await import('fs');
|
|
122
|
-
mkdirSync(outDir, { recursive: true });
|
|
123
|
-
|
|
124
|
-
for (const [route, comp] of Object.entries(components)) {
|
|
125
|
-
const ext = extname(comp.path);
|
|
126
|
-
const loader = ext === '.tsx' ? 'tsx' : ext === '.ts' ? 'ts' : 'jsx';
|
|
127
|
-
const safeName = route.replace(/\//g, '_').replace(/^_/, '') || 'root';
|
|
128
|
-
|
|
129
|
-
try {
|
|
130
|
-
let code = await Bun.file(comp.path).text();
|
|
131
|
-
|
|
132
|
-
if (!code.includes('import React')) {
|
|
133
|
-
code = `import React from 'react';\n${code}`;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
const transpiler = new Bun.Transpiler({
|
|
137
|
-
loader,
|
|
138
|
-
target: 'browser',
|
|
139
|
-
tsconfig: {
|
|
140
|
-
compilerOptions: {
|
|
141
|
-
jsx: 'react',
|
|
142
|
-
jsxFactory: 'React.createElement',
|
|
143
|
-
jsxFragmentFactory: 'React.Fragment',
|
|
144
|
-
},
|
|
145
|
-
},
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
const compiled = await transpiler.transform(code);
|
|
149
|
-
await Bun.write(join(outDir, `${safeName}.js`), compiled);
|
|
150
|
-
components[route].compiledPath = join(outDir, `${safeName}.js`);
|
|
151
|
-
components[route].compiledName = safeName;
|
|
152
|
-
|
|
153
|
-
} catch (err) {
|
|
154
|
-
logger.error(`Failed to compile loading component for ${route}: ${err.message}`);
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return components;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Generate loading-aware router code
|
|
163
|
-
* Wraps each route component with Suspense + loading fallback
|
|
164
|
-
*/
|
|
165
|
-
export function generateLoadingAwareRouter(routes, loadingComponents) {
|
|
166
|
-
const hasLoading = Object.keys(loadingComponents).length > 0;
|
|
167
|
-
|
|
168
|
-
const loadingImports = hasLoading
|
|
169
|
-
? Object.entries(loadingComponents)
|
|
170
|
-
.map(([route, comp]) => {
|
|
171
|
-
const safeName = comp.compiledName || (route.replace(/\//g, '_').replace(/^_/, '') || 'root');
|
|
172
|
-
return `import Loading_${safeName} from './loading/${safeName}.js';`;
|
|
173
|
-
})
|
|
174
|
-
.join('\n')
|
|
175
|
-
: '';
|
|
176
|
-
|
|
177
|
-
const getLoadingComponent = (route) => {
|
|
178
|
-
// Exact match
|
|
179
|
-
if (loadingComponents[route]) {
|
|
180
|
-
const safeName = loadingComponents[route].compiledName ||
|
|
181
|
-
(route.replace(/\//g, '_').replace(/^_/, '') || 'root');
|
|
182
|
-
return `Loading_${safeName}`;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
// Parent route match
|
|
186
|
-
const segments = route.split('/').filter(Boolean);
|
|
187
|
-
while (segments.length > 0) {
|
|
188
|
-
segments.pop();
|
|
189
|
-
const parent = '/' + segments.join('/') || '/';
|
|
190
|
-
if (loadingComponents[parent]) {
|
|
191
|
-
const safeName = loadingComponents[parent].compiledName ||
|
|
192
|
-
(parent.replace(/\//g, '_').replace(/^_/, '') || 'root');
|
|
193
|
-
return `Loading_${safeName}`;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return null;
|
|
198
|
-
};
|
|
199
|
-
|
|
200
|
-
return { loadingImports, getLoadingComponent };
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* Generate the default loading screen script to inject into HTML
|
|
205
|
-
*/
|
|
206
|
-
export function getLoadingScript(customText = 'Loading...', color = '#10b981') {
|
|
207
|
-
return DEFAULT_LOADING_HTML
|
|
208
|
-
.replace('Loading...', customText)
|
|
209
|
-
.replace('#10b981', color);
|
|
210
|
-
}
|
package/src/logger/logger.js
DELETED
|
@@ -1,320 +0,0 @@
|
|
|
1
|
-
// bertui/src/logger/logger.js
|
|
2
|
-
// Compact, progress-style CLI — replaces verbose line-by-line logs
|
|
3
|
-
|
|
4
|
-
import { createWriteStream } from 'fs';
|
|
5
|
-
import { join } from 'path';
|
|
6
|
-
import { mkdirSync, existsSync } from 'fs';
|
|
7
|
-
|
|
8
|
-
// ── ANSI helpers ─────────────────────────────────────────────────────────────
|
|
9
|
-
const C = {
|
|
10
|
-
reset: '\x1b[0m',
|
|
11
|
-
bold: '\x1b[1m',
|
|
12
|
-
dim: '\x1b[2m',
|
|
13
|
-
red: '\x1b[31m',
|
|
14
|
-
green: '\x1b[32m',
|
|
15
|
-
yellow: '\x1b[33m',
|
|
16
|
-
blue: '\x1b[34m',
|
|
17
|
-
magenta: '\x1b[35m',
|
|
18
|
-
cyan: '\x1b[36m',
|
|
19
|
-
white: '\x1b[37m',
|
|
20
|
-
bgBlack: '\x1b[40m',
|
|
21
|
-
bgRed: '\x1b[41m',
|
|
22
|
-
bgGreen: '\x1b[42m',
|
|
23
|
-
bgBlue: '\x1b[44m',
|
|
24
|
-
bgCyan: '\x1b[46m',
|
|
25
|
-
bgWhite: '\x1b[47m',
|
|
26
|
-
gray: '\x1b[90m',
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
const isTTY = process.stdout.isTTY;
|
|
30
|
-
|
|
31
|
-
// ── Spinner frames ────────────────────────────────────────────────────────────
|
|
32
|
-
const SPINNER = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏'];
|
|
33
|
-
let _spinnerFrame = 0;
|
|
34
|
-
let _spinnerTimer = null;
|
|
35
|
-
let _currentSpinnerLine = '';
|
|
36
|
-
|
|
37
|
-
// ── Internal state ────────────────────────────────────────────────────────────
|
|
38
|
-
let _mode = 'idle'; // 'idle' | 'build' | 'dev'
|
|
39
|
-
let _totalSteps = 10;
|
|
40
|
-
let _stepIndex = 0;
|
|
41
|
-
let _stepLabel = '';
|
|
42
|
-
let _stepDetail = '';
|
|
43
|
-
let _errors = [];
|
|
44
|
-
let _warnings = [];
|
|
45
|
-
let _startTime = null;
|
|
46
|
-
|
|
47
|
-
// ── Header ────────────────────────────────────────────────────────────────────
|
|
48
|
-
export function printHeader(mode = 'BUILD') {
|
|
49
|
-
_mode = mode.toLowerCase();
|
|
50
|
-
_startTime = Date.now();
|
|
51
|
-
_errors = [];
|
|
52
|
-
_warnings = [];
|
|
53
|
-
|
|
54
|
-
const W = 46;
|
|
55
|
-
const bar = '█'.repeat(W);
|
|
56
|
-
|
|
57
|
-
// Big block-letter BERTUI (6 rows)
|
|
58
|
-
const BIG = [
|
|
59
|
-
' ██████╗ ███████╗██████╗ ████████╗██╗ ██╗██╗',
|
|
60
|
-
' ██╔══██╗██╔════╝██╔══██╗╚══██╔══╝██║ ██║██║',
|
|
61
|
-
' ██████╔╝█████╗ ██████╔╝ ██║ ██║ ██║██║',
|
|
62
|
-
' ██╔══██╗██╔══╝ ██╔══██╗ ██║ ██║ ██║██║',
|
|
63
|
-
' ██████╔╝███████╗██║ ██║ ██║ ╚██████╔╝██║',
|
|
64
|
-
' ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝',
|
|
65
|
-
];
|
|
66
|
-
|
|
67
|
-
process.stdout.write('\n');
|
|
68
|
-
process.stdout.write(`${C.cyan}${C.bold} ${bar}${C.reset}\n`);
|
|
69
|
-
for (const row of BIG) {
|
|
70
|
-
process.stdout.write(`${C.cyan}${C.bold}${row}${C.reset}\n`);
|
|
71
|
-
}
|
|
72
|
-
process.stdout.write(`${C.gray} by Pease Ernest${C.reset}${C.gray} · ${C.reset}${C.white}${C.bold}${mode.toUpperCase()}${C.reset}\n`);
|
|
73
|
-
process.stdout.write(`${C.cyan}${C.bold} ${bar}${C.reset}\n`);
|
|
74
|
-
process.stdout.write('\n');
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// ── Step progress ─────────────────────────────────────────────────────────────
|
|
78
|
-
export function step(index, total, label, detail = '') {
|
|
79
|
-
_stepIndex = index;
|
|
80
|
-
_totalSteps = total;
|
|
81
|
-
_stepLabel = label;
|
|
82
|
-
_stepDetail = detail;
|
|
83
|
-
_stopSpinner();
|
|
84
|
-
_renderStep('running', detail);
|
|
85
|
-
_startSpinner();
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export function stepDone(label, detail = '') {
|
|
89
|
-
_stopSpinner();
|
|
90
|
-
_clearLine();
|
|
91
|
-
const idx = String(_stepIndex).padStart(2, ' ');
|
|
92
|
-
const lbl = (label || _stepLabel).padEnd(24, ' ');
|
|
93
|
-
const det = detail ? `${C.gray}${_truncate(detail, 38)}${C.reset}` : '';
|
|
94
|
-
process.stdout.write(
|
|
95
|
-
` ${C.gray}[${idx}/${_totalSteps}]${C.reset} ${C.green}✓${C.reset} ${C.white}${lbl}${C.reset} ${det}\n`
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function stepFail(label, detail = '') {
|
|
100
|
-
_stopSpinner();
|
|
101
|
-
_clearLine();
|
|
102
|
-
const idx = String(_stepIndex).padStart(2, ' ');
|
|
103
|
-
const lbl = (label || _stepLabel).padEnd(24, ' ');
|
|
104
|
-
process.stdout.write(
|
|
105
|
-
` ${C.gray}[${idx}/${_totalSteps}]${C.reset} ${C.red}✗${C.reset} ${C.white}${lbl}${C.reset} ${C.red}${detail}${C.reset}\n`
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// ── Inline file progress (replaces "Progress: 2/2 (100%)") ───────────────────
|
|
110
|
-
export function fileProgress(current, total, filename) {
|
|
111
|
-
if (!isTTY) return;
|
|
112
|
-
_clearLine();
|
|
113
|
-
const pct = Math.round((current / total) * 100);
|
|
114
|
-
const bar = _bar(pct, 16);
|
|
115
|
-
const name = _truncate(filename, 30);
|
|
116
|
-
_currentSpinnerLine =
|
|
117
|
-
` ${C.gray}[${String(_stepIndex).padStart(2,' ')}/${_totalSteps}]${C.reset}` +
|
|
118
|
-
` ${C.cyan}⠸${C.reset} ${C.white}${_stepLabel.padEnd(24,' ')}${C.reset}` +
|
|
119
|
-
` ${bar} ${C.gray}${current}/${total}${C.reset} ${C.dim}${name}${C.reset}`;
|
|
120
|
-
process.stdout.write('\r' + _currentSpinnerLine);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// ── Simple log levels (used internally, suppressed in compact mode) ───────────
|
|
124
|
-
export function info(msg) {
|
|
125
|
-
_debugLog('INFO', msg);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
export function success(msg) {
|
|
129
|
-
_debugLog('SUCCESS', msg);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export function warn(msg) {
|
|
133
|
-
_warnings.push(msg);
|
|
134
|
-
_stopSpinner();
|
|
135
|
-
_clearLine();
|
|
136
|
-
process.stdout.write(` ${C.yellow}⚠${C.reset} ${C.yellow}${msg}${C.reset}\n`);
|
|
137
|
-
if (_stepLabel) _startSpinner();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
export function error(msg) {
|
|
141
|
-
_errors.push(msg);
|
|
142
|
-
_stopSpinner();
|
|
143
|
-
_clearLine();
|
|
144
|
-
process.stdout.write(` ${C.red}✗${C.reset} ${C.red}${msg}${C.reset}\n`);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
export function debug(msg) {
|
|
148
|
-
_debugLog('DEBUG', msg);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// ── Table (kept for route/island tables but made compact) ─────────────────────
|
|
152
|
-
export function table(rows) {
|
|
153
|
-
if (!rows || rows.length === 0) return;
|
|
154
|
-
_stopSpinner();
|
|
155
|
-
const keys = Object.keys(rows[0]).filter(k => k !== '');
|
|
156
|
-
const widths = keys.map(k =>
|
|
157
|
-
Math.max(k.length, ...rows.map(r => String(r[k] ?? '').length))
|
|
158
|
-
);
|
|
159
|
-
|
|
160
|
-
const hr = ' ' + widths.map(w => '─'.repeat(w + 2)).join('┼') ;
|
|
161
|
-
const header = ' ' + keys.map((k, i) => ` ${C.bold}${k.padEnd(widths[i])}${C.reset} `).join('│');
|
|
162
|
-
|
|
163
|
-
process.stdout.write(`${C.gray}${hr}${C.reset}\n`);
|
|
164
|
-
process.stdout.write(`${header}\n`);
|
|
165
|
-
process.stdout.write(`${C.gray}${hr}${C.reset}\n`);
|
|
166
|
-
|
|
167
|
-
for (const row of rows) {
|
|
168
|
-
const line = ' ' + keys.map((k, i) => ` ${String(row[k] ?? '').padEnd(widths[i])} `).join(`${C.gray}│${C.reset}`);
|
|
169
|
-
process.stdout.write(`${line}\n`);
|
|
170
|
-
}
|
|
171
|
-
process.stdout.write(`${C.gray}${hr}${C.reset}\n`);
|
|
172
|
-
|
|
173
|
-
if (_stepLabel) _startSpinner();
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
// ── bigLog — replaced by section headers ─────────────────────────────────────
|
|
177
|
-
export function bigLog(title, opts = {}) {
|
|
178
|
-
_stopSpinner();
|
|
179
|
-
_clearLine();
|
|
180
|
-
process.stdout.write(`\n ${C.bold}${C.cyan}── ${title} ──${C.reset}\n\n`);
|
|
181
|
-
if (_stepLabel) _startSpinner();
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
// ── Build/Dev summary ─────────────────────────────────────────────────────────
|
|
185
|
-
export function printSummary(stats = {}) {
|
|
186
|
-
_stopSpinner();
|
|
187
|
-
// Close the log stream before printing summary
|
|
188
|
-
_closeLogStream();
|
|
189
|
-
|
|
190
|
-
process.stdout.write('\n');
|
|
191
|
-
|
|
192
|
-
const dur = _startTime ? `${((Date.now() - _startTime) / 1000).toFixed(2)}s` : '';
|
|
193
|
-
|
|
194
|
-
process.stdout.write(`${C.cyan}${C.bold} ────────────────────────────────────────────${C.reset}\n`);
|
|
195
|
-
process.stdout.write(`${C.green}${C.bold} ✓ Done${C.reset}${dur ? ` ${C.gray}${dur}${C.reset}` : ''}\n`);
|
|
196
|
-
|
|
197
|
-
if (stats.routes) _summaryLine('Routes', stats.routes);
|
|
198
|
-
if (stats.serverIslands)_summaryLine('Server Islands', stats.serverIslands);
|
|
199
|
-
if (stats.interactive) _summaryLine('Interactive', stats.interactive);
|
|
200
|
-
if (stats.staticRoutes) _summaryLine('Static', stats.staticRoutes);
|
|
201
|
-
if (stats.jsSize) _summaryLine('JS bundle', stats.jsSize);
|
|
202
|
-
if (stats.cssSize) _summaryLine('CSS bundle', stats.cssSize);
|
|
203
|
-
if (stats.outDir) _summaryLine('Output', stats.outDir);
|
|
204
|
-
|
|
205
|
-
if (_warnings.length > 0) {
|
|
206
|
-
process.stdout.write(`\n ${C.yellow}${_warnings.length} warning(s)${C.reset}\n`);
|
|
207
|
-
}
|
|
208
|
-
if (_errors.length > 0) {
|
|
209
|
-
process.stdout.write(`\n ${C.red}${_errors.length} error(s)${C.reset}\n`);
|
|
210
|
-
_errors.forEach(e => process.stdout.write(` ${C.red} · ${e}${C.reset}\n`));
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
process.stdout.write(`${C.cyan}${C.bold} ────────────────────────────────────────────${C.reset}\n\n`);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
function _summaryLine(label, value) {
|
|
217
|
-
process.stdout.write(
|
|
218
|
-
` ${C.gray}${label.padEnd(18)}${C.reset}${C.white}${value}${C.reset}\n`
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// ── Spinner internals ─────────────────────────────────────────────────────────
|
|
223
|
-
function _startSpinner() {
|
|
224
|
-
if (!isTTY || _spinnerTimer) return;
|
|
225
|
-
_spinnerTimer = setInterval(() => {
|
|
226
|
-
_spinnerFrame = (_spinnerFrame + 1) % SPINNER.length;
|
|
227
|
-
_renderStep('running', _stepDetail);
|
|
228
|
-
}, 80);
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function _stopSpinner() {
|
|
232
|
-
if (_spinnerTimer) {
|
|
233
|
-
clearInterval(_spinnerTimer);
|
|
234
|
-
_spinnerTimer = null;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
function _renderStep(state, detail = '') {
|
|
239
|
-
if (!isTTY) return;
|
|
240
|
-
_clearLine();
|
|
241
|
-
const spin = SPINNER[_spinnerFrame];
|
|
242
|
-
const idx = String(_stepIndex).padStart(2, ' ');
|
|
243
|
-
const lbl = _stepLabel.padEnd(24, ' ');
|
|
244
|
-
const det = detail ? `${C.gray}${_truncate(detail, 38)}${C.reset}` : '';
|
|
245
|
-
_currentSpinnerLine =
|
|
246
|
-
` ${C.gray}[${idx}/${_totalSteps}]${C.reset} ${C.cyan}${spin}${C.reset} ${C.white}${lbl}${C.reset} ${det}`;
|
|
247
|
-
process.stdout.write('\r' + _currentSpinnerLine);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function _clearLine() {
|
|
251
|
-
if (!isTTY) return;
|
|
252
|
-
process.stdout.write('\r\x1b[2K');
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// ── Helpers ───────────────────────────────────────────────────────────────────
|
|
256
|
-
function _bar(pct, width) {
|
|
257
|
-
const filled = Math.round((pct / 100) * width);
|
|
258
|
-
const empty = width - filled;
|
|
259
|
-
return `${C.cyan}${'█'.repeat(filled)}${C.gray}${'░'.repeat(empty)}${C.reset}`;
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function _truncate(str, max) {
|
|
263
|
-
if (!str) return '';
|
|
264
|
-
str = String(str);
|
|
265
|
-
return str.length > max ? '…' + str.slice(-(max - 1)) : str;
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
// ── Debug file log (always written, never shown in terminal) ──────────────────
|
|
269
|
-
let _logStream = null;
|
|
270
|
-
function _debugLog(level, msg) {
|
|
271
|
-
if (!_logStream) {
|
|
272
|
-
try {
|
|
273
|
-
const logDir = join(process.cwd(), '.bertui');
|
|
274
|
-
if (!existsSync(logDir)) {
|
|
275
|
-
mkdirSync(logDir, { recursive: true });
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
_logStream = createWriteStream(
|
|
279
|
-
join(logDir, 'dev.log'),
|
|
280
|
-
{ flags: 'a' }
|
|
281
|
-
);
|
|
282
|
-
} catch (err) {
|
|
283
|
-
return;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
const ts = new Date().toISOString().substring(11, 23);
|
|
287
|
-
_logStream.write(`[${ts}] [${level}] ${msg}\n`);
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
// NEW: Function to close the log stream
|
|
291
|
-
function _closeLogStream() {
|
|
292
|
-
if (_logStream) {
|
|
293
|
-
_logStream.end();
|
|
294
|
-
_logStream = null;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
|
|
298
|
-
// NEW: Cleanup function to be called when done
|
|
299
|
-
export function cleanup() {
|
|
300
|
-
_stopSpinner();
|
|
301
|
-
_closeLogStream();
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// ── Default export ────────────────────────────────────────────────────────────
|
|
305
|
-
export default {
|
|
306
|
-
printHeader,
|
|
307
|
-
step,
|
|
308
|
-
stepDone,
|
|
309
|
-
stepFail,
|
|
310
|
-
fileProgress,
|
|
311
|
-
info,
|
|
312
|
-
success,
|
|
313
|
-
warn,
|
|
314
|
-
error,
|
|
315
|
-
debug,
|
|
316
|
-
table,
|
|
317
|
-
bigLog,
|
|
318
|
-
printSummary,
|
|
319
|
-
cleanup, // Export cleanup function
|
|
320
|
-
};
|
package/src/logger/notes.md
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
here we will use the ernest logger libraray instead of chalk because i want colourfull logs and not just normal b/w logs the whole module is exported for use in the libraray
|
|
2
|
-
it is a file that is complete and needs no updated later on
|
|
3
|
-
// src/utils/logger.js
|
|
4
|
-
import { createLogger } from 'ernest-logger';
|
|
5
|
-
|
|
6
|
-
// Create logger instance for BertUI
|
|
7
|
-
const logger = createLogger({
|
|
8
|
-
time: true,
|
|
9
|
-
emoji: true,
|
|
10
|
-
level: 'info',
|
|
11
|
-
prefix: '[BertUI]',
|
|
12
|
-
customLevels: {
|
|
13
|
-
server: { color: 'brightCyan', emoji: '🌐', priority: 2 },
|
|
14
|
-
build: { color: 'brightGreen', emoji: '📦', priority: 2 },
|
|
15
|
-
hmr: { color: 'brightYellow', emoji: '🔥', priority: 2 }
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
// Export the logger
|
|
20
|
-
export default logger;
|