@streetui/compiler 1.0.0 → 1.2.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.
@@ -0,0 +1,142 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/diagnostics.ts
21
+ var diagnostics_exports = {};
22
+ __export(diagnostics_exports, {
23
+ analyzeGraph: () => analyzeGraph,
24
+ formatInspection: () => formatInspection,
25
+ inspectCompilation: () => inspectCompilation
26
+ });
27
+ module.exports = __toCommonJS(diagnostics_exports);
28
+
29
+ // src/analysis/analyze.ts
30
+ var TEXT_PROP_KEYS = /* @__PURE__ */ new Set(["text", "label", "value"]);
31
+ function analyzeGraph(graph) {
32
+ const nodes = /* @__PURE__ */ new Map();
33
+ const summary = {
34
+ totalNodes: 0,
35
+ staticNodes: 0,
36
+ staticSubtrees: 0,
37
+ dynamicTextNodes: 0,
38
+ dynamicAttrNodes: 0,
39
+ eventNodes: 0,
40
+ lists: 0,
41
+ conditionals: 0
42
+ };
43
+ const visit = (node) => {
44
+ let allChildrenStatic = true;
45
+ for (const child of node.children) {
46
+ const childSubtreeStatic = visit(child);
47
+ if (!childSubtreeStatic) allChildrenStatic = false;
48
+ }
49
+ let hasDynamicText = false;
50
+ let hasDynamicAttr = false;
51
+ for (const ref of node.stateRefs) {
52
+ if (TEXT_PROP_KEYS.has(ref.propKey)) hasDynamicText = true;
53
+ else hasDynamicAttr = true;
54
+ }
55
+ const hasEvents = node.events.length > 0;
56
+ const isList = node.type === "reactive-list";
57
+ const isConditional = node.type === "conditional";
58
+ const isStatic = node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional;
59
+ const isStaticSubtree = isStatic && allChildrenStatic;
60
+ nodes.set(node.id, {
61
+ isStatic,
62
+ isStaticSubtree,
63
+ hasDynamicText,
64
+ hasDynamicAttr,
65
+ hasEvents,
66
+ isList,
67
+ isConditional
68
+ });
69
+ summary.totalNodes += 1;
70
+ if (isStatic) summary.staticNodes += 1;
71
+ if (isStaticSubtree) summary.staticSubtrees += 1;
72
+ if (hasDynamicText) summary.dynamicTextNodes += 1;
73
+ if (hasDynamicAttr) summary.dynamicAttrNodes += 1;
74
+ if (hasEvents) summary.eventNodes += 1;
75
+ if (isList) summary.lists += 1;
76
+ if (isConditional) summary.conditionals += 1;
77
+ return isStaticSubtree;
78
+ };
79
+ visit(graph.root);
80
+ return { nodes, summary };
81
+ }
82
+
83
+ // src/analysis/inspect.ts
84
+ function inspectCompilation(graph) {
85
+ const analysis = analyzeGraph(graph);
86
+ const nodes = [];
87
+ const walk = (node, depth) => {
88
+ const a = analysis.nodes.get(node.id);
89
+ if (a !== void 0) {
90
+ const classification = a.isStaticSubtree ? "static-subtree-root" : a.isStatic ? "static" : "dynamic";
91
+ nodes.push({
92
+ id: node.id,
93
+ type: node.type,
94
+ depth,
95
+ classification,
96
+ dynamicText: a.hasDynamicText,
97
+ dynamicAttrs: a.hasDynamicAttr,
98
+ events: node.events.map((e) => e.type),
99
+ boundProps: node.stateRefs.map((r) => r.propKey),
100
+ isList: a.isList,
101
+ isConditional: a.isConditional,
102
+ hydration: a.isStaticSubtree ? "adopt-static" : "verify-dynamic"
103
+ });
104
+ }
105
+ for (const child of node.children) walk(child, depth + 1);
106
+ };
107
+ walk(graph.root, 0);
108
+ const staticRatio = analysis.summary.totalNodes === 0 ? 0 : analysis.summary.staticNodes / analysis.summary.totalNodes;
109
+ return {
110
+ name: graph.name,
111
+ version: graph.version,
112
+ summary: { ...analysis.summary, staticRatio: +staticRatio.toFixed(4) },
113
+ nodes
114
+ };
115
+ }
116
+ function formatInspection(inspection) {
117
+ const s = inspection.summary;
118
+ const lines = [];
119
+ lines.push(`StreetUI compiler inspection \u2014 ${inspection.name} v${inspection.version}`);
120
+ lines.push(
121
+ ` nodes=${s.totalNodes} static=${s.staticNodes} staticSubtrees=${s.staticSubtrees} dynamicText=${s.dynamicTextNodes} dynamicAttrs=${s.dynamicAttrNodes} events=${s.eventNodes} lists=${s.lists} conditionals=${s.conditionals} staticRatio=${(s.staticRatio * 100).toFixed(1)}%`
122
+ );
123
+ for (const n of inspection.nodes) {
124
+ const flags = [];
125
+ if (n.dynamicText) flags.push("text");
126
+ if (n.dynamicAttrs) flags.push("attr:" + n.boundProps.join(","));
127
+ if (n.events.length > 0) flags.push("on:" + n.events.join(","));
128
+ if (n.isList) flags.push("list");
129
+ if (n.isConditional) flags.push("cond");
130
+ lines.push(
131
+ ` ${" ".repeat(n.depth)}${n.type}#${n.id} [${n.classification}]` + (flags.length > 0 ? ` {${flags.join(" ")}}` : "")
132
+ );
133
+ }
134
+ return lines.join("\n");
135
+ }
136
+ // Annotate the CommonJS export names for ESM import in node:
137
+ 0 && (module.exports = {
138
+ analyzeGraph,
139
+ formatInspection,
140
+ inspectCompilation
141
+ });
142
+ //# sourceMappingURL=diagnostics.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/diagnostics.ts","../src/analysis/analyze.ts","../src/analysis/inspect.ts"],"sourcesContent":["/**\n * `@streetui/compiler/diagnostics` — opt-in, build/dev-time compiler diagnostics.\n *\n * The static-graph analysis (`analyzeGraph`) and the human/machine-readable\n * compiler-inspection report (`inspectCompilation` / `formatInspection`) live on\n * this dedicated subpath — deliberately NOT re-exported from the compiler's main\n * barrel — so they never enter the runtime bundle (`streetui`'s `dist/index.js`).\n * They are reached only via the diagnostic subpath (`streetui/testing`), keeping\n * the shipped runtime lean (spec §6/§7/§14).\n */\nexport * from './analysis/analyze.js';\nexport * from './analysis/inspect.js';\n","/**\n * Static graph analysis (v1.2, spec §3/§12/§14).\n *\n * A single post-order walk over the Semantic Application Graph that classifies\n * every node as static (no bound signals, no events, not a reactive\n * region) or dynamic, and rolls that up into whole-static-subtree flags. This\n * is COMPILE-TIME metadata only — it introduces no virtual DOM, no second tree\n * and no runtime reactive system. It is consumed by:\n * - the hydration path, to skip per-node attribute/text re-verification on\n * provably-static subtrees (§12), and\n * - the diagnostic compiler-inspection report (§14).\n *\n * The renderer's initial-mount fast path does not need this map: it already\n * skips reactive wiring per node via cheap `events.length`/`stateRefs.length`\n * guards. Keeping the analysis out of the mount hot path avoids adding lookup\n * cost (and keeps the shipped runtime lean).\n */\n\nimport type { NodeId } from '@streetui/core';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\n\n/** Prop keys whose bound signal drives text content rather than an attribute. */\nconst TEXT_PROP_KEYS: ReadonlySet<string> = new Set(['text', 'label', 'value']);\n\nexport interface NodeAnalysis {\n /** No bound signals, no events, and not a reactive-list/conditional region. */\n readonly isStatic: boolean;\n /** This node is static AND every descendant is a static subtree. */\n readonly isStaticSubtree: boolean;\n /** A signal is bound to this node's text/label/value content. */\n readonly hasDynamicText: boolean;\n /** A signal is bound to a non-content prop (a reactive attribute). */\n readonly hasDynamicAttr: boolean;\n /** This node wires one or more DOM event handlers. */\n readonly hasEvents: boolean;\n /** This node is a keyed reactive list. */\n readonly isList: boolean;\n /** This node is a conditional (0..1 branch) region. */\n readonly isConditional: boolean;\n}\n\nexport interface GraphAnalysisSummary {\n readonly totalNodes: number;\n readonly staticNodes: number;\n readonly staticSubtrees: number;\n readonly dynamicTextNodes: number;\n readonly dynamicAttrNodes: number;\n readonly eventNodes: number;\n readonly lists: number;\n readonly conditionals: number;\n}\n\nexport interface GraphAnalysis {\n readonly nodes: ReadonlyMap<NodeId, NodeAnalysis>;\n readonly summary: GraphAnalysisSummary;\n}\n\n/**\n * Analyze a fully-built graph. O(n) single post-order pass; allocates one small\n * record per node. Safe to skip entirely when neither hydration nor diagnostics\n * need it.\n */\nexport function analyzeGraph(graph: ApplicationGraph): GraphAnalysis {\n const nodes = new Map<NodeId, NodeAnalysis>();\n const summary = {\n totalNodes: 0, staticNodes: 0, staticSubtrees: 0, dynamicTextNodes: 0,\n dynamicAttrNodes: 0, eventNodes: 0, lists: 0, conditionals: 0,\n };\n\n const visit = (node: GraphNode): boolean => {\n // Post-order: children first so subtree rollup is exact.\n let allChildrenStatic = true;\n for (const child of node.children) {\n const childSubtreeStatic = visit(child);\n if (!childSubtreeStatic) allChildrenStatic = false;\n }\n\n let hasDynamicText = false;\n let hasDynamicAttr = false;\n for (const ref of node.stateRefs) {\n if (TEXT_PROP_KEYS.has(ref.propKey)) hasDynamicText = true;\n else hasDynamicAttr = true;\n }\n const hasEvents = node.events.length > 0;\n const isList = node.type === 'reactive-list';\n const isConditional = node.type === 'conditional';\n const isStatic =\n node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional;\n const isStaticSubtree = isStatic && allChildrenStatic;\n\n nodes.set(node.id, {\n isStatic, isStaticSubtree, hasDynamicText, hasDynamicAttr,\n hasEvents, isList, isConditional,\n });\n\n summary.totalNodes += 1;\n if (isStatic) summary.staticNodes += 1;\n if (isStaticSubtree) summary.staticSubtrees += 1;\n if (hasDynamicText) summary.dynamicTextNodes += 1;\n if (hasDynamicAttr) summary.dynamicAttrNodes += 1;\n if (hasEvents) summary.eventNodes += 1;\n if (isList) summary.lists += 1;\n if (isConditional) summary.conditionals += 1;\n\n return isStaticSubtree;\n };\n\n visit(graph.root);\n return { nodes, summary };\n}\n","/**\n * Diagnostic compiler-inspection mode (v1.2, spec §14).\n *\n * Produces a machine-readable (and optionally text-formatted) description of\n * what the compiler understands about an application: which nodes are static\n * vs dynamic, which carry dynamic text or attributes, which wire events, and\n * which are conditional regions or keyed lists — plus the hydration metadata\n * derived from that classification.\n *\n * This is a DIAGNOSTIC tool. It is not part of the runtime, is not consulted\n * during mount, and is tree-shakeable out of any app that never calls it.\n */\n\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport { analyzeGraph, type GraphAnalysisSummary } from './analyze.js';\n\nexport interface InspectedCompilationNode {\n readonly id: string;\n readonly type: string;\n readonly depth: number;\n readonly classification: 'static' | 'static-subtree-root' | 'dynamic';\n readonly dynamicText: boolean;\n readonly dynamicAttrs: boolean;\n readonly events: readonly string[];\n readonly boundProps: readonly string[];\n readonly isList: boolean;\n readonly isConditional: boolean;\n /** Hydration hint: how the hydration path should treat this node. */\n readonly hydration: 'adopt-static' | 'verify-dynamic';\n}\n\nexport interface CompilerInspection {\n readonly name: string;\n readonly version: string;\n readonly summary: GraphAnalysisSummary & {\n /** Fraction of nodes provably static (0..1). */\n readonly staticRatio: number;\n };\n readonly nodes: readonly InspectedCompilationNode[];\n}\n\n/**\n * Inspect a compiled/built graph and return a structured diagnostic report.\n * Purely observational — never mutates the graph.\n */\nexport function inspectCompilation(graph: ApplicationGraph): CompilerInspection {\n const analysis = analyzeGraph(graph);\n const nodes: InspectedCompilationNode[] = [];\n\n const walk = (node: GraphNode, depth: number): void => {\n const a = analysis.nodes.get(node.id);\n if (a !== undefined) {\n const classification: InspectedCompilationNode['classification'] = a.isStaticSubtree\n ? 'static-subtree-root'\n : a.isStatic\n ? 'static'\n : 'dynamic';\n nodes.push({\n id: node.id,\n type: node.type,\n depth,\n classification,\n dynamicText: a.hasDynamicText,\n dynamicAttrs: a.hasDynamicAttr,\n events: node.events.map((e) => e.type),\n boundProps: node.stateRefs.map((r) => r.propKey),\n isList: a.isList,\n isConditional: a.isConditional,\n hydration: a.isStaticSubtree ? 'adopt-static' : 'verify-dynamic',\n });\n }\n for (const child of node.children) walk(child, depth + 1);\n };\n walk(graph.root, 0);\n\n const staticRatio =\n analysis.summary.totalNodes === 0\n ? 0\n : analysis.summary.staticNodes / analysis.summary.totalNodes;\n\n return {\n name: graph.name,\n version: graph.version,\n summary: { ...analysis.summary, staticRatio: +staticRatio.toFixed(4) },\n nodes,\n };\n}\n\n/** Render an inspection as a compact human-readable text report. */\nexport function formatInspection(inspection: CompilerInspection): string {\n const s = inspection.summary;\n const lines: string[] = [];\n lines.push(`StreetUI compiler inspection — ${inspection.name} v${inspection.version}`);\n lines.push(\n ` nodes=${s.totalNodes} static=${s.staticNodes} ` +\n `staticSubtrees=${s.staticSubtrees} dynamicText=${s.dynamicTextNodes} ` +\n `dynamicAttrs=${s.dynamicAttrNodes} events=${s.eventNodes} ` +\n `lists=${s.lists} conditionals=${s.conditionals} ` +\n `staticRatio=${(s.staticRatio * 100).toFixed(1)}%`,\n );\n for (const n of inspection.nodes) {\n const flags: string[] = [];\n if (n.dynamicText) flags.push('text');\n if (n.dynamicAttrs) flags.push('attr:' + n.boundProps.join(','));\n if (n.events.length > 0) flags.push('on:' + n.events.join(','));\n if (n.isList) flags.push('list');\n if (n.isConditional) flags.push('cond');\n lines.push(\n ` ${' '.repeat(n.depth)}${n.type}#${n.id} [${n.classification}]` +\n (flags.length > 0 ? ` {${flags.join(' ')}}` : ''),\n );\n }\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,103 @@
1
+ import { NodeId } from '@streetui/core';
2
+ import { ApplicationGraph } from '@streetui/graph';
3
+
4
+ /**
5
+ * Static graph analysis (v1.2, spec §3/§12/§14).
6
+ *
7
+ * A single post-order walk over the Semantic Application Graph that classifies
8
+ * every node as static (no bound signals, no events, not a reactive
9
+ * region) or dynamic, and rolls that up into whole-static-subtree flags. This
10
+ * is COMPILE-TIME metadata only — it introduces no virtual DOM, no second tree
11
+ * and no runtime reactive system. It is consumed by:
12
+ * - the hydration path, to skip per-node attribute/text re-verification on
13
+ * provably-static subtrees (§12), and
14
+ * - the diagnostic compiler-inspection report (§14).
15
+ *
16
+ * The renderer's initial-mount fast path does not need this map: it already
17
+ * skips reactive wiring per node via cheap `events.length`/`stateRefs.length`
18
+ * guards. Keeping the analysis out of the mount hot path avoids adding lookup
19
+ * cost (and keeps the shipped runtime lean).
20
+ */
21
+
22
+ interface NodeAnalysis {
23
+ /** No bound signals, no events, and not a reactive-list/conditional region. */
24
+ readonly isStatic: boolean;
25
+ /** This node is static AND every descendant is a static subtree. */
26
+ readonly isStaticSubtree: boolean;
27
+ /** A signal is bound to this node's text/label/value content. */
28
+ readonly hasDynamicText: boolean;
29
+ /** A signal is bound to a non-content prop (a reactive attribute). */
30
+ readonly hasDynamicAttr: boolean;
31
+ /** This node wires one or more DOM event handlers. */
32
+ readonly hasEvents: boolean;
33
+ /** This node is a keyed reactive list. */
34
+ readonly isList: boolean;
35
+ /** This node is a conditional (0..1 branch) region. */
36
+ readonly isConditional: boolean;
37
+ }
38
+ interface GraphAnalysisSummary {
39
+ readonly totalNodes: number;
40
+ readonly staticNodes: number;
41
+ readonly staticSubtrees: number;
42
+ readonly dynamicTextNodes: number;
43
+ readonly dynamicAttrNodes: number;
44
+ readonly eventNodes: number;
45
+ readonly lists: number;
46
+ readonly conditionals: number;
47
+ }
48
+ interface GraphAnalysis {
49
+ readonly nodes: ReadonlyMap<NodeId, NodeAnalysis>;
50
+ readonly summary: GraphAnalysisSummary;
51
+ }
52
+ /**
53
+ * Analyze a fully-built graph. O(n) single post-order pass; allocates one small
54
+ * record per node. Safe to skip entirely when neither hydration nor diagnostics
55
+ * need it.
56
+ */
57
+ declare function analyzeGraph(graph: ApplicationGraph): GraphAnalysis;
58
+
59
+ /**
60
+ * Diagnostic compiler-inspection mode (v1.2, spec §14).
61
+ *
62
+ * Produces a machine-readable (and optionally text-formatted) description of
63
+ * what the compiler understands about an application: which nodes are static
64
+ * vs dynamic, which carry dynamic text or attributes, which wire events, and
65
+ * which are conditional regions or keyed lists — plus the hydration metadata
66
+ * derived from that classification.
67
+ *
68
+ * This is a DIAGNOSTIC tool. It is not part of the runtime, is not consulted
69
+ * during mount, and is tree-shakeable out of any app that never calls it.
70
+ */
71
+
72
+ interface InspectedCompilationNode {
73
+ readonly id: string;
74
+ readonly type: string;
75
+ readonly depth: number;
76
+ readonly classification: 'static' | 'static-subtree-root' | 'dynamic';
77
+ readonly dynamicText: boolean;
78
+ readonly dynamicAttrs: boolean;
79
+ readonly events: readonly string[];
80
+ readonly boundProps: readonly string[];
81
+ readonly isList: boolean;
82
+ readonly isConditional: boolean;
83
+ /** Hydration hint: how the hydration path should treat this node. */
84
+ readonly hydration: 'adopt-static' | 'verify-dynamic';
85
+ }
86
+ interface CompilerInspection {
87
+ readonly name: string;
88
+ readonly version: string;
89
+ readonly summary: GraphAnalysisSummary & {
90
+ /** Fraction of nodes provably static (0..1). */
91
+ readonly staticRatio: number;
92
+ };
93
+ readonly nodes: readonly InspectedCompilationNode[];
94
+ }
95
+ /**
96
+ * Inspect a compiled/built graph and return a structured diagnostic report.
97
+ * Purely observational — never mutates the graph.
98
+ */
99
+ declare function inspectCompilation(graph: ApplicationGraph): CompilerInspection;
100
+ /** Render an inspection as a compact human-readable text report. */
101
+ declare function formatInspection(inspection: CompilerInspection): string;
102
+
103
+ export { type CompilerInspection, type GraphAnalysis, type GraphAnalysisSummary, type InspectedCompilationNode, type NodeAnalysis, analyzeGraph, formatInspection, inspectCompilation };
@@ -0,0 +1,103 @@
1
+ import { NodeId } from '@streetui/core';
2
+ import { ApplicationGraph } from '@streetui/graph';
3
+
4
+ /**
5
+ * Static graph analysis (v1.2, spec §3/§12/§14).
6
+ *
7
+ * A single post-order walk over the Semantic Application Graph that classifies
8
+ * every node as static (no bound signals, no events, not a reactive
9
+ * region) or dynamic, and rolls that up into whole-static-subtree flags. This
10
+ * is COMPILE-TIME metadata only — it introduces no virtual DOM, no second tree
11
+ * and no runtime reactive system. It is consumed by:
12
+ * - the hydration path, to skip per-node attribute/text re-verification on
13
+ * provably-static subtrees (§12), and
14
+ * - the diagnostic compiler-inspection report (§14).
15
+ *
16
+ * The renderer's initial-mount fast path does not need this map: it already
17
+ * skips reactive wiring per node via cheap `events.length`/`stateRefs.length`
18
+ * guards. Keeping the analysis out of the mount hot path avoids adding lookup
19
+ * cost (and keeps the shipped runtime lean).
20
+ */
21
+
22
+ interface NodeAnalysis {
23
+ /** No bound signals, no events, and not a reactive-list/conditional region. */
24
+ readonly isStatic: boolean;
25
+ /** This node is static AND every descendant is a static subtree. */
26
+ readonly isStaticSubtree: boolean;
27
+ /** A signal is bound to this node's text/label/value content. */
28
+ readonly hasDynamicText: boolean;
29
+ /** A signal is bound to a non-content prop (a reactive attribute). */
30
+ readonly hasDynamicAttr: boolean;
31
+ /** This node wires one or more DOM event handlers. */
32
+ readonly hasEvents: boolean;
33
+ /** This node is a keyed reactive list. */
34
+ readonly isList: boolean;
35
+ /** This node is a conditional (0..1 branch) region. */
36
+ readonly isConditional: boolean;
37
+ }
38
+ interface GraphAnalysisSummary {
39
+ readonly totalNodes: number;
40
+ readonly staticNodes: number;
41
+ readonly staticSubtrees: number;
42
+ readonly dynamicTextNodes: number;
43
+ readonly dynamicAttrNodes: number;
44
+ readonly eventNodes: number;
45
+ readonly lists: number;
46
+ readonly conditionals: number;
47
+ }
48
+ interface GraphAnalysis {
49
+ readonly nodes: ReadonlyMap<NodeId, NodeAnalysis>;
50
+ readonly summary: GraphAnalysisSummary;
51
+ }
52
+ /**
53
+ * Analyze a fully-built graph. O(n) single post-order pass; allocates one small
54
+ * record per node. Safe to skip entirely when neither hydration nor diagnostics
55
+ * need it.
56
+ */
57
+ declare function analyzeGraph(graph: ApplicationGraph): GraphAnalysis;
58
+
59
+ /**
60
+ * Diagnostic compiler-inspection mode (v1.2, spec §14).
61
+ *
62
+ * Produces a machine-readable (and optionally text-formatted) description of
63
+ * what the compiler understands about an application: which nodes are static
64
+ * vs dynamic, which carry dynamic text or attributes, which wire events, and
65
+ * which are conditional regions or keyed lists — plus the hydration metadata
66
+ * derived from that classification.
67
+ *
68
+ * This is a DIAGNOSTIC tool. It is not part of the runtime, is not consulted
69
+ * during mount, and is tree-shakeable out of any app that never calls it.
70
+ */
71
+
72
+ interface InspectedCompilationNode {
73
+ readonly id: string;
74
+ readonly type: string;
75
+ readonly depth: number;
76
+ readonly classification: 'static' | 'static-subtree-root' | 'dynamic';
77
+ readonly dynamicText: boolean;
78
+ readonly dynamicAttrs: boolean;
79
+ readonly events: readonly string[];
80
+ readonly boundProps: readonly string[];
81
+ readonly isList: boolean;
82
+ readonly isConditional: boolean;
83
+ /** Hydration hint: how the hydration path should treat this node. */
84
+ readonly hydration: 'adopt-static' | 'verify-dynamic';
85
+ }
86
+ interface CompilerInspection {
87
+ readonly name: string;
88
+ readonly version: string;
89
+ readonly summary: GraphAnalysisSummary & {
90
+ /** Fraction of nodes provably static (0..1). */
91
+ readonly staticRatio: number;
92
+ };
93
+ readonly nodes: readonly InspectedCompilationNode[];
94
+ }
95
+ /**
96
+ * Inspect a compiled/built graph and return a structured diagnostic report.
97
+ * Purely observational — never mutates the graph.
98
+ */
99
+ declare function inspectCompilation(graph: ApplicationGraph): CompilerInspection;
100
+ /** Render an inspection as a compact human-readable text report. */
101
+ declare function formatInspection(inspection: CompilerInspection): string;
102
+
103
+ export { type CompilerInspection, type GraphAnalysis, type GraphAnalysisSummary, type InspectedCompilationNode, type NodeAnalysis, analyzeGraph, formatInspection, inspectCompilation };
@@ -0,0 +1,113 @@
1
+ // src/analysis/analyze.ts
2
+ var TEXT_PROP_KEYS = /* @__PURE__ */ new Set(["text", "label", "value"]);
3
+ function analyzeGraph(graph) {
4
+ const nodes = /* @__PURE__ */ new Map();
5
+ const summary = {
6
+ totalNodes: 0,
7
+ staticNodes: 0,
8
+ staticSubtrees: 0,
9
+ dynamicTextNodes: 0,
10
+ dynamicAttrNodes: 0,
11
+ eventNodes: 0,
12
+ lists: 0,
13
+ conditionals: 0
14
+ };
15
+ const visit = (node) => {
16
+ let allChildrenStatic = true;
17
+ for (const child of node.children) {
18
+ const childSubtreeStatic = visit(child);
19
+ if (!childSubtreeStatic) allChildrenStatic = false;
20
+ }
21
+ let hasDynamicText = false;
22
+ let hasDynamicAttr = false;
23
+ for (const ref of node.stateRefs) {
24
+ if (TEXT_PROP_KEYS.has(ref.propKey)) hasDynamicText = true;
25
+ else hasDynamicAttr = true;
26
+ }
27
+ const hasEvents = node.events.length > 0;
28
+ const isList = node.type === "reactive-list";
29
+ const isConditional = node.type === "conditional";
30
+ const isStatic = node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional;
31
+ const isStaticSubtree = isStatic && allChildrenStatic;
32
+ nodes.set(node.id, {
33
+ isStatic,
34
+ isStaticSubtree,
35
+ hasDynamicText,
36
+ hasDynamicAttr,
37
+ hasEvents,
38
+ isList,
39
+ isConditional
40
+ });
41
+ summary.totalNodes += 1;
42
+ if (isStatic) summary.staticNodes += 1;
43
+ if (isStaticSubtree) summary.staticSubtrees += 1;
44
+ if (hasDynamicText) summary.dynamicTextNodes += 1;
45
+ if (hasDynamicAttr) summary.dynamicAttrNodes += 1;
46
+ if (hasEvents) summary.eventNodes += 1;
47
+ if (isList) summary.lists += 1;
48
+ if (isConditional) summary.conditionals += 1;
49
+ return isStaticSubtree;
50
+ };
51
+ visit(graph.root);
52
+ return { nodes, summary };
53
+ }
54
+
55
+ // src/analysis/inspect.ts
56
+ function inspectCompilation(graph) {
57
+ const analysis = analyzeGraph(graph);
58
+ const nodes = [];
59
+ const walk = (node, depth) => {
60
+ const a = analysis.nodes.get(node.id);
61
+ if (a !== void 0) {
62
+ const classification = a.isStaticSubtree ? "static-subtree-root" : a.isStatic ? "static" : "dynamic";
63
+ nodes.push({
64
+ id: node.id,
65
+ type: node.type,
66
+ depth,
67
+ classification,
68
+ dynamicText: a.hasDynamicText,
69
+ dynamicAttrs: a.hasDynamicAttr,
70
+ events: node.events.map((e) => e.type),
71
+ boundProps: node.stateRefs.map((r) => r.propKey),
72
+ isList: a.isList,
73
+ isConditional: a.isConditional,
74
+ hydration: a.isStaticSubtree ? "adopt-static" : "verify-dynamic"
75
+ });
76
+ }
77
+ for (const child of node.children) walk(child, depth + 1);
78
+ };
79
+ walk(graph.root, 0);
80
+ const staticRatio = analysis.summary.totalNodes === 0 ? 0 : analysis.summary.staticNodes / analysis.summary.totalNodes;
81
+ return {
82
+ name: graph.name,
83
+ version: graph.version,
84
+ summary: { ...analysis.summary, staticRatio: +staticRatio.toFixed(4) },
85
+ nodes
86
+ };
87
+ }
88
+ function formatInspection(inspection) {
89
+ const s = inspection.summary;
90
+ const lines = [];
91
+ lines.push(`StreetUI compiler inspection \u2014 ${inspection.name} v${inspection.version}`);
92
+ lines.push(
93
+ ` nodes=${s.totalNodes} static=${s.staticNodes} staticSubtrees=${s.staticSubtrees} dynamicText=${s.dynamicTextNodes} dynamicAttrs=${s.dynamicAttrNodes} events=${s.eventNodes} lists=${s.lists} conditionals=${s.conditionals} staticRatio=${(s.staticRatio * 100).toFixed(1)}%`
94
+ );
95
+ for (const n of inspection.nodes) {
96
+ const flags = [];
97
+ if (n.dynamicText) flags.push("text");
98
+ if (n.dynamicAttrs) flags.push("attr:" + n.boundProps.join(","));
99
+ if (n.events.length > 0) flags.push("on:" + n.events.join(","));
100
+ if (n.isList) flags.push("list");
101
+ if (n.isConditional) flags.push("cond");
102
+ lines.push(
103
+ ` ${" ".repeat(n.depth)}${n.type}#${n.id} [${n.classification}]` + (flags.length > 0 ? ` {${flags.join(" ")}}` : "")
104
+ );
105
+ }
106
+ return lines.join("\n");
107
+ }
108
+ export {
109
+ analyzeGraph,
110
+ formatInspection,
111
+ inspectCompilation
112
+ };
113
+ //# sourceMappingURL=diagnostics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/analysis/analyze.ts","../src/analysis/inspect.ts"],"sourcesContent":["/**\n * Static graph analysis (v1.2, spec §3/§12/§14).\n *\n * A single post-order walk over the Semantic Application Graph that classifies\n * every node as static (no bound signals, no events, not a reactive\n * region) or dynamic, and rolls that up into whole-static-subtree flags. This\n * is COMPILE-TIME metadata only — it introduces no virtual DOM, no second tree\n * and no runtime reactive system. It is consumed by:\n * - the hydration path, to skip per-node attribute/text re-verification on\n * provably-static subtrees (§12), and\n * - the diagnostic compiler-inspection report (§14).\n *\n * The renderer's initial-mount fast path does not need this map: it already\n * skips reactive wiring per node via cheap `events.length`/`stateRefs.length`\n * guards. Keeping the analysis out of the mount hot path avoids adding lookup\n * cost (and keeps the shipped runtime lean).\n */\n\nimport type { NodeId } from '@streetui/core';\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\n\n/** Prop keys whose bound signal drives text content rather than an attribute. */\nconst TEXT_PROP_KEYS: ReadonlySet<string> = new Set(['text', 'label', 'value']);\n\nexport interface NodeAnalysis {\n /** No bound signals, no events, and not a reactive-list/conditional region. */\n readonly isStatic: boolean;\n /** This node is static AND every descendant is a static subtree. */\n readonly isStaticSubtree: boolean;\n /** A signal is bound to this node's text/label/value content. */\n readonly hasDynamicText: boolean;\n /** A signal is bound to a non-content prop (a reactive attribute). */\n readonly hasDynamicAttr: boolean;\n /** This node wires one or more DOM event handlers. */\n readonly hasEvents: boolean;\n /** This node is a keyed reactive list. */\n readonly isList: boolean;\n /** This node is a conditional (0..1 branch) region. */\n readonly isConditional: boolean;\n}\n\nexport interface GraphAnalysisSummary {\n readonly totalNodes: number;\n readonly staticNodes: number;\n readonly staticSubtrees: number;\n readonly dynamicTextNodes: number;\n readonly dynamicAttrNodes: number;\n readonly eventNodes: number;\n readonly lists: number;\n readonly conditionals: number;\n}\n\nexport interface GraphAnalysis {\n readonly nodes: ReadonlyMap<NodeId, NodeAnalysis>;\n readonly summary: GraphAnalysisSummary;\n}\n\n/**\n * Analyze a fully-built graph. O(n) single post-order pass; allocates one small\n * record per node. Safe to skip entirely when neither hydration nor diagnostics\n * need it.\n */\nexport function analyzeGraph(graph: ApplicationGraph): GraphAnalysis {\n const nodes = new Map<NodeId, NodeAnalysis>();\n const summary = {\n totalNodes: 0, staticNodes: 0, staticSubtrees: 0, dynamicTextNodes: 0,\n dynamicAttrNodes: 0, eventNodes: 0, lists: 0, conditionals: 0,\n };\n\n const visit = (node: GraphNode): boolean => {\n // Post-order: children first so subtree rollup is exact.\n let allChildrenStatic = true;\n for (const child of node.children) {\n const childSubtreeStatic = visit(child);\n if (!childSubtreeStatic) allChildrenStatic = false;\n }\n\n let hasDynamicText = false;\n let hasDynamicAttr = false;\n for (const ref of node.stateRefs) {\n if (TEXT_PROP_KEYS.has(ref.propKey)) hasDynamicText = true;\n else hasDynamicAttr = true;\n }\n const hasEvents = node.events.length > 0;\n const isList = node.type === 'reactive-list';\n const isConditional = node.type === 'conditional';\n const isStatic =\n node.stateRefs.length === 0 && !hasEvents && !isList && !isConditional;\n const isStaticSubtree = isStatic && allChildrenStatic;\n\n nodes.set(node.id, {\n isStatic, isStaticSubtree, hasDynamicText, hasDynamicAttr,\n hasEvents, isList, isConditional,\n });\n\n summary.totalNodes += 1;\n if (isStatic) summary.staticNodes += 1;\n if (isStaticSubtree) summary.staticSubtrees += 1;\n if (hasDynamicText) summary.dynamicTextNodes += 1;\n if (hasDynamicAttr) summary.dynamicAttrNodes += 1;\n if (hasEvents) summary.eventNodes += 1;\n if (isList) summary.lists += 1;\n if (isConditional) summary.conditionals += 1;\n\n return isStaticSubtree;\n };\n\n visit(graph.root);\n return { nodes, summary };\n}\n","/**\n * Diagnostic compiler-inspection mode (v1.2, spec §14).\n *\n * Produces a machine-readable (and optionally text-formatted) description of\n * what the compiler understands about an application: which nodes are static\n * vs dynamic, which carry dynamic text or attributes, which wire events, and\n * which are conditional regions or keyed lists — plus the hydration metadata\n * derived from that classification.\n *\n * This is a DIAGNOSTIC tool. It is not part of the runtime, is not consulted\n * during mount, and is tree-shakeable out of any app that never calls it.\n */\n\nimport type { ApplicationGraph, GraphNode } from '@streetui/graph';\nimport { analyzeGraph, type GraphAnalysisSummary } from './analyze.js';\n\nexport interface InspectedCompilationNode {\n readonly id: string;\n readonly type: string;\n readonly depth: number;\n readonly classification: 'static' | 'static-subtree-root' | 'dynamic';\n readonly dynamicText: boolean;\n readonly dynamicAttrs: boolean;\n readonly events: readonly string[];\n readonly boundProps: readonly string[];\n readonly isList: boolean;\n readonly isConditional: boolean;\n /** Hydration hint: how the hydration path should treat this node. */\n readonly hydration: 'adopt-static' | 'verify-dynamic';\n}\n\nexport interface CompilerInspection {\n readonly name: string;\n readonly version: string;\n readonly summary: GraphAnalysisSummary & {\n /** Fraction of nodes provably static (0..1). */\n readonly staticRatio: number;\n };\n readonly nodes: readonly InspectedCompilationNode[];\n}\n\n/**\n * Inspect a compiled/built graph and return a structured diagnostic report.\n * Purely observational — never mutates the graph.\n */\nexport function inspectCompilation(graph: ApplicationGraph): CompilerInspection {\n const analysis = analyzeGraph(graph);\n const nodes: InspectedCompilationNode[] = [];\n\n const walk = (node: GraphNode, depth: number): void => {\n const a = analysis.nodes.get(node.id);\n if (a !== undefined) {\n const classification: InspectedCompilationNode['classification'] = a.isStaticSubtree\n ? 'static-subtree-root'\n : a.isStatic\n ? 'static'\n : 'dynamic';\n nodes.push({\n id: node.id,\n type: node.type,\n depth,\n classification,\n dynamicText: a.hasDynamicText,\n dynamicAttrs: a.hasDynamicAttr,\n events: node.events.map((e) => e.type),\n boundProps: node.stateRefs.map((r) => r.propKey),\n isList: a.isList,\n isConditional: a.isConditional,\n hydration: a.isStaticSubtree ? 'adopt-static' : 'verify-dynamic',\n });\n }\n for (const child of node.children) walk(child, depth + 1);\n };\n walk(graph.root, 0);\n\n const staticRatio =\n analysis.summary.totalNodes === 0\n ? 0\n : analysis.summary.staticNodes / analysis.summary.totalNodes;\n\n return {\n name: graph.name,\n version: graph.version,\n summary: { ...analysis.summary, staticRatio: +staticRatio.toFixed(4) },\n nodes,\n };\n}\n\n/** Render an inspection as a compact human-readable text report. */\nexport function formatInspection(inspection: CompilerInspection): string {\n const s = inspection.summary;\n const lines: string[] = [];\n lines.push(`StreetUI compiler inspection — ${inspection.name} v${inspection.version}`);\n lines.push(\n ` nodes=${s.totalNodes} static=${s.staticNodes} ` +\n `staticSubtrees=${s.staticSubtrees} dynamicText=${s.dynamicTextNodes} ` +\n `dynamicAttrs=${s.dynamicAttrNodes} events=${s.eventNodes} ` +\n `lists=${s.lists} conditionals=${s.conditionals} ` +\n `staticRatio=${(s.staticRatio * 100).toFixed(1)}%`,\n );\n for (const n of inspection.nodes) {\n const flags: string[] = [];\n if (n.dynamicText) flags.push('text');\n if (n.dynamicAttrs) flags.push('attr:' + n.boundProps.join(','));\n if (n.events.length > 0) flags.push('on:' + n.events.join(','));\n if (n.isList) flags.push('list');\n if (n.isConditional) flags.push('cond');\n lines.push(\n ` ${' '.repeat(n.depth)}${n.type}#${n.id} [${n.classification}]` +\n (flags.length > 0 ? ` {${flags.join(' ')}}` : ''),\n );\n }\n return lines.join('\\n');\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streetui/compiler",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "StreetUI compiler — DSL → validation → Semantic Application Graph",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -16,6 +16,16 @@
16
16
  "types": "./dist/index.d.cts",
17
17
  "default": "./dist/index.cjs"
18
18
  }
19
+ },
20
+ "./diagnostics": {
21
+ "import": {
22
+ "types": "./dist/diagnostics.d.ts",
23
+ "default": "./dist/diagnostics.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/diagnostics.d.cts",
27
+ "default": "./dist/diagnostics.cjs"
28
+ }
19
29
  }
20
30
  },
21
31
  "scripts": {
@@ -25,10 +35,10 @@
25
35
  "clean": "rm -rf dist"
26
36
  },
27
37
  "dependencies": {
28
- "@streetui/core": "1.0.0",
29
- "@streetui/graph": "1.0.0",
30
- "@streetui/dsl": "1.0.0",
31
- "@streetui/state": "1.0.0"
38
+ "@streetui/core": "1.2.0",
39
+ "@streetui/graph": "1.2.0",
40
+ "@streetui/dsl": "1.2.0",
41
+ "@streetui/state": "1.2.0"
32
42
  },
33
43
  "devDependencies": {
34
44
  "typescript": "*",