@vertz/ui-server 0.2.35 → 0.2.36
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.d.ts +2 -1
- package/dist/bun-dev-server.js +21 -1
- package/dist/bun-plugin/index.js +73 -14
- package/dist/index.d.ts +23 -1
- package/dist/index.js +3 -3
- package/dist/node-handler.d.ts +20 -0
- package/dist/node-handler.js +2 -2
- package/dist/shared/{chunk-fv51ctcf.js → chunk-9s2dppdh.js} +1 -1
- package/dist/shared/{chunk-tqa618t8.js → chunk-hjsbx25c.js} +7 -5
- package/dist/shared/{chunk-bggdy77b.js → chunk-wq2ke61r.js} +13 -0
- package/dist/ssr/index.d.ts +21 -1
- package/dist/ssr/index.js +2 -2
- package/package.json +5 -5
package/dist/bun-dev-server.d.ts
CHANGED
|
@@ -126,6 +126,7 @@ interface ErrorDetail {
|
|
|
126
126
|
}
|
|
127
127
|
type ErrorCategory = "build" | "resolve" | "runtime" | "ssr";
|
|
128
128
|
declare function isStaleGraphError(message: string): boolean;
|
|
129
|
+
declare function parsePluginError(text: string): ErrorDetail | null;
|
|
129
130
|
/**
|
|
130
131
|
* Detect Bun's reload stub — the response served when the dev bundler
|
|
131
132
|
* fails to compile a client module. The stub is literally:
|
|
@@ -257,4 +258,4 @@ declare function clearSSRRequireCache(): number;
|
|
|
257
258
|
* SSR is always on. HMR always works. No mode toggle needed.
|
|
258
259
|
*/
|
|
259
260
|
declare function createBunDevServer(options: BunDevServerOptions): BunDevServer;
|
|
260
|
-
export { shouldCheckStaleBundler, parseHMRAssets, isStaleGraphError, isReloadStub, generateSSRPageHtml, formatTerminalRuntimeError, detectFaviconTag, createRuntimeErrorDeduplicator, createFetchInterceptor, createBunDevServer, clearSSRRequireCache, buildScriptTag, SSRPageHtmlOptions, HMRAssets, FetchInterceptorOptions, ErrorDetail, ErrorCategory, BunDevServerOptions, BunDevServer };
|
|
261
|
+
export { shouldCheckStaleBundler, parsePluginError, parseHMRAssets, isStaleGraphError, isReloadStub, generateSSRPageHtml, formatTerminalRuntimeError, detectFaviconTag, createRuntimeErrorDeduplicator, createFetchInterceptor, createBunDevServer, clearSSRRequireCache, buildScriptTag, SSRPageHtmlOptions, HMRAssets, FetchInterceptorOptions, ErrorDetail, ErrorCategory, BunDevServerOptions, BunDevServer };
|
package/dist/bun-dev-server.js
CHANGED
|
@@ -2559,6 +2559,19 @@ var STALE_GRAPH_PATTERNS = [
|
|
|
2559
2559
|
function isStaleGraphError(message) {
|
|
2560
2560
|
return STALE_GRAPH_PATTERNS.some((pattern) => pattern.test(message));
|
|
2561
2561
|
}
|
|
2562
|
+
var PLUGIN_ERROR_PATTERN = /\[vertz-bun-plugin\] Failed to process (.+?): ([\s\S]*)/;
|
|
2563
|
+
var LINE_COL_PATTERN = /\((\d+):(\d+)\)/;
|
|
2564
|
+
function parsePluginError(text) {
|
|
2565
|
+
const match = text.match(PLUGIN_ERROR_PATTERN);
|
|
2566
|
+
if (!match)
|
|
2567
|
+
return null;
|
|
2568
|
+
const file = match[1];
|
|
2569
|
+
const message = match[2]?.trim() || "Compilation failed";
|
|
2570
|
+
const locMatch = message.match(LINE_COL_PATTERN);
|
|
2571
|
+
const line = locMatch ? Number(locMatch[1]) : undefined;
|
|
2572
|
+
const column = locMatch ? Number(locMatch[2]) : undefined;
|
|
2573
|
+
return { message, file, line, column };
|
|
2574
|
+
}
|
|
2562
2575
|
function isReloadStub(text) {
|
|
2563
2576
|
return text.trimStart().startsWith("try{location.reload()}");
|
|
2564
2577
|
}
|
|
@@ -3125,7 +3138,13 @@ function createBunDevServer(options) {
|
|
|
3125
3138
|
const text = args.map((a) => typeof a === "string" ? a : String(a)).join(" ");
|
|
3126
3139
|
if (!text.startsWith("[Server]")) {
|
|
3127
3140
|
lastBuildError = text;
|
|
3128
|
-
|
|
3141
|
+
const pluginErr = parsePluginError(text);
|
|
3142
|
+
if (pluginErr && text !== lastBroadcastedError) {
|
|
3143
|
+
lastBroadcastedError = text;
|
|
3144
|
+
const absFile = pluginErr.file ? resolve(projectRoot, pluginErr.file) : undefined;
|
|
3145
|
+
const lineText = pluginErr.line && absFile ? readLineText(absFile, pluginErr.line) : undefined;
|
|
3146
|
+
broadcastError("build", [{ ...pluginErr, absFile, lineText }]);
|
|
3147
|
+
} else if (resolvePatterns.some((p) => text.includes(p)) && text !== lastBroadcastedError) {
|
|
3129
3148
|
lastBroadcastedError = text;
|
|
3130
3149
|
broadcastError("resolve", [{ message: text }]);
|
|
3131
3150
|
} else {
|
|
@@ -4196,6 +4215,7 @@ data: {}
|
|
|
4196
4215
|
}
|
|
4197
4216
|
export {
|
|
4198
4217
|
shouldCheckStaleBundler,
|
|
4218
|
+
parsePluginError,
|
|
4199
4219
|
parseHMRAssets,
|
|
4200
4220
|
isStaleGraphError,
|
|
4201
4221
|
isReloadStub,
|
package/dist/bun-plugin/index.js
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
|
|
10
10
|
// src/bun-plugin/plugin.ts
|
|
11
11
|
import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "fs";
|
|
12
|
-
import { dirname, relative, resolve as
|
|
12
|
+
import { dirname, relative, resolve as resolve3 } from "path";
|
|
13
13
|
import remapping from "@ampproject/remapping";
|
|
14
14
|
import {
|
|
15
15
|
ComponentAnalyzer,
|
|
@@ -55,6 +55,39 @@ function injectContextStableIds(source, sourceFile, relFilePath) {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
// src/bun-plugin/native-compiler-loader.ts
|
|
59
|
+
import { existsSync } from "fs";
|
|
60
|
+
import { join, resolve } from "path";
|
|
61
|
+
var __dirname = "/home/runner/work/vertz/vertz/packages/ui-server/src/bun-plugin";
|
|
62
|
+
function tryLoadNativeCompiler() {
|
|
63
|
+
if (process.env.VERTZ_NATIVE_COMPILER !== "1") {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
const platform = process.platform === "darwin" ? "darwin" : "linux";
|
|
67
|
+
const arch = process.arch === "arm64" ? "arm64" : "x64";
|
|
68
|
+
const binaryName = `vertz-compiler.${platform}-${arch}.node`;
|
|
69
|
+
try {
|
|
70
|
+
const modulePath = __require.resolve(`@vertz/native-compiler/${binaryName}`);
|
|
71
|
+
return __require(modulePath);
|
|
72
|
+
} catch {}
|
|
73
|
+
let dir = resolve(__dirname);
|
|
74
|
+
for (let i = 0;i < 10; i++) {
|
|
75
|
+
const candidate = join(dir, "native", "vertz-compiler", binaryName);
|
|
76
|
+
if (existsSync(candidate)) {
|
|
77
|
+
try {
|
|
78
|
+
return __require(candidate);
|
|
79
|
+
} catch {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
const parent = resolve(dir, "..");
|
|
84
|
+
if (parent === dir)
|
|
85
|
+
break;
|
|
86
|
+
dir = parent;
|
|
87
|
+
}
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
58
91
|
// src/bun-plugin/entity-schema-loader.ts
|
|
59
92
|
import { readFileSync } from "fs";
|
|
60
93
|
function loadEntitySchema(schemaPath) {
|
|
@@ -491,8 +524,8 @@ function filePathHash(filePath) {
|
|
|
491
524
|
|
|
492
525
|
// src/bun-plugin/image-processor.ts
|
|
493
526
|
import { createHash } from "crypto";
|
|
494
|
-
import { existsSync, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
495
|
-
import { basename, extname, resolve } from "path";
|
|
527
|
+
import { existsSync as existsSync2, mkdirSync, readFileSync as readFileSync2, writeFileSync } from "fs";
|
|
528
|
+
import { basename, extname, resolve as resolve2 } from "path";
|
|
496
529
|
import sharp from "sharp";
|
|
497
530
|
var FORMAT_MAP = {
|
|
498
531
|
jpeg: { ext: ".jpg", mime: "image/jpeg" },
|
|
@@ -505,7 +538,7 @@ var FORMAT_MAP = {
|
|
|
505
538
|
};
|
|
506
539
|
async function processImage(opts) {
|
|
507
540
|
const { sourcePath, width, height, quality, fit, outputDir } = opts;
|
|
508
|
-
if (!
|
|
541
|
+
if (!existsSync2(sourcePath)) {
|
|
509
542
|
return { ok: false, error: `Image not found: ${sourcePath}` };
|
|
510
543
|
}
|
|
511
544
|
const sourceBuffer = readFileSync2(sourcePath);
|
|
@@ -518,10 +551,10 @@ async function processImage(opts) {
|
|
|
518
551
|
const webp1xName = `${name}-${hash}-${width}w.webp`;
|
|
519
552
|
const webp2xName = `${name}-${hash}-${width * 2}w.webp`;
|
|
520
553
|
const fallbackName = `${name}-${hash}-${width * 2}w${formatInfo.ext}`;
|
|
521
|
-
const webp1xPath =
|
|
522
|
-
const webp2xPath =
|
|
523
|
-
const fallbackPath =
|
|
524
|
-
if (
|
|
554
|
+
const webp1xPath = resolve2(outputDir, webp1xName);
|
|
555
|
+
const webp2xPath = resolve2(outputDir, webp2xName);
|
|
556
|
+
const fallbackPath = resolve2(outputDir, fallbackName);
|
|
557
|
+
if (existsSync2(webp1xPath) && existsSync2(webp2xPath) && existsSync2(fallbackPath)) {
|
|
525
558
|
return {
|
|
526
559
|
ok: true,
|
|
527
560
|
webp1x: { path: webp1xPath, url: `/__vertz_img/${webp1xName}` },
|
|
@@ -935,14 +968,14 @@ function createVertzBunPlugin(options) {
|
|
|
935
968
|
const fastRefresh = options?.fastRefresh ?? hmr;
|
|
936
969
|
const routeSplitting = options?.routeSplitting ?? false;
|
|
937
970
|
const projectRoot = options?.projectRoot ?? process.cwd();
|
|
938
|
-
const cssOutDir = options?.cssOutDir ??
|
|
971
|
+
const cssOutDir = options?.cssOutDir ?? resolve3(projectRoot, ".vertz", "css");
|
|
939
972
|
const cssExtractor = new CSSExtractor;
|
|
940
973
|
const componentAnalyzer = new ComponentAnalyzer;
|
|
941
974
|
const logger = options?.logger;
|
|
942
975
|
const diagnostics = options?.diagnostics;
|
|
943
976
|
const fileExtractions = new Map;
|
|
944
977
|
const cssSidecarMap = new Map;
|
|
945
|
-
const srcDir = options?.srcDir ??
|
|
978
|
+
const srcDir = options?.srcDir ?? resolve3(projectRoot, "src");
|
|
946
979
|
const frameworkManifestJson = __require(__require.resolve("@vertz/ui/reactivity.json"));
|
|
947
980
|
const manifestResult = generateAllManifests({
|
|
948
981
|
srcDir,
|
|
@@ -997,7 +1030,7 @@ function createVertzBunPlugin(options) {
|
|
|
997
1030
|
}
|
|
998
1031
|
}
|
|
999
1032
|
diagnostics?.recordFieldSelectionManifest(fieldSelectionFileCount);
|
|
1000
|
-
const entitySchemaPath = options?.entitySchemaPath ??
|
|
1033
|
+
const entitySchemaPath = options?.entitySchemaPath ?? resolve3(projectRoot, ".vertz", "generated", "entity-schema.json");
|
|
1001
1034
|
let entitySchema = loadEntitySchema(entitySchemaPath);
|
|
1002
1035
|
if (logger?.isEnabled("fields") && entitySchema) {
|
|
1003
1036
|
logger.log("fields", "entity-schema-loaded", {
|
|
@@ -1005,6 +1038,8 @@ function createVertzBunPlugin(options) {
|
|
|
1005
1038
|
entities: Object.keys(entitySchema).length
|
|
1006
1039
|
});
|
|
1007
1040
|
}
|
|
1041
|
+
const nativeCompiler = tryLoadNativeCompiler();
|
|
1042
|
+
let nativeManifestWarningLogged = false;
|
|
1008
1043
|
mkdirSync2(cssOutDir, { recursive: true });
|
|
1009
1044
|
const plugin = {
|
|
1010
1045
|
name: "vertz-bun-plugin",
|
|
@@ -1094,7 +1129,7 @@ function createVertzBunPlugin(options) {
|
|
|
1094
1129
|
}))
|
|
1095
1130
|
});
|
|
1096
1131
|
}
|
|
1097
|
-
const imageOutputDir =
|
|
1132
|
+
const imageOutputDir = resolve3(projectRoot, ".vertz", "images");
|
|
1098
1133
|
const imageQueue = [];
|
|
1099
1134
|
const imageResult = transformImages(codeForCompile, args.path, {
|
|
1100
1135
|
projectRoot,
|
|
@@ -1124,7 +1159,31 @@ function createVertzBunPlugin(options) {
|
|
|
1124
1159
|
if (imageQueue.length > 0) {
|
|
1125
1160
|
await Promise.all(imageQueue.map((opts) => processImage({ ...opts, fit: opts.fit })));
|
|
1126
1161
|
}
|
|
1127
|
-
const compileResult =
|
|
1162
|
+
const compileResult = nativeCompiler ? (() => {
|
|
1163
|
+
if (!nativeManifestWarningLogged && manifests.size > 0) {
|
|
1164
|
+
nativeManifestWarningLogged = true;
|
|
1165
|
+
const userManifestCount = [...manifests.keys()].filter((k) => !k.includes("node_modules")).length;
|
|
1166
|
+
if (userManifestCount > 0) {
|
|
1167
|
+
console.warn(`[vertz-bun-plugin] Native compiler does not support cross-file reactivity manifests. ` + `${userManifestCount} user module(s) with exported signal APIs will not have ` + `.value insertion for their signal properties. ` + `Set VERTZ_NATIVE_COMPILER=0 if cross-file reactivity is needed.`);
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1170
|
+
const nativeResult = nativeCompiler.compile(codeAfterImageTransform, {
|
|
1171
|
+
filename: args.path,
|
|
1172
|
+
target: options?.target,
|
|
1173
|
+
fastRefresh: false
|
|
1174
|
+
});
|
|
1175
|
+
return {
|
|
1176
|
+
code: nativeResult.code,
|
|
1177
|
+
map: nativeResult.map ? JSON.parse(nativeResult.map) : { version: 3, sources: [], mappings: "", names: [] },
|
|
1178
|
+
diagnostics: (nativeResult.diagnostics ?? []).map((d) => ({
|
|
1179
|
+
code: "native-diagnostic",
|
|
1180
|
+
message: d.message,
|
|
1181
|
+
severity: "warning",
|
|
1182
|
+
line: d.line ?? 1,
|
|
1183
|
+
column: d.column ?? 0
|
|
1184
|
+
}))
|
|
1185
|
+
};
|
|
1186
|
+
})() : compile(codeAfterImageTransform, {
|
|
1128
1187
|
filename: args.path,
|
|
1129
1188
|
target: options?.target,
|
|
1130
1189
|
manifests: getManifestsRecord()
|
|
@@ -1145,7 +1204,7 @@ function createVertzBunPlugin(options) {
|
|
|
1145
1204
|
if (hmr) {
|
|
1146
1205
|
const hash = filePathHash(args.path);
|
|
1147
1206
|
const cssFileName = `${hash}.css`;
|
|
1148
|
-
const cssFilePath =
|
|
1207
|
+
const cssFilePath = resolve3(cssOutDir, cssFileName);
|
|
1149
1208
|
writeFileSync2(cssFilePath, extraction.css);
|
|
1150
1209
|
cssSidecarMap.set(args.path, cssFilePath);
|
|
1151
1210
|
const relPath2 = relative(dirname(args.path), cssFilePath);
|
package/dist/index.d.ts
CHANGED
|
@@ -302,6 +302,18 @@ interface AotManifest {
|
|
|
302
302
|
/** Route pattern → AOT entry. */
|
|
303
303
|
routes: Record<string, AotRouteEntry>;
|
|
304
304
|
}
|
|
305
|
+
/**
|
|
306
|
+
* Resolves custom data for AOT-rendered routes.
|
|
307
|
+
*
|
|
308
|
+
* Called after the entity prefetch pipeline, before the `allKeysResolved` bail check.
|
|
309
|
+
* Only called when there are unresolved query keys remaining.
|
|
310
|
+
*
|
|
311
|
+
* @param pattern - Matched route pattern (e.g., '/products/:id')
|
|
312
|
+
* @param params - Route params (e.g., \{ id: 'abc-123' \})
|
|
313
|
+
* @param unresolvedKeys - Query keys not yet populated by entity prefetch
|
|
314
|
+
* @returns Map of cache key → data, or empty Map to skip
|
|
315
|
+
*/
|
|
316
|
+
type AotDataResolver = (pattern: string, params: Record<string, string>, unresolvedKeys: string[]) => Promise<Map<string, unknown>> | Map<string, unknown>;
|
|
305
317
|
/** Options for `ssrRenderAot()`. */
|
|
306
318
|
interface SSRRenderAotOptions {
|
|
307
319
|
/** AOT manifest with pre-compiled render functions. */
|
|
@@ -318,6 +330,8 @@ interface SSRRenderAotOptions {
|
|
|
318
330
|
prefetchSession?: PrefetchSession;
|
|
319
331
|
/** AOT diagnostics collector (dev mode). When provided with VERTZ_DEBUG=aot, enables dual rendering and divergence detection. */
|
|
320
332
|
diagnostics?: AotDiagnostics;
|
|
333
|
+
/** Custom data resolver for non-entity AOT routes. */
|
|
334
|
+
aotDataResolver?: AotDataResolver;
|
|
321
335
|
}
|
|
322
336
|
/**
|
|
323
337
|
* Create closure-based runtime fallback renderers for components
|
|
@@ -465,6 +479,14 @@ interface SSRHandlerOptions {
|
|
|
465
479
|
* Load via `loadAotManifest(serverDir)` at startup.
|
|
466
480
|
*/
|
|
467
481
|
aotManifest?: AotManifest;
|
|
482
|
+
/**
|
|
483
|
+
* Custom data resolver for AOT routes with non-entity data sources.
|
|
484
|
+
*
|
|
485
|
+
* Called after entity prefetch, with only the unresolved query keys.
|
|
486
|
+
* Enables AOT rendering for routes that use custom data layers
|
|
487
|
+
* (JSON files, third-party APIs, custom DB clients).
|
|
488
|
+
*/
|
|
489
|
+
aotDataResolver?: AotDataResolver;
|
|
468
490
|
}
|
|
469
491
|
declare function createSSRHandler(options: SSRHandlerOptions): (request: Request) => Promise<Response>;
|
|
470
492
|
type NodeHandlerOptions = SSRHandlerOptions;
|
|
@@ -1134,4 +1156,4 @@ declare function collectStreamChunks(stream: ReadableStream<Uint8Array>): Promis
|
|
|
1134
1156
|
* @param nonce - Optional CSP nonce to add to the inline script tag.
|
|
1135
1157
|
*/
|
|
1136
1158
|
declare function createTemplateChunk(slotId: number, resolvedHtml: string, nonce?: string): string;
|
|
1137
|
-
export { wrapWithHydrationMarkers, toPrefetchSession, streamToString, ssrStorage, ssrRenderToString, ssrRenderSinglePass, ssrRenderAot, ssrDiscoverQueries, setGlobalSSRTimeout, serializeToHtml, safeSerialize, resetSlotCounter, renderToStream, renderToHTMLStream, renderToHTML, renderPage, renderHeadToHtml, renderAssetTags, registerSSRQuery, reconstructDescriptors, rawHtml, matchUrlToPatterns, loadAotManifest, isInSSR, isAotDebugEnabled, inlineCriticalCss, getStreamingRuntimeScript, getSSRUrl, getSSRQueries, getGlobalSSRTimeout, getAccessSetForSSR, generateSSRHtml, generateAotBuildManifest, generateAotBarrel, extractRoutes, extractFontMetrics, evaluateAccessRule, encodeChunk, detectFallbackFont, createTemplateChunk, createSlotPlaceholder, createSessionScript, createSSRHandler, createSSRDataChunk, createSSRAdapter, createPrefetchManifestManager, createNodeHandler, createHoles, createAotManifestManager, createAccessSetScript, collectStreamChunks, clearGlobalSSRTimeout, buildAotRouteMap, __ssr_style_object, __ssr_spread, __esc_attr, __esc, VNode, SessionResolver, SessionData, SerializedAccessRule, SSRSinglePassOptions, SSRSessionInfo, SSRRenderResult, SSRRenderAotOptions, SSRQueryEntry2 as SSRQueryEntry, SSRPrefetchManifest, SSRModule, SSRHandlerOptions, SSRDiscoverResult, SSRAotContext, RenderToStreamOptions, RenderToHTMLStreamOptions, RenderToHTMLOptions, ReconstructedDescriptor, RawHtml, PrefetchSession, PrefetchManifestSnapshot, PrefetchManifestManagerOptions, PrefetchManifestManager, PageOptions, NodeHandlerOptions, MatchedRoute, MatchOptions, HydrationOptions, HeadEntry, HeadCollector, GenerateSSRHtmlOptions, FontFallbackMetrics7 as FontFallbackMetrics, FallbackFontName2 as FallbackFontName, ExtractedRoute, EntityAccessMap, AssetDescriptor, AotTier, AotRouteMapEntry, AotRouteEntry, AotRenderFn, AotManifestSnapshot, AotManifestManagerOptions, AotManifestManager, AotManifest, AotDivergenceEntry, AotDiagnosticsSnapshot, AotDiagnostics, AotDevManifest, AotDevComponentEntry, AotComponentDiagnostic, AotCompiledFile, AotBuildManifest, AotBuildComponentEntry, AotBarrelResult };
|
|
1159
|
+
export { wrapWithHydrationMarkers, toPrefetchSession, streamToString, ssrStorage, ssrRenderToString, ssrRenderSinglePass, ssrRenderAot, ssrDiscoverQueries, setGlobalSSRTimeout, serializeToHtml, safeSerialize, resetSlotCounter, renderToStream, renderToHTMLStream, renderToHTML, renderPage, renderHeadToHtml, renderAssetTags, registerSSRQuery, reconstructDescriptors, rawHtml, matchUrlToPatterns, loadAotManifest, isInSSR, isAotDebugEnabled, inlineCriticalCss, getStreamingRuntimeScript, getSSRUrl, getSSRQueries, getGlobalSSRTimeout, getAccessSetForSSR, generateSSRHtml, generateAotBuildManifest, generateAotBarrel, extractRoutes, extractFontMetrics, evaluateAccessRule, encodeChunk, detectFallbackFont, createTemplateChunk, createSlotPlaceholder, createSessionScript, createSSRHandler, createSSRDataChunk, createSSRAdapter, createPrefetchManifestManager, createNodeHandler, createHoles, createAotManifestManager, createAccessSetScript, collectStreamChunks, clearGlobalSSRTimeout, buildAotRouteMap, __ssr_style_object, __ssr_spread, __esc_attr, __esc, VNode, SessionResolver, SessionData, SerializedAccessRule, SSRSinglePassOptions, SSRSessionInfo, SSRRenderResult, SSRRenderAotOptions, SSRQueryEntry2 as SSRQueryEntry, SSRPrefetchManifest, SSRModule, SSRHandlerOptions, SSRDiscoverResult, SSRAotContext, RenderToStreamOptions, RenderToHTMLStreamOptions, RenderToHTMLOptions, ReconstructedDescriptor, RawHtml, PrefetchSession, PrefetchManifestSnapshot, PrefetchManifestManagerOptions, PrefetchManifestManager, PageOptions, NodeHandlerOptions, MatchedRoute, MatchOptions, HydrationOptions, HeadEntry, HeadCollector, GenerateSSRHtmlOptions, FontFallbackMetrics7 as FontFallbackMetrics, FallbackFontName2 as FallbackFontName, ExtractedRoute, EntityAccessMap, AssetDescriptor, AotTier, AotRouteMapEntry, AotRouteEntry, AotRenderFn, AotManifestSnapshot, AotManifestManagerOptions, AotManifestManager, AotManifest, AotDivergenceEntry, AotDiagnosticsSnapshot, AotDiagnostics, AotDevManifest, AotDevComponentEntry, AotDataResolver, AotComponentDiagnostic, AotCompiledFile, AotBuildManifest, AotBuildComponentEntry, AotBarrelResult };
|
package/dist/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createSSRHandler,
|
|
3
3
|
loadAotManifest
|
|
4
|
-
} from "./shared/chunk-
|
|
4
|
+
} from "./shared/chunk-hjsbx25c.js";
|
|
5
5
|
import {
|
|
6
6
|
createNodeHandler
|
|
7
|
-
} from "./shared/chunk-
|
|
7
|
+
} from "./shared/chunk-9s2dppdh.js";
|
|
8
8
|
import {
|
|
9
9
|
collectStreamChunks,
|
|
10
10
|
compileThemeCached,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
ssrRenderToString,
|
|
35
35
|
streamToString,
|
|
36
36
|
toPrefetchSession
|
|
37
|
-
} from "./shared/chunk-
|
|
37
|
+
} from "./shared/chunk-wq2ke61r.js";
|
|
38
38
|
import {
|
|
39
39
|
clearGlobalSSRTimeout,
|
|
40
40
|
createSSRAdapter,
|
package/dist/node-handler.d.ts
CHANGED
|
@@ -115,6 +115,18 @@ interface AotManifest {
|
|
|
115
115
|
/** Route pattern → AOT entry. */
|
|
116
116
|
routes: Record<string, AotRouteEntry>;
|
|
117
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Resolves custom data for AOT-rendered routes.
|
|
120
|
+
*
|
|
121
|
+
* Called after the entity prefetch pipeline, before the `allKeysResolved` bail check.
|
|
122
|
+
* Only called when there are unresolved query keys remaining.
|
|
123
|
+
*
|
|
124
|
+
* @param pattern - Matched route pattern (e.g., '/products/:id')
|
|
125
|
+
* @param params - Route params (e.g., \{ id: 'abc-123' \})
|
|
126
|
+
* @param unresolvedKeys - Query keys not yet populated by entity prefetch
|
|
127
|
+
* @returns Map of cache key → data, or empty Map to skip
|
|
128
|
+
*/
|
|
129
|
+
type AotDataResolver = (pattern: string, params: Record<string, string>, unresolvedKeys: string[]) => Promise<Map<string, unknown>> | Map<string, unknown>;
|
|
118
130
|
import { AccessSet } from "@vertz/ui/auth";
|
|
119
131
|
interface SessionData {
|
|
120
132
|
user: {
|
|
@@ -217,6 +229,14 @@ interface SSRHandlerOptions {
|
|
|
217
229
|
* Load via `loadAotManifest(serverDir)` at startup.
|
|
218
230
|
*/
|
|
219
231
|
aotManifest?: AotManifest;
|
|
232
|
+
/**
|
|
233
|
+
* Custom data resolver for AOT routes with non-entity data sources.
|
|
234
|
+
*
|
|
235
|
+
* Called after entity prefetch, with only the unresolved query keys.
|
|
236
|
+
* Enables AOT rendering for routes that use custom data layers
|
|
237
|
+
* (JSON files, third-party APIs, custom DB clients).
|
|
238
|
+
*/
|
|
239
|
+
aotDataResolver?: AotDataResolver;
|
|
220
240
|
}
|
|
221
241
|
type NodeHandlerOptions = SSRHandlerOptions;
|
|
222
242
|
declare function createNodeHandler(options: NodeHandlerOptions): (req: IncomingMessage, res: ServerResponse) => void;
|
package/dist/node-handler.js
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
ssrRenderSinglePass,
|
|
12
12
|
ssrStreamNavQueries,
|
|
13
13
|
toPrefetchSession
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-wq2ke61r.js";
|
|
15
15
|
|
|
16
16
|
// src/aot-manifest-loader.ts
|
|
17
17
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -108,7 +108,8 @@ function createSSRHandler(options) {
|
|
|
108
108
|
sessionResolver,
|
|
109
109
|
manifest,
|
|
110
110
|
progressiveHTML,
|
|
111
|
-
aotManifest
|
|
111
|
+
aotManifest,
|
|
112
|
+
aotDataResolver
|
|
112
113
|
} = options;
|
|
113
114
|
const { template, linkHeader, modulepreloadTags, splitResult } = precomputeHandlerState(options);
|
|
114
115
|
return async (request) => {
|
|
@@ -128,7 +129,7 @@ function createSSRHandler(options) {
|
|
|
128
129
|
if (useProgressive) {
|
|
129
130
|
return handleProgressiveHTMLRequest(module, splitResult, pathname + url.search, ssrTimeout, nonce, fallbackMetrics, linkHeader, modulepreloadTags, routeChunkManifest, cacheControl, sessionScript, ssrAuth, manifest);
|
|
130
131
|
}
|
|
131
|
-
return handleHTMLRequest(module, template, pathname + url.search, ssrTimeout, nonce, fallbackMetrics, linkHeader, modulepreloadTags, routeChunkManifest, cacheControl, sessionScript, ssrAuth, manifest, aotManifest);
|
|
132
|
+
return handleHTMLRequest(module, template, pathname + url.search, ssrTimeout, nonce, fallbackMetrics, linkHeader, modulepreloadTags, routeChunkManifest, cacheControl, sessionScript, ssrAuth, manifest, aotManifest, aotDataResolver);
|
|
132
133
|
};
|
|
133
134
|
}
|
|
134
135
|
async function handleNavRequest(module, url, ssrTimeout) {
|
|
@@ -217,7 +218,7 @@ async function handleProgressiveHTMLRequest(module, split, url, ssrTimeout, nonc
|
|
|
217
218
|
});
|
|
218
219
|
}
|
|
219
220
|
}
|
|
220
|
-
async function handleHTMLRequest(module, template, url, ssrTimeout, nonce, fallbackMetrics, linkHeader, staticModulepreloadTags, routeChunkManifest, cacheControl, sessionScript, ssrAuth, manifest, aotManifest) {
|
|
221
|
+
async function handleHTMLRequest(module, template, url, ssrTimeout, nonce, fallbackMetrics, linkHeader, staticModulepreloadTags, routeChunkManifest, cacheControl, sessionScript, ssrAuth, manifest, aotManifest, aotDataResolver) {
|
|
221
222
|
try {
|
|
222
223
|
const prefetchSession = ssrAuth ? toPrefetchSession(ssrAuth) : undefined;
|
|
223
224
|
const result = aotManifest ? await ssrRenderAot(module, url, {
|
|
@@ -226,7 +227,8 @@ async function handleHTMLRequest(module, template, url, ssrTimeout, nonce, fallb
|
|
|
226
227
|
ssrTimeout,
|
|
227
228
|
fallbackMetrics,
|
|
228
229
|
ssrAuth,
|
|
229
|
-
prefetchSession
|
|
230
|
+
prefetchSession,
|
|
231
|
+
aotDataResolver
|
|
230
232
|
}) : await ssrRenderSinglePass(module, url, {
|
|
231
233
|
ssrTimeout,
|
|
232
234
|
fallbackMetrics,
|
|
@@ -1082,6 +1082,19 @@ async function ssrRenderAot(module, url, options) {
|
|
|
1082
1082
|
await prefetchForAot(aotEntry.queryKeys, manifest.routeEntries, match, apiClient, ssrTimeout, queryCache);
|
|
1083
1083
|
}
|
|
1084
1084
|
}
|
|
1085
|
+
if (aotEntry.queryKeys && aotEntry.queryKeys.length > 0 && options.aotDataResolver) {
|
|
1086
|
+
const unresolvedKeys = aotEntry.queryKeys.filter((k) => !queryCache.has(k));
|
|
1087
|
+
if (unresolvedKeys.length > 0) {
|
|
1088
|
+
try {
|
|
1089
|
+
const resolved = await options.aotDataResolver(match.pattern, match.params, unresolvedKeys);
|
|
1090
|
+
for (const [key, value] of resolved) {
|
|
1091
|
+
queryCache.set(key, value);
|
|
1092
|
+
}
|
|
1093
|
+
} catch {
|
|
1094
|
+
return ssrRenderSinglePass(module, normalizedUrl, fallbackOptions);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1085
1098
|
if (aotEntry.queryKeys && aotEntry.queryKeys.length > 0) {
|
|
1086
1099
|
const allKeysResolved = aotEntry.queryKeys.every((k) => queryCache.has(k));
|
|
1087
1100
|
if (!allKeysResolved) {
|
package/dist/ssr/index.d.ts
CHANGED
|
@@ -162,6 +162,18 @@ interface AotManifest {
|
|
|
162
162
|
routes: Record<string, AotRouteEntry>;
|
|
163
163
|
}
|
|
164
164
|
/**
|
|
165
|
+
* Resolves custom data for AOT-rendered routes.
|
|
166
|
+
*
|
|
167
|
+
* Called after the entity prefetch pipeline, before the `allKeysResolved` bail check.
|
|
168
|
+
* Only called when there are unresolved query keys remaining.
|
|
169
|
+
*
|
|
170
|
+
* @param pattern - Matched route pattern (e.g., '/products/:id')
|
|
171
|
+
* @param params - Route params (e.g., \{ id: 'abc-123' \})
|
|
172
|
+
* @param unresolvedKeys - Query keys not yet populated by entity prefetch
|
|
173
|
+
* @returns Map of cache key → data, or empty Map to skip
|
|
174
|
+
*/
|
|
175
|
+
type AotDataResolver = (pattern: string, params: Record<string, string>, unresolvedKeys: string[]) => Promise<Map<string, unknown>> | Map<string, unknown>;
|
|
176
|
+
/**
|
|
165
177
|
* Load AOT manifest and routes module from a server build directory.
|
|
166
178
|
*
|
|
167
179
|
* Returns `null` if either `aot-manifest.json` or `aot-routes.js` is missing,
|
|
@@ -335,6 +347,14 @@ interface SSRHandlerOptions {
|
|
|
335
347
|
* Load via `loadAotManifest(serverDir)` at startup.
|
|
336
348
|
*/
|
|
337
349
|
aotManifest?: AotManifest;
|
|
350
|
+
/**
|
|
351
|
+
* Custom data resolver for AOT routes with non-entity data sources.
|
|
352
|
+
*
|
|
353
|
+
* Called after entity prefetch, with only the unresolved query keys.
|
|
354
|
+
* Enables AOT rendering for routes that use custom data layers
|
|
355
|
+
* (JSON files, third-party APIs, custom DB clients).
|
|
356
|
+
*/
|
|
357
|
+
aotDataResolver?: AotDataResolver;
|
|
338
358
|
}
|
|
339
359
|
declare function createSSRHandler(options: SSRHandlerOptions): (request: Request) => Promise<Response>;
|
|
340
360
|
interface InjectIntoTemplateOptions {
|
|
@@ -357,4 +377,4 @@ interface InjectIntoTemplateOptions {
|
|
|
357
377
|
* injects CSS before </head>, and ssrData before </body>.
|
|
358
378
|
*/
|
|
359
379
|
declare function injectIntoTemplate(options: InjectIntoTemplateOptions): string;
|
|
360
|
-
export { stripScriptsFromStaticHTML, ssrRenderToString, ssrDiscoverQueries, prerenderRoutes, loadAotManifest, injectIntoTemplate, filterPrerenderableRoutes, discoverRoutes, createSSRHandler, collectPrerenderPaths, SSRRenderResult, SSRModule, SSRHandlerOptions, SSRDiscoverResult, PrerenderResult, PrerenderOptions, AotManifest };
|
|
380
|
+
export { stripScriptsFromStaticHTML, ssrRenderToString, ssrDiscoverQueries, prerenderRoutes, loadAotManifest, injectIntoTemplate, filterPrerenderableRoutes, discoverRoutes, createSSRHandler, collectPrerenderPaths, SSRRenderResult, SSRModule, SSRHandlerOptions, SSRDiscoverResult, PrerenderResult, PrerenderOptions, AotManifest, AotDataResolver };
|
package/dist/ssr/index.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createSSRHandler,
|
|
3
3
|
loadAotManifest
|
|
4
|
-
} from "../shared/chunk-
|
|
4
|
+
} from "../shared/chunk-hjsbx25c.js";
|
|
5
5
|
import {
|
|
6
6
|
injectIntoTemplate,
|
|
7
7
|
ssrDiscoverQueries,
|
|
8
8
|
ssrRenderToString
|
|
9
|
-
} from "../shared/chunk-
|
|
9
|
+
} from "../shared/chunk-wq2ke61r.js";
|
|
10
10
|
import"../shared/chunk-ybftdw1r.js";
|
|
11
11
|
// src/prerender.ts
|
|
12
12
|
async function discoverRoutes(module) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vertz/ui-server",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.36",
|
|
4
4
|
"description": "Vertz UI server-side rendering runtime",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -67,9 +67,9 @@
|
|
|
67
67
|
"@ampproject/remapping": "^2.3.0",
|
|
68
68
|
"@capsizecss/unpack": "^4.0.0",
|
|
69
69
|
"@jridgewell/trace-mapping": "^0.3.31",
|
|
70
|
-
"@vertz/core": "^0.2.
|
|
71
|
-
"@vertz/ui": "^0.2.
|
|
72
|
-
"@vertz/ui-compiler": "^0.2.
|
|
70
|
+
"@vertz/core": "^0.2.35",
|
|
71
|
+
"@vertz/ui": "^0.2.35",
|
|
72
|
+
"@vertz/ui-compiler": "^0.2.35",
|
|
73
73
|
"magic-string": "^0.30.0",
|
|
74
74
|
"sharp": "^0.34.5",
|
|
75
75
|
"ts-morph": "^27.0.2"
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"devDependencies": {
|
|
78
78
|
"@happy-dom/global-registrator": "^20.8.3",
|
|
79
79
|
"@playwright/test": "^1.58.2",
|
|
80
|
-
"@vertz/codegen": "^0.2.
|
|
80
|
+
"@vertz/codegen": "^0.2.35",
|
|
81
81
|
"@vertz/ui-auth": "^0.2.19",
|
|
82
82
|
"bun-types": "^1.3.10",
|
|
83
83
|
"bunup": "^0.16.31",
|