@streetui/renderer 1.5.0 → 1.6.1
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/index.cjs +69 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -1
- package/dist/index.d.ts +23 -1
- package/dist/index.js +69 -4
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/index.d.cts
CHANGED
|
@@ -110,8 +110,18 @@ interface RenderContext {
|
|
|
110
110
|
* DevTools/diagnostics stay off the production runtime path.
|
|
111
111
|
*/
|
|
112
112
|
readonly hydrationDiagnostics?: HydrationDiagnosticSink;
|
|
113
|
+
/**
|
|
114
|
+
* Optional SSR-only static-subtree plan (v1.7). Maps a maximal
|
|
115
|
+
* static-subtree root GraphNode.id → its precomputed, verbatim HTML string.
|
|
116
|
+
* Present only on the server render path when a plan has been built; on the
|
|
117
|
+
* browser mount path it is always `undefined`, so the client hot path is
|
|
118
|
+
* unaffected (a single `=== undefined` check short-circuits). When a mounted
|
|
119
|
+
* node's id is in this map, the renderer emits the precomputed HTML via
|
|
120
|
+
* `dom.createRawHTML` instead of recursively constructing the subtree.
|
|
121
|
+
*/
|
|
122
|
+
readonly staticHTML?: ReadonlyMap<string, string>;
|
|
113
123
|
}
|
|
114
|
-
declare function createRenderContext(dom: DOMAdapter, graph: ApplicationGraph, container: Element, hydrationDiagnostics?: HydrationDiagnosticSink): RenderContext;
|
|
124
|
+
declare function createRenderContext(dom: DOMAdapter, graph: ApplicationGraph, container: Element, hydrationDiagnostics?: HydrationDiagnosticSink, staticHTML?: ReadonlyMap<string, string>): RenderContext;
|
|
115
125
|
|
|
116
126
|
/**
|
|
117
127
|
* Attribute and property application helpers.
|
|
@@ -393,6 +403,18 @@ interface RenderToStringOptions {
|
|
|
393
403
|
* `ServerDOMAdapter` per call so concurrent renders never share state.
|
|
394
404
|
*/
|
|
395
405
|
readonly domAdapter?: ServerDOMAdapter;
|
|
406
|
+
/**
|
|
407
|
+
* @internal — testing/benchmark knob for the v1.7 static SSR plan.
|
|
408
|
+
*
|
|
409
|
+
* `undefined` (default): use the per-app cached plan (build once, reuse).
|
|
410
|
+
* `null`: disable the plan entirely — the exact v1.6 runtime mount path, used
|
|
411
|
+
* by the byte-identity gate and A/B benchmark as the "legacy" baseline.
|
|
412
|
+
* a map: use this explicit plan.
|
|
413
|
+
*
|
|
414
|
+
* Not part of the supported public API; output is byte-identical regardless
|
|
415
|
+
* of this value (§8).
|
|
416
|
+
*/
|
|
417
|
+
readonly staticPlan?: ReadonlyMap<string, string> | null;
|
|
396
418
|
}
|
|
397
419
|
/**
|
|
398
420
|
* Render a compiled StreetUI application to an HTML string.
|
package/dist/index.d.ts
CHANGED
|
@@ -110,8 +110,18 @@ interface RenderContext {
|
|
|
110
110
|
* DevTools/diagnostics stay off the production runtime path.
|
|
111
111
|
*/
|
|
112
112
|
readonly hydrationDiagnostics?: HydrationDiagnosticSink;
|
|
113
|
+
/**
|
|
114
|
+
* Optional SSR-only static-subtree plan (v1.7). Maps a maximal
|
|
115
|
+
* static-subtree root GraphNode.id → its precomputed, verbatim HTML string.
|
|
116
|
+
* Present only on the server render path when a plan has been built; on the
|
|
117
|
+
* browser mount path it is always `undefined`, so the client hot path is
|
|
118
|
+
* unaffected (a single `=== undefined` check short-circuits). When a mounted
|
|
119
|
+
* node's id is in this map, the renderer emits the precomputed HTML via
|
|
120
|
+
* `dom.createRawHTML` instead of recursively constructing the subtree.
|
|
121
|
+
*/
|
|
122
|
+
readonly staticHTML?: ReadonlyMap<string, string>;
|
|
113
123
|
}
|
|
114
|
-
declare function createRenderContext(dom: DOMAdapter, graph: ApplicationGraph, container: Element, hydrationDiagnostics?: HydrationDiagnosticSink): RenderContext;
|
|
124
|
+
declare function createRenderContext(dom: DOMAdapter, graph: ApplicationGraph, container: Element, hydrationDiagnostics?: HydrationDiagnosticSink, staticHTML?: ReadonlyMap<string, string>): RenderContext;
|
|
115
125
|
|
|
116
126
|
/**
|
|
117
127
|
* Attribute and property application helpers.
|
|
@@ -393,6 +403,18 @@ interface RenderToStringOptions {
|
|
|
393
403
|
* `ServerDOMAdapter` per call so concurrent renders never share state.
|
|
394
404
|
*/
|
|
395
405
|
readonly domAdapter?: ServerDOMAdapter;
|
|
406
|
+
/**
|
|
407
|
+
* @internal — testing/benchmark knob for the v1.7 static SSR plan.
|
|
408
|
+
*
|
|
409
|
+
* `undefined` (default): use the per-app cached plan (build once, reuse).
|
|
410
|
+
* `null`: disable the plan entirely — the exact v1.6 runtime mount path, used
|
|
411
|
+
* by the byte-identity gate and A/B benchmark as the "legacy" baseline.
|
|
412
|
+
* a map: use this explicit plan.
|
|
413
|
+
*
|
|
414
|
+
* Not part of the supported public API; output is byte-identical regardless
|
|
415
|
+
* of this value (§8).
|
|
416
|
+
*/
|
|
417
|
+
readonly staticPlan?: ReadonlyMap<string, string> | null;
|
|
396
418
|
}
|
|
397
419
|
/**
|
|
398
420
|
* Render a compiled StreetUI application to an HTML string.
|
package/dist/index.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
// src/render-context.ts
|
|
2
|
-
function createRenderContext(dom, graph, container, hydrationDiagnostics) {
|
|
2
|
+
function createRenderContext(dom, graph, container, hydrationDiagnostics, staticHTML) {
|
|
3
3
|
return {
|
|
4
4
|
dom,
|
|
5
5
|
graph,
|
|
6
6
|
instances: /* @__PURE__ */ new Map(),
|
|
7
7
|
container,
|
|
8
|
-
...hydrationDiagnostics !== void 0 ? { hydrationDiagnostics } : {}
|
|
8
|
+
...hydrationDiagnostics !== void 0 ? { hydrationDiagnostics } : {},
|
|
9
|
+
...staticHTML !== void 0 ? { staticHTML } : {}
|
|
9
10
|
};
|
|
10
11
|
}
|
|
11
12
|
|
|
@@ -434,6 +435,17 @@ function mountGraph(ctx) {
|
|
|
434
435
|
}
|
|
435
436
|
function mountNode(ctx, graphNode, parentDom) {
|
|
436
437
|
const { dom, graph } = ctx;
|
|
438
|
+
const staticHTML = ctx.staticHTML;
|
|
439
|
+
if (staticHTML !== void 0 && dom.createRawHTML !== void 0) {
|
|
440
|
+
const precomputed = staticHTML.get(graphNode.id);
|
|
441
|
+
if (precomputed !== void 0) {
|
|
442
|
+
const raw = dom.createRawHTML(precomputed);
|
|
443
|
+
dom.appendChild(parentDom, raw);
|
|
444
|
+
const instance2 = new NodeInstance(graphNode, raw);
|
|
445
|
+
ctx.instances.set(graphNode.id, instance2);
|
|
446
|
+
return instance2;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
437
449
|
if (graphNode.type === "application") {
|
|
438
450
|
const instance2 = new NodeInstance(graphNode, parentDom);
|
|
439
451
|
ctx.instances.set(graphNode.id, instance2);
|
|
@@ -1025,11 +1037,64 @@ function readState(dom, root) {
|
|
|
1025
1037
|
}
|
|
1026
1038
|
|
|
1027
1039
|
// src/ssr.ts
|
|
1040
|
+
import { ServerDOMAdapter as ServerDOMAdapter2 } from "@streetui/dom";
|
|
1041
|
+
|
|
1042
|
+
// src/static-ssr-plan.ts
|
|
1043
|
+
import { analyzeGraph } from "@streetui/compiler/diagnostics";
|
|
1028
1044
|
import { ServerDOMAdapter } from "@streetui/dom";
|
|
1045
|
+
function collectMaximalStaticRoots(graph) {
|
|
1046
|
+
const analysis = analyzeGraph(graph);
|
|
1047
|
+
const roots = [];
|
|
1048
|
+
const walk = (node) => {
|
|
1049
|
+
if (node.type !== "application") {
|
|
1050
|
+
const a = analysis.nodes.get(node.id);
|
|
1051
|
+
if (a !== void 0 && a.isStaticSubtree) {
|
|
1052
|
+
roots.push(node);
|
|
1053
|
+
return;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
for (const child of node.children) walk(child);
|
|
1057
|
+
};
|
|
1058
|
+
walk(graph.root);
|
|
1059
|
+
return roots;
|
|
1060
|
+
}
|
|
1061
|
+
function serializeStaticSubtree(dom, graph, root) {
|
|
1062
|
+
const container = dom.createElement("div");
|
|
1063
|
+
const ctx = createRenderContext(dom, graph, container);
|
|
1064
|
+
const instance = mountNode(ctx, root, container);
|
|
1065
|
+
const html = dom.serializeInner(container);
|
|
1066
|
+
instance.dispose();
|
|
1067
|
+
ctx.instances.clear();
|
|
1068
|
+
return html;
|
|
1069
|
+
}
|
|
1070
|
+
function buildStaticSSRPlan(compiled) {
|
|
1071
|
+
const graph = compiled.graph;
|
|
1072
|
+
const roots = collectMaximalStaticRoots(graph);
|
|
1073
|
+
const plan = /* @__PURE__ */ new Map();
|
|
1074
|
+
if (roots.length === 0) return plan;
|
|
1075
|
+
const dom = new ServerDOMAdapter();
|
|
1076
|
+
for (const root of roots) {
|
|
1077
|
+
plan.set(root.id, serializeStaticSubtree(dom, graph, root));
|
|
1078
|
+
}
|
|
1079
|
+
return plan;
|
|
1080
|
+
}
|
|
1081
|
+
var PLAN_CACHE = /* @__PURE__ */ new WeakMap();
|
|
1082
|
+
function getStaticSSRPlan(compiled) {
|
|
1083
|
+
let plan = PLAN_CACHE.get(compiled);
|
|
1084
|
+
if (plan === void 0) {
|
|
1085
|
+
plan = buildStaticSSRPlan(compiled);
|
|
1086
|
+
PLAN_CACHE.set(compiled, plan);
|
|
1087
|
+
}
|
|
1088
|
+
return plan;
|
|
1089
|
+
}
|
|
1090
|
+
|
|
1091
|
+
// src/ssr.ts
|
|
1029
1092
|
function renderToString(compiled, options = {}) {
|
|
1030
|
-
const dom = options.domAdapter ?? new
|
|
1093
|
+
const dom = options.domAdapter ?? new ServerDOMAdapter2();
|
|
1094
|
+
const plan = options.staticPlan === null ? void 0 : options.staticPlan ?? getStaticSSRPlan(compiled);
|
|
1095
|
+
const staticHTML = plan !== void 0 && plan.size > 0 ? plan : void 0;
|
|
1031
1096
|
const container = dom.createElement("div");
|
|
1032
|
-
const ctx = createRenderContext(dom, compiled.graph, container);
|
|
1097
|
+
const ctx = createRenderContext(dom, compiled.graph, container, void 0, staticHTML);
|
|
1033
1098
|
const rootInstance = mountGraph(ctx);
|
|
1034
1099
|
const html = dom.serializeInner(container);
|
|
1035
1100
|
rootInstance.dispose();
|