@vertz/ui-server 0.2.25 → 0.2.26
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/dist/bun-dev-server.js +244 -2
- package/dist/bun-plugin/index.d.ts +1 -1
- package/dist/index.d.ts +333 -85
- package/dist/index.js +655 -153
- package/package.json +5 -5
package/dist/bun-dev-server.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
|
|
10
10
|
// src/bun-dev-server.ts
|
|
11
11
|
import { execSync } from "child_process";
|
|
12
|
-
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, watch as watch2, writeFileSync as writeFileSync2 } from "fs";
|
|
12
|
+
import { existsSync as existsSync2, mkdirSync, readdirSync as readdirSync2, readFileSync as readFileSync2, watch as watch2, writeFileSync as writeFileSync2 } from "fs";
|
|
13
13
|
import { dirname, normalize, resolve } from "path";
|
|
14
14
|
|
|
15
15
|
// src/debug-logger.ts
|
|
@@ -644,6 +644,186 @@ function escapeAttr(s) {
|
|
|
644
644
|
return s.replace(/[&"'<>]/g, (c) => `&#${c.charCodeAt(0)};`);
|
|
645
645
|
}
|
|
646
646
|
|
|
647
|
+
// src/ssr-aot-manifest-dev.ts
|
|
648
|
+
import { compileForSSRAot } from "@vertz/ui-compiler";
|
|
649
|
+
|
|
650
|
+
// src/ssr-aot-diagnostics.ts
|
|
651
|
+
var MAX_DIVERGENCES = 20;
|
|
652
|
+
|
|
653
|
+
class AotDiagnostics {
|
|
654
|
+
_components = new Map;
|
|
655
|
+
_divergences = [];
|
|
656
|
+
recordCompilation(components) {
|
|
657
|
+
for (const comp of components) {
|
|
658
|
+
this._components.set(comp.name, {
|
|
659
|
+
tier: comp.tier,
|
|
660
|
+
holes: comp.holes
|
|
661
|
+
});
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
recordDivergence(component, aotHtml, domHtml) {
|
|
665
|
+
this._divergences.push({
|
|
666
|
+
component,
|
|
667
|
+
aotHtml,
|
|
668
|
+
domHtml,
|
|
669
|
+
timestamp: new Date().toISOString()
|
|
670
|
+
});
|
|
671
|
+
if (this._divergences.length > MAX_DIVERGENCES) {
|
|
672
|
+
this._divergences = this._divergences.slice(this._divergences.length - MAX_DIVERGENCES);
|
|
673
|
+
}
|
|
674
|
+
}
|
|
675
|
+
clear() {
|
|
676
|
+
this._components.clear();
|
|
677
|
+
this._divergences = [];
|
|
678
|
+
}
|
|
679
|
+
clearComponents() {
|
|
680
|
+
this._components.clear();
|
|
681
|
+
}
|
|
682
|
+
getClassificationLog() {
|
|
683
|
+
const lines = [];
|
|
684
|
+
for (const [name, comp] of this._components) {
|
|
685
|
+
let line = `${name}: ${comp.tier}`;
|
|
686
|
+
if (comp.holes.length > 0) {
|
|
687
|
+
line += `, ${comp.holes.length} hole${comp.holes.length > 1 ? "s" : ""} (${comp.holes.join(", ")})`;
|
|
688
|
+
}
|
|
689
|
+
lines.push(line);
|
|
690
|
+
}
|
|
691
|
+
const snapshot = this.getSnapshot();
|
|
692
|
+
const { total, aot, percentage } = snapshot.coverage;
|
|
693
|
+
if (total > 0) {
|
|
694
|
+
lines.push(`Coverage: ${aot}/${total} components (${percentage}%)`);
|
|
695
|
+
}
|
|
696
|
+
return lines;
|
|
697
|
+
}
|
|
698
|
+
getSnapshot() {
|
|
699
|
+
let aot = 0;
|
|
700
|
+
let runtime = 0;
|
|
701
|
+
for (const comp of this._components.values()) {
|
|
702
|
+
if (comp.tier === "runtime-fallback") {
|
|
703
|
+
runtime++;
|
|
704
|
+
} else {
|
|
705
|
+
aot++;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
const total = aot + runtime;
|
|
709
|
+
return {
|
|
710
|
+
components: Object.fromEntries(this._components),
|
|
711
|
+
coverage: {
|
|
712
|
+
total,
|
|
713
|
+
aot,
|
|
714
|
+
runtime,
|
|
715
|
+
percentage: total === 0 ? 0 : Math.round(aot / total * 100)
|
|
716
|
+
},
|
|
717
|
+
divergences: [...this._divergences]
|
|
718
|
+
};
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// src/ssr-aot-manifest-dev.ts
|
|
723
|
+
function createAotManifestManager(options) {
|
|
724
|
+
const { readFile: readFile2, listFiles } = options;
|
|
725
|
+
let currentManifest = null;
|
|
726
|
+
const diagnostics = new AotDiagnostics;
|
|
727
|
+
let rebuildCount = 0;
|
|
728
|
+
let lastRebuildMs = null;
|
|
729
|
+
let lastRebuildAt = null;
|
|
730
|
+
function compileFile(filePath, source) {
|
|
731
|
+
try {
|
|
732
|
+
const result = compileForSSRAot(source, { filename: filePath });
|
|
733
|
+
return result.components.map((comp) => ({
|
|
734
|
+
name: comp.name,
|
|
735
|
+
entry: {
|
|
736
|
+
tier: comp.tier,
|
|
737
|
+
holes: comp.holes,
|
|
738
|
+
file: filePath
|
|
739
|
+
}
|
|
740
|
+
}));
|
|
741
|
+
} catch {
|
|
742
|
+
return [];
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
function updateDiagnostics(manifest, isFullBuild) {
|
|
746
|
+
if (isFullBuild) {
|
|
747
|
+
diagnostics.clear();
|
|
748
|
+
} else {
|
|
749
|
+
diagnostics.clearComponents();
|
|
750
|
+
}
|
|
751
|
+
const entries = Object.entries(manifest.components).map(([name, entry]) => ({
|
|
752
|
+
name,
|
|
753
|
+
tier: entry.tier,
|
|
754
|
+
holes: entry.holes
|
|
755
|
+
}));
|
|
756
|
+
diagnostics.recordCompilation(entries);
|
|
757
|
+
}
|
|
758
|
+
function fullBuild() {
|
|
759
|
+
const start = performance.now();
|
|
760
|
+
const files = listFiles();
|
|
761
|
+
const components = {};
|
|
762
|
+
for (const filePath of files) {
|
|
763
|
+
if (!filePath.endsWith(".tsx"))
|
|
764
|
+
continue;
|
|
765
|
+
const source = readFile2(filePath);
|
|
766
|
+
if (!source)
|
|
767
|
+
continue;
|
|
768
|
+
const entries = compileFile(filePath, source);
|
|
769
|
+
for (const { name, entry } of entries) {
|
|
770
|
+
components[name] = entry;
|
|
771
|
+
}
|
|
772
|
+
}
|
|
773
|
+
currentManifest = { components };
|
|
774
|
+
updateDiagnostics(currentManifest, true);
|
|
775
|
+
rebuildCount++;
|
|
776
|
+
lastRebuildMs = Math.round(performance.now() - start);
|
|
777
|
+
lastRebuildAt = new Date().toISOString();
|
|
778
|
+
}
|
|
779
|
+
function incrementalUpdate(filePath, sourceText) {
|
|
780
|
+
if (!currentManifest)
|
|
781
|
+
return;
|
|
782
|
+
const start = performance.now();
|
|
783
|
+
const newComponents = { ...currentManifest.components };
|
|
784
|
+
for (const [name, entry] of Object.entries(newComponents)) {
|
|
785
|
+
if (entry.file === filePath) {
|
|
786
|
+
delete newComponents[name];
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
if (sourceText.trim()) {
|
|
790
|
+
const entries = compileFile(filePath, sourceText);
|
|
791
|
+
for (const { name, entry } of entries) {
|
|
792
|
+
newComponents[name] = entry;
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
currentManifest = { components: newComponents };
|
|
796
|
+
updateDiagnostics(currentManifest, false);
|
|
797
|
+
rebuildCount++;
|
|
798
|
+
lastRebuildMs = Math.round(performance.now() - start);
|
|
799
|
+
lastRebuildAt = new Date().toISOString();
|
|
800
|
+
}
|
|
801
|
+
return {
|
|
802
|
+
build() {
|
|
803
|
+
fullBuild();
|
|
804
|
+
},
|
|
805
|
+
onFileChange(filePath, sourceText) {
|
|
806
|
+
if (!filePath.endsWith(".tsx"))
|
|
807
|
+
return;
|
|
808
|
+
incrementalUpdate(filePath, sourceText);
|
|
809
|
+
},
|
|
810
|
+
getManifest() {
|
|
811
|
+
return currentManifest;
|
|
812
|
+
},
|
|
813
|
+
getSnapshot() {
|
|
814
|
+
return {
|
|
815
|
+
manifest: currentManifest,
|
|
816
|
+
rebuildCount,
|
|
817
|
+
lastRebuildMs,
|
|
818
|
+
lastRebuildAt
|
|
819
|
+
};
|
|
820
|
+
},
|
|
821
|
+
getDiagnostics() {
|
|
822
|
+
return diagnostics;
|
|
823
|
+
}
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
|
|
647
827
|
// src/ssr-prefetch-dev.ts
|
|
648
828
|
import {
|
|
649
829
|
analyzeComponentQueries,
|
|
@@ -2726,6 +2906,18 @@ function clearSSRRequireCache() {
|
|
|
2726
2906
|
}
|
|
2727
2907
|
return keys.length;
|
|
2728
2908
|
}
|
|
2909
|
+
function collectFiles(dir) {
|
|
2910
|
+
const files = [];
|
|
2911
|
+
for (const entry of readdirSync2(dir, { withFileTypes: true })) {
|
|
2912
|
+
const fullPath = resolve(dir, entry.name);
|
|
2913
|
+
if (entry.isDirectory()) {
|
|
2914
|
+
files.push(...collectFiles(fullPath));
|
|
2915
|
+
} else {
|
|
2916
|
+
files.push(fullPath);
|
|
2917
|
+
}
|
|
2918
|
+
}
|
|
2919
|
+
return files;
|
|
2920
|
+
}
|
|
2729
2921
|
function createBunDevServer(options) {
|
|
2730
2922
|
const {
|
|
2731
2923
|
entry,
|
|
@@ -2756,6 +2948,7 @@ function createBunDevServer(options) {
|
|
|
2756
2948
|
mkdirSync(devDir, { recursive: true });
|
|
2757
2949
|
const logger = createDebugLogger(devDir);
|
|
2758
2950
|
const diagnostics = new DiagnosticsCollector;
|
|
2951
|
+
let aotManifestManager = null;
|
|
2759
2952
|
let server = null;
|
|
2760
2953
|
let srcWatcherRef = null;
|
|
2761
2954
|
let refreshTimeout = null;
|
|
@@ -3170,6 +3363,36 @@ function createBunDevServer(options) {
|
|
|
3170
3363
|
prefetchManager = null;
|
|
3171
3364
|
}
|
|
3172
3365
|
}
|
|
3366
|
+
aotManifestManager = createAotManifestManager({
|
|
3367
|
+
readFile: (path) => {
|
|
3368
|
+
try {
|
|
3369
|
+
return readFileSync2(path, "utf-8");
|
|
3370
|
+
} catch {
|
|
3371
|
+
return;
|
|
3372
|
+
}
|
|
3373
|
+
},
|
|
3374
|
+
listFiles: () => {
|
|
3375
|
+
try {
|
|
3376
|
+
return collectFiles(srcDir);
|
|
3377
|
+
} catch {
|
|
3378
|
+
return [];
|
|
3379
|
+
}
|
|
3380
|
+
}
|
|
3381
|
+
});
|
|
3382
|
+
try {
|
|
3383
|
+
const aotStart = performance.now();
|
|
3384
|
+
aotManifestManager.build();
|
|
3385
|
+
const aotMs = Math.round(performance.now() - aotStart);
|
|
3386
|
+
logger.log("aot", "initial-build", { durationMs: aotMs });
|
|
3387
|
+
if (logRequests) {
|
|
3388
|
+
const manifest = aotManifestManager.getManifest();
|
|
3389
|
+
const count = manifest ? Object.keys(manifest.components).length : 0;
|
|
3390
|
+
console.log(`[Server] AOT manifest built (${count} components, ${aotMs}ms)`);
|
|
3391
|
+
}
|
|
3392
|
+
} catch (e) {
|
|
3393
|
+
console.warn("[Server] Failed to build AOT manifest:", e instanceof Error ? e.message : e);
|
|
3394
|
+
aotManifestManager = null;
|
|
3395
|
+
}
|
|
3173
3396
|
mkdirSync(devDir, { recursive: true });
|
|
3174
3397
|
const frInitPath = resolve(devDir, "fast-refresh-init.ts");
|
|
3175
3398
|
writeFileSync2(frInitPath, `import '@vertz/ui-server/fast-refresh-runtime';
|
|
@@ -3260,6 +3483,12 @@ if (import.meta.hot) import.meta.hot.accept();
|
|
|
3260
3483
|
if (pathname === "/__vertz_diagnostics") {
|
|
3261
3484
|
return Response.json(diagnostics.getSnapshot());
|
|
3262
3485
|
}
|
|
3486
|
+
if (pathname === "/__vertz_ssr_aot") {
|
|
3487
|
+
if (!aotManifestManager) {
|
|
3488
|
+
return Response.json({ error: "AOT manifest manager not available" }, { status: 404 });
|
|
3489
|
+
}
|
|
3490
|
+
return Response.json(aotManifestManager.getDiagnostics().getSnapshot());
|
|
3491
|
+
}
|
|
3263
3492
|
if (pathname === "/__vertz_prefetch_manifest") {
|
|
3264
3493
|
if (!prefetchManager) {
|
|
3265
3494
|
return Response.json({ error: "No prefetch manifest available (router file not found)" }, { status: 404 });
|
|
@@ -3687,7 +3916,20 @@ data: {}
|
|
|
3687
3916
|
isRouter: changedFilePath === routerPath
|
|
3688
3917
|
});
|
|
3689
3918
|
}
|
|
3690
|
-
|
|
3919
|
+
if (aotManifestManager) {
|
|
3920
|
+
const aotStart = performance.now();
|
|
3921
|
+
aotManifestManager.onFileChange(changedFilePath, source);
|
|
3922
|
+
const aotMs = Math.round(performance.now() - aotStart);
|
|
3923
|
+
logger.log("aot", "rebuild", {
|
|
3924
|
+
file: lastChangedFile,
|
|
3925
|
+
durationMs: aotMs
|
|
3926
|
+
});
|
|
3927
|
+
}
|
|
3928
|
+
} catch {
|
|
3929
|
+
if (aotManifestManager) {
|
|
3930
|
+
aotManifestManager.onFileChange(changedFilePath, "");
|
|
3931
|
+
}
|
|
3932
|
+
}
|
|
3691
3933
|
}
|
|
3692
3934
|
if (stopped)
|
|
3693
3935
|
return;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
type ErrorCategory = "build" | "resolve" | "runtime" | "ssr";
|
|
2
2
|
import { CSSExtractionResult } from "@vertz/ui-compiler";
|
|
3
|
-
type DebugCategory = "fields" | "manifest" | "plugin" | "prefetch" | "ssr" | "watcher" | "ws";
|
|
3
|
+
type DebugCategory = "aot" | "fields" | "manifest" | "plugin" | "prefetch" | "ssr" | "watcher" | "ws";
|
|
4
4
|
interface DebugLogger {
|
|
5
5
|
log(category: DebugCategory, message: string, data?: Record<string, unknown>): void;
|
|
6
6
|
isEnabled(category: DebugCategory): boolean;
|