streetui 2.1.0 → 2.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.
package/dist/index.cjs CHANGED
@@ -28,6 +28,7 @@ __export(src_exports, {
28
28
  CleanupRegistry: () => CleanupRegistry,
29
29
  ContainerBuilderImpl: () => ContainerBuilderImpl,
30
30
  DEFAULT_PERF_THRESHOLDS: () => DEFAULT_PERF_THRESHOLDS,
31
+ DEVTOOLS_TABS: () => DEVTOOLS_TABS,
31
32
  DerivedSignal: () => DerivedSignal,
32
33
  DiagnosticCollector: () => DiagnosticCollector,
33
34
  DiagnosticError: () => DiagnosticError,
@@ -124,13 +125,17 @@ __export(src_exports, {
124
125
  inspectApplication: () => inspectApplication,
125
126
  inspectComponents: () => inspectComponents,
126
127
  inspectContext: () => inspectContext,
128
+ inspectEvents: () => inspectEvents,
127
129
  inspectForm: () => inspectForm,
128
130
  inspectGraph: () => inspectGraph,
131
+ inspectHydration: () => inspectHydration,
129
132
  inspectI18n: () => inspectI18n,
130
133
  inspectInteractions: () => inspectInteractions,
134
+ inspectMutation: () => inspectMutation,
131
135
  inspectResource: () => inspectResource,
132
136
  inspectRouter: () => inspectRouter,
133
137
  inspectSignal: () => inspectSignal,
138
+ inspectSignalGraph: () => inspectSignalGraph,
134
139
  interpolate: () => interpolate,
135
140
  isBatching: () => isBatching,
136
141
  isComponentDefinition: () => isComponentDefinition,
@@ -164,6 +169,7 @@ __export(src_exports, {
164
169
  renderDevToolsHTML: () => renderDevToolsHTML,
165
170
  renderDevToolsReport: () => renderDevToolsReport,
166
171
  renderHead: () => renderHead,
172
+ renderInteractiveDevTools: () => renderInteractiveDevTools,
167
173
  renderToString: () => renderToString,
168
174
  reportDiagnostic: () => reportDiagnostic,
169
175
  reportError: () => reportError,
@@ -205,7 +211,7 @@ __export(src_exports, {
205
211
  module.exports = __toCommonJS(src_exports);
206
212
 
207
213
  // src/version.ts
208
- var VERSION = "2.1.0";
214
+ var VERSION = "2.2.0";
209
215
 
210
216
  // ../state/src/signal.ts
211
217
  var _activeConsumer = null;
@@ -5849,6 +5855,23 @@ function errorMessageOf(error) {
5849
5855
  if (error instanceof Error) return error.message;
5850
5856
  return String(error);
5851
5857
  }
5858
+ function inspectMutation(mutation2, options = {}) {
5859
+ const error = mutation2.error.peek();
5860
+ const hasError = error !== void 0 && error !== null;
5861
+ const base = {
5862
+ status: mutation2.status.peek(),
5863
+ pending: mutation2.pending.peek(),
5864
+ hasData: mutation2.data.peek() !== void 0,
5865
+ hasError,
5866
+ errorName: hasError ? errorConstructorName(error) : void 0
5867
+ };
5868
+ if (options.includeData !== true) return base;
5869
+ return {
5870
+ ...base,
5871
+ data: mutation2.data.peek(),
5872
+ ...hasError ? { errorMessage: errorMessageOf(error) } : {}
5873
+ };
5874
+ }
5852
5875
  function inspectRouter(router) {
5853
5876
  const match = router.currentRoute.peek();
5854
5877
  const query = {};
@@ -5896,6 +5919,97 @@ function inspectI18n(i18n, options = {}) {
5896
5919
  return { ...base, missingKeys };
5897
5920
  }
5898
5921
 
5922
+ // ../devtools/src/inspect-detail.ts
5923
+ function inspectEvents(graph) {
5924
+ const nodes = [];
5925
+ const byType = {};
5926
+ let totalHandlers = 0;
5927
+ graph.walk((node, depth) => {
5928
+ if (node.events.length === 0) return;
5929
+ const types = node.events.map((e) => e.type);
5930
+ for (const t of types) {
5931
+ byType[t] = (byType[t] ?? 0) + 1;
5932
+ totalHandlers += 1;
5933
+ }
5934
+ nodes.push({
5935
+ id: node.id,
5936
+ nodeType: node.type,
5937
+ key: node.key,
5938
+ depth,
5939
+ eventTypes: [...types].sort()
5940
+ });
5941
+ });
5942
+ return { nodes, totalHandlers, byType };
5943
+ }
5944
+ function inspectSignalGraph(compiled, options = {}) {
5945
+ const graph = compiled.graph;
5946
+ const edges = [];
5947
+ const byId = /* @__PURE__ */ new Map();
5948
+ graph.walk((node) => {
5949
+ for (const ref of node.stateRefs) {
5950
+ edges.push({
5951
+ signalId: ref.signalId,
5952
+ nodeId: node.id,
5953
+ nodeType: node.type,
5954
+ propKey: ref.propKey
5955
+ });
5956
+ let entry = byId.get(ref.signalId);
5957
+ if (entry === void 0) {
5958
+ entry = { boundNodeIds: /* @__PURE__ */ new Set(), bindingCount: 0 };
5959
+ byId.set(ref.signalId, entry);
5960
+ }
5961
+ entry.boundNodeIds.add(node.id);
5962
+ entry.bindingCount += 1;
5963
+ }
5964
+ });
5965
+ const live = options.signalsById;
5966
+ const signals = [...byId.entries()].sort((a, b) => a[0] < b[0] ? -1 : a[0] > b[0] ? 1 : 0).map(([signalId, entry]) => {
5967
+ const base = {
5968
+ signalId,
5969
+ boundNodeIds: [...entry.boundNodeIds],
5970
+ bindingCount: entry.bindingCount
5971
+ };
5972
+ const sig = live?.[signalId];
5973
+ if (sig === void 0) return base;
5974
+ const oc = observerCount(sig);
5975
+ return {
5976
+ ...base,
5977
+ kind: signalKind(sig),
5978
+ ...oc !== void 0 ? { observerCount: oc } : {}
5979
+ };
5980
+ });
5981
+ return { signals, edges };
5982
+ }
5983
+
5984
+ // ../devtools/src/inspect-ssr.ts
5985
+ function countType(graph, type) {
5986
+ let n = 0;
5987
+ graph.walk((node) => {
5988
+ if (node.type === type) n += 1;
5989
+ });
5990
+ return n;
5991
+ }
5992
+ function inspectHydration(compiled) {
5993
+ const graph = compiled.graph;
5994
+ const { summary } = analyzeGraph(graph);
5995
+ const dynamicNodes = summary.totalNodes - summary.staticNodes;
5996
+ const staticRatio = summary.totalNodes === 0 ? 0 : Math.round(summary.staticNodes / summary.totalNodes * 1e4) / 1e4;
5997
+ return {
5998
+ totalNodes: summary.totalNodes,
5999
+ staticNodes: summary.staticNodes,
6000
+ staticSubtrees: summary.staticSubtrees,
6001
+ dynamicNodes,
6002
+ dynamicTextNodes: summary.dynamicTextNodes,
6003
+ dynamicAttrNodes: summary.dynamicAttrNodes,
6004
+ eventNodes: summary.eventNodes,
6005
+ lists: summary.lists,
6006
+ conditionals: summary.conditionals,
6007
+ portals: countType(graph, "portal"),
6008
+ headAnchors: countType(graph, "head"),
6009
+ staticRatio
6010
+ };
6011
+ }
6012
+
5899
6013
  // ../devtools/src/panels.ts
5900
6014
  function createDevTools(compiled, sources = {}, options = {}) {
5901
6015
  let current = capture(compiled, sources, options);
@@ -5949,6 +6063,12 @@ function capture(compiled, sources, options) {
5949
6063
  warnings: app.diagnostics.warnings,
5950
6064
  messages: app.diagnostics.messages
5951
6065
  };
6066
+ const events = inspectEvents(compiled.graph);
6067
+ const signalGraph = inspectSignalGraph(
6068
+ compiled,
6069
+ sources.signalsById !== void 0 ? { signalsById: sources.signalsById } : {}
6070
+ );
6071
+ const hydration = inspectHydration(compiled);
5952
6072
  const snapshot = {
5953
6073
  application,
5954
6074
  graph: app.graph,
@@ -5958,8 +6078,12 @@ function capture(compiled, sources, options) {
5958
6078
  overlays: interactions.overlays,
5959
6079
  transitions: interactions.transitions,
5960
6080
  diagnostics,
6081
+ events,
6082
+ signalGraph,
6083
+ hydration,
5961
6084
  ...sources.router !== void 0 ? { router: inspectRouter(sources.router) } : {},
5962
6085
  ...sources.resources !== void 0 ? { resources: mapInspect(sources.resources, (r) => inspectResource(r)) } : {},
6086
+ ...sources.mutations !== void 0 ? { mutations: mapInspect(sources.mutations, (m) => inspectMutation(m)) } : {},
5963
6087
  ...sources.forms !== void 0 ? { forms: mapInspect(sources.forms, (f) => inspectForm(f)) } : {},
5964
6088
  ...sources.contexts !== void 0 ? { contexts: mapInspect(sources.contexts, (c) => inspectContext(c)) } : {},
5965
6089
  ...sources.i18n !== void 0 ? {
@@ -6026,6 +6150,12 @@ function formatSnapshot(s) {
6026
6150
  lines.push(` ${label}: ${r.status}${r.loading ? " (loading)" : ""}${r.hasError ? ` !${r.errorName}` : ""}`);
6027
6151
  }
6028
6152
  }
6153
+ if (s.mutations !== void 0) {
6154
+ lines.push("Mutations:");
6155
+ for (const [label, m] of Object.entries(s.mutations)) {
6156
+ lines.push(` ${label}: ${m.status}${m.pending ? " (pending)" : ""}${m.hasError ? ` !${m.errorName}` : ""}`);
6157
+ }
6158
+ }
6029
6159
  if (s.forms !== void 0) {
6030
6160
  lines.push("Forms:");
6031
6161
  for (const [label, f] of Object.entries(s.forms)) {
@@ -6056,6 +6186,17 @@ function formatSnapshot(s) {
6056
6186
  for (const m of s.diagnostics.messages) {
6057
6187
  lines.push(` ${m}`);
6058
6188
  }
6189
+ lines.push(
6190
+ `Events: ${s.events.nodes.length} node(s), ${s.events.totalHandlers} handler(s)` + (Object.keys(s.events.byType).length > 0 ? ` \xB7 ${Object.entries(s.events.byType).map(([t, n]) => `${t}\xD7${n}`).join(", ")}` : "")
6191
+ );
6192
+ lines.push(
6193
+ `Signal graph: ${s.signalGraph.signals.length} signal(s), ${s.signalGraph.edges.length} binding edge(s)`
6194
+ );
6195
+ const h = s.hydration;
6196
+ lines.push(
6197
+ `SSR/Hydration: ${h.staticNodes}/${h.totalNodes} static (${(h.staticRatio * 100).toFixed(1)}%), ${h.dynamicNodes} dynamic \xB7 ${h.staticSubtrees} static subtree(s) \xB7 ${h.portals} portal(s), ${h.headAnchors} head anchor(s)`
6198
+ );
6199
+ lines.push(" (structural counts only \u2014 not wall-clock timings; browser gate BLOCKED)");
6059
6200
  return lines.join("\n");
6060
6201
  }
6061
6202
  function format(value) {
@@ -6241,6 +6382,207 @@ var DEVTOOLS_CSS = [
6241
6382
  "code{color:#d7d7e0}"
6242
6383
  ].join("");
6243
6384
 
6385
+ // ../devtools/src/interactive.ts
6386
+ var DEVTOOLS_TABS = [
6387
+ { id: "components", label: "Component Tree" },
6388
+ { id: "inspector", label: "Component Inspector" },
6389
+ { id: "state", label: "Reactive State" },
6390
+ { id: "signalGraph", label: "Signal Graph" },
6391
+ { id: "router", label: "Router" },
6392
+ { id: "resources", label: "Resource / Async" },
6393
+ { id: "mutations", label: "Mutations" },
6394
+ { id: "events", label: "Events" },
6395
+ { id: "overlays", label: "Overlays" },
6396
+ { id: "performance", label: "Performance" },
6397
+ { id: "diagnostics", label: "Error Diagnostics" },
6398
+ { id: "hydration", label: "SSR / Hydration" }
6399
+ ];
6400
+ var EMBED_ESCAPE = new RegExp("[<\\u2028\\u2029]", "g");
6401
+ function embedJson(snapshot) {
6402
+ return JSON.stringify(snapshot).replace(EMBED_ESCAPE, (ch) => {
6403
+ const code = ch.charCodeAt(0).toString(16).padStart(4, "0");
6404
+ return `\\u${code}`;
6405
+ });
6406
+ }
6407
+ function renderInteractiveDevTools(snapshot, options = {}) {
6408
+ const app = snapshot.application;
6409
+ const title = options.title ?? `StreetUI DevTools \u2014 ${app.identity.name}`;
6410
+ const initialTab = options.initialTab ?? DEVTOOLS_TABS[0].id;
6411
+ const tabButtons = DEVTOOLS_TABS.map(
6412
+ (t) => `<button type="button" role="tab" class="st-tab" data-tab="${escapeHtml(t.id)}"${t.id === initialTab ? ' aria-selected="true"' : ' aria-selected="false"'}>${escapeHtml(t.label)}</button>`
6413
+ ).join("");
6414
+ return `<!doctype html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width,initial-scale=1"><title>${escapeHtml(title)}</title><style>${INTERACTIVE_CSS}</style></head><body class="st-dt"><header class="st-top"><h1>${escapeHtml(title)} <span class="st-dim">v${escapeHtml(app.identity.version)}</span></h1><button type="button" id="st-refresh" class="st-refresh">&#8635; Refresh</button></header><nav class="st-tabs" role="tablist" aria-label="DevTools panels">${tabButtons}</nav><main id="st-panel" class="st-body" role="tabpanel" aria-live="polite"></main><footer class="st-foot"><span class="st-dim">Structural inspection over one compiled graph. Not a production profiler; browser/AT conformance not claimed (gates BLOCKED).</span></footer><script type="application/json" id="st-data">${embedJson(snapshot)}</script><script>${CONTROLLER_JS.replace("__INITIAL_TAB__", JSON.stringify(initialTab))}</script></body></html>`;
6415
+ }
6416
+ var CONTROLLER_JS = [
6417
+ "(function(){",
6418
+ '"use strict";',
6419
+ "var INITIAL_TAB=__INITIAL_TAB__;",
6420
+ "function esc(v){",
6421
+ " if(v===null||v===undefined)return String(v);",
6422
+ " var s=typeof v==='string'?v:(typeof v==='object'?sj(v):String(v));",
6423
+ ` return s.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;').replace(/'/g,'&#39;');`,
6424
+ "}",
6425
+ 'function sj(v){try{return JSON.stringify(v);}catch(e){return "[object]";}}',
6426
+ 'function read(){var el=document.getElementById("st-data");if(!el)return {};try{return JSON.parse(el.textContent||"{}");}catch(e){return {};}}',
6427
+ "var state={data:read(),tab:INITIAL_TAB,selected:null};",
6428
+ "function findNode(n,id){if(!n)return null;if(n.id===id)return n;var c=n.children||[];for(var i=0;i<c.length;i++){var f=findNode(c[i],id);if(f)return f;}return null;}",
6429
+ 'function empty(m){return "<p class=\\"st-empty\\">"+esc(m||"(none)")+"</p>";}',
6430
+ 'function kv(k,v){return "<div class=\\"st-kv\\"><span class=\\"st-k\\">"+esc(k)+"</span><span class=\\"st-v\\">"+esc(v)+"</span></div>";}',
6431
+ "function rComponents(){",
6432
+ " var cs=state.data.components||[];",
6433
+ ' if(!cs.length)return empty("No component() instances");',
6434
+ ' var h="<ul class=\\"st-list\\">";',
6435
+ " for(var i=0;i<cs.length;i++){var c=cs[i];",
6436
+ ' h+="<li class=\\"st-row st-click\\" data-node=\\""+esc(c.id||"")+"\\">"',
6437
+ ' +"<span class=\\"st-ind\\" style=\\"--d:"+(c.depth||0)+"\\"></span>"',
6438
+ ' +"<code>"+esc(c.name)+"</code>"',
6439
+ ' +(c.key!=null?" <span class=\\"st-key\\">#"+esc(c.key)+"</span>":"")',
6440
+ ' +" <span class=\\"st-dim\\">"+(c.childCount||0)+" child</span></li>";}',
6441
+ ' return h+"</ul><p class=\\"st-dim\\">Click a component to inspect it.</p>";',
6442
+ "}",
6443
+ "function rInspector(){",
6444
+ ' if(!state.selected)return empty("Select a node in Component Tree, Events or Overlays");',
6445
+ " var n=findNode(state.data.graph,state.selected);",
6446
+ ' if(!n)return empty("Node "+state.selected+" not found in current snapshot");',
6447
+ ' var h="<h3><code>&lt;"+esc(n.type)+"&gt;</code>"+(n.key!=null?" <span class=\\"st-key\\">#"+esc(n.key)+"</span>":"")+"</h3>";',
6448
+ ' h+=kv("id",n.id)+kv("depth",n.depth)+kv("children",(n.children||[]).length);',
6449
+ " var pk=Object.keys(n.props||{});",
6450
+ ' h+="<h4>Props</h4>"+(pk.length?pk.map(function(k){return kv(k,n.props[k]);}).join(""):empty("none"));',
6451
+ ' h+="<h4>Event types</h4>"+((n.eventTypes||[]).length?"<code>"+esc((n.eventTypes||[]).join(", "))+"</code>":empty("none"));',
6452
+ ' h+="<h4>State bindings</h4>"+((n.stateBindings||[]).length?"<ul class=\\"st-list\\">"+n.stateBindings.map(function(b){return "<li><code>"+esc(b)+"</code></li>";}).join("")+"</ul>":empty("none"));',
6453
+ " return h;",
6454
+ "}",
6455
+ "function rState(){",
6456
+ " var s=state.data.signals||{};var live=s.live||{};var ids=s.boundSignalIds||[];",
6457
+ ' var h="<p class=\\"st-dim\\">"+ids.length+" signal id(s) bound in graph. Effects are shown as observer counts (no global effect registry).</p>";',
6458
+ " var labels=Object.keys(live);",
6459
+ ' if(!labels.length)return h+empty("No live signals registered with DevTools");',
6460
+ ' h+="<ul class=\\"st-list\\">";',
6461
+ " for(var i=0;i<labels.length;i++){var l=labels[i];var sg=live[l];",
6462
+ ' h+="<li><code>"+esc(l)+"</code> <span class=\\"st-key\\">["+esc(sg.kind)+"]</span> = <code>"+esc(sg.value)+"</code> <span class=\\"st-dim\\">observers "+esc(sg.observerCount==null?"?":sg.observerCount)+"</span></li>";}',
6463
+ ' return h+"</ul>";',
6464
+ "}",
6465
+ "function rSignalGraph(){",
6466
+ " var g=state.data.signalGraph||{signals:[],edges:[]};",
6467
+ ' if(!(g.signals||[]).length)return empty("No signal bindings in graph");',
6468
+ ' var h="<p class=\\"st-dim\\">"+g.signals.length+" signal(s), "+(g.edges||[]).length+" binding edge(s)</p><ul class=\\"st-list\\">";',
6469
+ " for(var i=0;i<g.signals.length;i++){var sn=g.signals[i];",
6470
+ ' h+="<li><code>"+esc(sn.signalId)+"</code> <span class=\\"st-dim\\">&rarr; "+(sn.boundNodeIds||[]).length+" node(s), "+sn.bindingCount+" edge(s)</span>"',
6471
+ ' +(sn.kind?" <span class=\\"st-key\\">["+esc(sn.kind)+"]</span>":"")',
6472
+ ' +(sn.observerCount!=null?" <span class=\\"st-dim\\">obs "+esc(sn.observerCount)+"</span>":"")+"</li>";}',
6473
+ ' return h+"</ul>";',
6474
+ "}",
6475
+ "function rRouter(){",
6476
+ ' var r=state.data.router;if(!r)return empty("No router registered");',
6477
+ ' return kv("path",r.path)+kv("pattern",r.pattern)+kv("fallback",r.isFallback?"yes":"no")',
6478
+ ' +"<h4>Params</h4>"+(Object.keys(r.params||{}).length?Object.keys(r.params).map(function(k){return kv(k,r.params[k]);}).join(""):empty("none"))',
6479
+ ' +"<h4>Query</h4>"+(Object.keys(r.query||{}).length?Object.keys(r.query).map(function(k){return kv(k,r.query[k]);}).join(""):empty("none"));',
6480
+ "}",
6481
+ "function rResources(){",
6482
+ ' var rs=state.data.resources;if(!rs||!Object.keys(rs).length)return empty("No resources registered");',
6483
+ ' var ks=Object.keys(rs);var h="<ul class=\\"st-list\\">";',
6484
+ " for(var i=0;i<ks.length;i++){var r=rs[ks[i]];",
6485
+ ' h+="<li><code>"+esc(ks[i])+"</code>: <span class=\\"st-key\\">"+esc(r.status)+"</span>"',
6486
+ ' +(r.loading?" <span class=\\"st-dim\\">(loading)</span>":"")',
6487
+ ' +(r.isRefetching?" <span class=\\"st-dim\\">(refetching)</span>":"")',
6488
+ ' +(r.hasError?" <span class=\\"st-err\\">!"+esc(r.errorName)+"</span>":"")+"</li>";}',
6489
+ ' return h+"</ul>";',
6490
+ "}",
6491
+ "function rMutations(){",
6492
+ ' var ms=state.data.mutations;if(!ms||!Object.keys(ms).length)return empty("No mutations registered");',
6493
+ ' var ks=Object.keys(ms);var h="<ul class=\\"st-list\\">";',
6494
+ " for(var i=0;i<ks.length;i++){var m=ms[ks[i]];",
6495
+ ' h+="<li><code>"+esc(ks[i])+"</code>: <span class=\\"st-key\\">"+esc(m.status)+"</span>"',
6496
+ ' +(m.pending?" <span class=\\"st-dim\\">(pending)</span>":"")',
6497
+ ' +(m.hasError?" <span class=\\"st-err\\">!"+esc(m.errorName)+"</span>":"")+"</li>";}',
6498
+ ' return h+"</ul>";',
6499
+ "}",
6500
+ "function rEvents(){",
6501
+ " var e=state.data.events||{nodes:[],totalHandlers:0,byType:{}};",
6502
+ " var bt=e.byType||{};var bk=Object.keys(bt);",
6503
+ ' var h="<p class=\\"st-dim\\">"+(e.nodes||[]).length+" node(s), "+e.totalHandlers+" handler(s)</p>";',
6504
+ ' h+=bk.length?"<p>"+bk.map(function(t){return "<span class=\\"st-badge\\">"+esc(t)+" &times;"+bt[t]+"</span>";}).join(" ")+"</p>":"";',
6505
+ ' if(!(e.nodes||[]).length)return h+empty("No event handlers wired");',
6506
+ ' h+="<ul class=\\"st-list\\">";',
6507
+ " for(var i=0;i<e.nodes.length;i++){var n=e.nodes[i];",
6508
+ ' h+="<li class=\\"st-row st-click\\" data-node=\\""+esc(n.id)+"\\"><code>&lt;"+esc(n.nodeType)+"&gt;</code>"',
6509
+ ' +(n.key!=null?" <span class=\\"st-key\\">#"+esc(n.key)+"</span>":"")',
6510
+ ' +" <span class=\\"st-dim\\">"+esc((n.eventTypes||[]).join(", "))+"</span></li>";}',
6511
+ ' return h+"</ul>";',
6512
+ "}",
6513
+ "function rOverlays(){",
6514
+ ' var os=state.data.overlays||[];if(!os.length)return empty("No overlays wired");',
6515
+ ' var h="<ul class=\\"st-list\\">";',
6516
+ " for(var i=0;i<os.length;i++){var o=os[i];",
6517
+ ' var kind=o.modal?"modal":(o.menu?"menu":(o.takesFocus?"focusable":"non-modal"));',
6518
+ ' h+="<li class=\\"st-row st-click\\" data-node=\\""+esc(o.id)+"\\"><code>"+esc(o.key||o.id)+"</code> <span class=\\"st-key\\">["+kind+"]</span> <span class=\\"st-dim\\">"+(o.open?"open":"closed")+(o.closeOnEscape?" \\u00b7 esc":"")+(o.restoreFocus?" \\u00b7 restore":"")+"</span></li>";}',
6519
+ ' return h+"</ul>";',
6520
+ "}",
6521
+ "function rPerformance(){",
6522
+ " var p=state.data.performance||{snapshot:{},diagnostics:[]};var snap=p.snapshot||{};",
6523
+ ' var h="<p class=\\"st-warn\\">Structural counts, not wall-clock timings. A real render/interaction timeline needs a browser (gate BLOCKED); no timings are fabricated here.</p>";',
6524
+ " var sk=Object.keys(snap);",
6525
+ ' h+="<h4>Graph metrics</h4>"+(sk.length?sk.map(function(k){return kv(k,snap[k]);}).join(""):empty("none"));',
6526
+ " var d=p.diagnostics||[];",
6527
+ ' h+="<h4>Diagnostics ("+d.length+")</h4>"+(d.length?"<ul class=\\"st-list\\">"+d.map(function(x){return "<li><code>"+esc(x.code)+"</code>: "+esc(x.message)+"</li>";}).join("")+"</ul>":empty("none"));',
6528
+ " return h;",
6529
+ "}",
6530
+ "function rDiagnostics(){",
6531
+ " var d=state.data.diagnostics||{errors:0,warnings:0,messages:[]};",
6532
+ ' var h="<p class=\\"st-dim\\">"+d.errors+" error(s) \\u00b7 "+d.warnings+" warning(s) (compiler findings)</p>";',
6533
+ " var m=d.messages||[];",
6534
+ ' return h+(m.length?"<ul class=\\"st-list\\">"+m.map(function(x){return "<li>"+esc(x)+"</li>";}).join("")+"</ul>":empty("No diagnostics"));',
6535
+ "}",
6536
+ "function rHydration(){",
6537
+ ' var h2=state.data.hydration;if(!h2)return empty("No hydration inspection");',
6538
+ " var pct=(h2.staticRatio*100).toFixed(1);",
6539
+ ' var h="<p class=\\"st-warn\\">Structural static-vs-dynamic split only \\u2014 NOT wall-clock SSR/hydration timing (browser gate BLOCKED).</p>";',
6540
+ ' h+=kv("total nodes",h2.totalNodes)+kv("static nodes",h2.staticNodes+" ("+pct+"%)")+kv("dynamic nodes",h2.dynamicNodes)',
6541
+ ' +kv("static subtrees",h2.staticSubtrees)+kv("dynamic text",h2.dynamicTextNodes)+kv("dynamic attrs",h2.dynamicAttrNodes)',
6542
+ ' +kv("event nodes",h2.eventNodes)+kv("lists",h2.lists)+kv("conditionals",h2.conditionals)+kv("portals",h2.portals)+kv("head anchors",h2.headAnchors);',
6543
+ " return h;",
6544
+ "}",
6545
+ "var RENDERERS={components:rComponents,inspector:rInspector,state:rState,signalGraph:rSignalGraph,router:rRouter,resources:rResources,mutations:rMutations,events:rEvents,overlays:rOverlays,performance:rPerformance,diagnostics:rDiagnostics,hydration:rHydration};",
6546
+ 'function renderTab(){var el=document.getElementById("st-panel");if(!el)return;var fn=RENDERERS[state.tab]||function(){return empty("Unknown panel");};',
6547
+ " el.innerHTML=fn();",
6548
+ ' var rows=el.querySelectorAll(".st-click");',
6549
+ ' for(var i=0;i<rows.length;i++){(function(row){row.addEventListener("click",function(){var id=row.getAttribute("data-node");if(id){state.selected=id;selectTab("inspector");}});})(rows[i]);}',
6550
+ "}",
6551
+ 'function selectTab(id){state.tab=id;var tabs=document.querySelectorAll(".st-tab");for(var i=0;i<tabs.length;i++){var t=tabs[i];t.setAttribute("aria-selected",t.getAttribute("data-tab")===id?"true":"false");}renderTab();}',
6552
+ 'function selectComponent(id){state.selected=id;selectTab("inspector");}',
6553
+ 'function refresh(){var hook=window.__STREETUI_DEVTOOLS_REFRESH__;if(typeof hook!=="function")return false;var next=hook();if(next&&typeof next==="object"){state.data=next;renderTab();return true;}return false;}',
6554
+ "function bind(){",
6555
+ ' var tabs=document.querySelectorAll(".st-tab");',
6556
+ ' for(var i=0;i<tabs.length;i++){(function(t){t.addEventListener("click",function(){selectTab(t.getAttribute("data-tab"));});})(tabs[i]);}',
6557
+ ' var rb=document.getElementById("st-refresh");if(rb)rb.addEventListener("click",refresh);',
6558
+ "}",
6559
+ "window.__StreetUIDevTools={get data(){return state.data;},get tab(){return state.tab;},get selected(){return state.selected;},selectTab:selectTab,selectComponent:selectComponent,refresh:refresh,render:renderTab};",
6560
+ "bind();renderTab();",
6561
+ "})();"
6562
+ ].join("\n");
6563
+ var INTERACTIVE_CSS = [
6564
+ "*{box-sizing:border-box}",
6565
+ ".st-dt{font:13px/1.5 ui-monospace,SFMono-Regular,Menlo,monospace;margin:0;color:#e6e6e6;background:#1e1e28;display:flex;flex-direction:column;min-height:100vh}",
6566
+ ".st-top{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #333;background:#15151c}",
6567
+ ".st-top h1{font-size:14px;margin:0}",
6568
+ ".st-refresh{font:inherit;color:#e6e6e6;background:#2c2c3a;border:1px solid #3a3a4a;border-radius:5px;padding:4px 10px;cursor:pointer}",
6569
+ ".st-refresh:hover{background:#37374a}",
6570
+ ".st-tabs{display:flex;flex-wrap:wrap;gap:2px;padding:6px 10px;border-bottom:1px solid #2c2c38;background:#191922}",
6571
+ ".st-tab{font:inherit;color:#b8b8c8;background:transparent;border:0;border-radius:5px;padding:5px 10px;cursor:pointer}",
6572
+ ".st-tab:hover{background:#26263200}",
6573
+ '.st-tab[aria-selected="true"]{background:#2f2f40;color:#fff}',
6574
+ ".st-body{flex:1;padding:12px 16px;overflow:auto}",
6575
+ ".st-body h3{font-size:13px;margin:2px 0 8px}.st-body h4{font-size:11px;text-transform:uppercase;letter-spacing:.05em;color:#9a9aae;margin:14px 0 4px}",
6576
+ ".st-list{list-style:none;margin:0;padding:0}.st-list li{padding:2px 0}",
6577
+ ".st-row{display:flex;align-items:center;gap:6px}.st-click{cursor:pointer;border-radius:4px;padding:2px 4px}.st-click:hover{background:#26263a}",
6578
+ ".st-ind{display:inline-block;width:calc(var(--d,0)*12px)}",
6579
+ ".st-kv{display:flex;gap:10px;padding:1px 0}.st-k{color:#9a9aae;min-width:120px}.st-v{color:#d7d7e0;word-break:break-all}",
6580
+ ".st-badge{display:inline-block;background:#2c2c3a;border-radius:10px;padding:1px 8px;font-size:11px}",
6581
+ ".st-foot{padding:6px 16px;border-top:1px solid #2c2c38;background:#15151c}",
6582
+ ".st-dim{color:#8a8a9a}.st-key{color:#7db4ff}.st-err{color:#ff8a8a}.st-empty{color:#6a6a7a}.st-warn{color:#ffce8a;margin:0 0 10px}",
6583
+ "code{color:#d7d7e0}"
6584
+ ].join("");
6585
+
6244
6586
  // ../devtools/src/devtools-report.ts
6245
6587
  function renderDevToolsReport(compiled, sources = {}, options = {}) {
6246
6588
  const session = createDevTools(compiled, sources, options);
@@ -6261,6 +6603,7 @@ function defineConfig(config) {
6261
6603
  CleanupRegistry,
6262
6604
  ContainerBuilderImpl,
6263
6605
  DEFAULT_PERF_THRESHOLDS,
6606
+ DEVTOOLS_TABS,
6264
6607
  DerivedSignal,
6265
6608
  DiagnosticCollector,
6266
6609
  DiagnosticError,
@@ -6357,13 +6700,17 @@ function defineConfig(config) {
6357
6700
  inspectApplication,
6358
6701
  inspectComponents,
6359
6702
  inspectContext,
6703
+ inspectEvents,
6360
6704
  inspectForm,
6361
6705
  inspectGraph,
6706
+ inspectHydration,
6362
6707
  inspectI18n,
6363
6708
  inspectInteractions,
6709
+ inspectMutation,
6364
6710
  inspectResource,
6365
6711
  inspectRouter,
6366
6712
  inspectSignal,
6713
+ inspectSignalGraph,
6367
6714
  interpolate,
6368
6715
  isBatching,
6369
6716
  isComponentDefinition,
@@ -6397,6 +6744,7 @@ function defineConfig(config) {
6397
6744
  renderDevToolsHTML,
6398
6745
  renderDevToolsReport,
6399
6746
  renderHead,
6747
+ renderInteractiveDevTools,
6400
6748
  renderToString,
6401
6749
  reportDiagnostic,
6402
6750
  reportError,